쿠버네티스란?

셀프 힐링
- 쿠버네티스는 스스로 복구한다
- Pod가 죽거나, 컨테이너가 비정상 종료되거나, 노드가 장애 나면
- 사람이 직접 고치지 않아도 쿠버네티스가 자동으로 다시 맞춘다
선언 감시
- Deployment, StatefulSet 같은 YAML 파일에 쓰여있는 Replica 수, 이미지 버전 등을 쿠버네티스는 계속 감시
현재 상태와 비교
- 실제로 pod가 몇개 떠있고, 죽은 pod는 없는지 확인
- Desired 상태와 Actual 상태가 다르다면 Pod 새로 생성하여 시작
쿠버네티스 사용 이유
- API로 상태를 정의한다
- “어떻게 할지”가 아니라 “어떤 상태여야 하는지”를 적는다
컨트롤플레인
- 쿠버네트스의 두뇌
- 구성요소
- API 서버: API 요청에 응답하고 저장소에 기록. REST 서비스 제공
- ETCD: 쿠버네티스의 기억장치 (Pod, Deployment, Service 같은 모든 상태 정보 저장)
- 스케줄러: 새로 만들 Pod를 어느 노드에 올릴지 결정
- 컨트롤러 매니저: 제어루프 사용해서 설정 상태를 유지하도록 함
노드
- 실제 앱을 실행하는 시스템
- 구성요소
- 컨테이너 런타임: 컨테이너 실행 엔진
- Kubelet: API 서버와 통신하며 노드의 컨테이너 관리
- Kube-proxy: 앱의 구성요소에 따라 트래픽 분산
ETCD
- 데이터를 분산해서 보관
- 모든 데이터는 모든 노드에 동일하게 존재 (ETCD를 통해 모든 노드가 데이터 공유)
- 모든 데이터는 리더에 먼저 쓰이고 나머지 노드에 복제
- 내부구성은 각 노드에 ETCD가 각각 붙어있음 (노드 죽으면 ETCD 같이 죽음)
- 외부구성은 노드와 ETCD가 떨어져있음 (노드 죽어도 ETCD 안죽음)
Pod

- 쿠버네티스의 가장 작은 실행 단위
- Pod : 컨테이너 = 1:1 비율 (종단 컨테이너는 1:N가능)
- Pod는 무조건 노드안에 존재
- 동일한 Pod 안에 있는 컨테이너는 네트워크 및 볼륨 공유 가능
- Pod들은 공유 가능한 네트워크 주소 값을 갖음
- 각각의 Pod는 개별 IP를 보유 (이걸 통해 LAN처럼 서로 통신이 무조건 가능)
- Pod 내의 컨테이너가 여러개인 경우, 서로 다른 포트를 통해 서비스해야함
# Pod 생성하는 yml 파일 예시
apiVersion: v1 # 사용할 Kubernetes API 버전
kind: Pod # 생성할 리소스 종류
metadata:
name: my-redis # Pod 이름
spec: # Pod의 원하는 상태(Desired State) 정의
containers: # Pod 안에서 실행될 컨테이너 목록
- name: redis # 컨테이너 이름 (Pod 내부에서 식별)
image: redis:7.2 # 사용할 컨테이너 이미지
ports:
- containerPort: 6379 # 컨테이너가 사용하는 포트
Pod 관련 핵심 명령어 (예시 파일 기반)
# redis가 실행중인 컨테이너에 bash로 접속후 프로세스를 조회
kbectl exec -it redis-pod -- bash
# Pod 이벤트 및 컨테이너 로그 확인
kubectl logs redis-pod
Label
- 라벨은 쿠버네티스의 모든 리소스를 관리하기 쉽도록 도움
- 셀렉터를 통해 리소스를 선택 가능
- 리소스를 만들 때 뿐만 아니라 이미 만들어진 리소스의 라벨도 수정 가능
- key/value 쌍임
# Label 생성을 위한 yml 파일 예시
apiVersion: v1
kind: Pod
metadata:
name: goapp-pod
labels:
env: prod
tier: backend
spec:
containers:
- image: dangtong/goapp
name: goapp-container
ports:
- containerPort: 8080
protocol: TCP
핵심 명령어
# yaml 파일을 이용해 pod 를 생성
kubectl apply -f ./goapp-with-label.yaml
# 생성된 POD를 조회
kubectl get po --show-labels
# Label 추가 (참고로 동일한 key를 중복해서는 라벨 추가 못함)
# 만약 env=web이었으면 기존 yml파일에서 키 중복이 일어남
kubectl label po goapp-pod app=web
# label 수정
kubectl label po goapp-pod app=api --overwrite
# Label 삭제
kubectl label po goapp-pod app-
Annotation
- key/value 쌍이지만 라벨과 다르게 셀렉터 활용 불가능
- 라벨보다 더 많은 정보 담을 수 있음
- 주로 주석 역할로 쓰임
# Annotation 추가
kubectl annotate pod goapp-pod maker="dangtong" team="k8s-team"
# Annotation 확인
kubectl describe po goapp-pod
# Annotation 삭제
Kubectl annotate po goapp-pod maker- team-
Namespace
- 클러스터 내에서 리소스 그룹을 격리하기 위한 역할
- 리소스 이름은 Namespace 내에서는 고유해야함 (다른 네임스페이스면 이름 같아도 상관 X)
- ResourceQuota를 사용해 CPU, 메모리 등의 자원제한 가능
- Namespace 삭제시 내부의 모든 리소스 삭제
probe

- probe는 판단만 함. 행동은 X
- probe 결과 바탕으로 kubelet이 행동
Replication Controller
- pod가 사라지면 새로운 노드에 pod 생성 (pod가 죽은 이유의 대부분은 해당 노드 문제여서 안전하게 새로운 노드에 생성함)
- RC를 붙이지 않은 pod는 사라져도 생성 안됨
- RC는 구닥다리 방식이라 이제 안씀
3가지 구성 요소
- RC 내에 있는 pod 결정하는 라벨 셀렉터 사용
- 실행해야 하는 pod의 원하는 수를 지정(replica 갯수 지정)
- 새로운 pod 복제본 만들 때 필요한 pod 탬플릿
pod 템플릿 수정하면 반영되는 시점

ReplicaSet
- RC 대체용
- 일반적으로 Deployment 사용해서 RS 생성함
- RC와 동일하게 동작하지만 pod 선택이 더 자유로움
- RC는 지역적으로 멀리 떨어져있는 노드끼리 통신 X, 하지만 RS는 O

DaemonSet
- 모든 노드에 pod를 1개씩 보장하는 컨트롤러
- RC, RS는 노드의 갯수 컨트롤러임
- 주로 노드마다 로그 수집, 모니터링 에이전트등이 필요할때 사용됨
- RC, RS, DS 등 컨트롤러는 '노드'를 관리하는게 아니라 '생성한 pod'를 관리
# K8s 실제 컨트롤러 구성 사용 예시
[Control Plane]
└─ kube-controller-manager
├─ ReplicaSet Controller
├─ DaemonSet Controller
└─ Deployment Controller
[Node 1]
├─ web-pod (ReplicaSet 컨트롤러가 생성한 pod)
└─ log-agent (DaemonSet 컨트롤러가 생성한 pod)
[Node 2]
├─ web-pod (ReplicaSet 컨트롤러가 생성한 pod)
└─ log-agent (DaemonSet 컨트롤러가 생성한 pod)
- RC/RS를 replica 3개로 설정했다면 이렇게만 생각함
"이 템플릿의 Pod가 클러스터 전체에 총 3개 있으면 됨" / 노드단위가 아님!
Deployments
- Pod와 RS가 만들어짐
- 객체이고 모든 히스토리를 보관하며 롤백이 가능함
- 버전 2개를 동시에 띄우는 배포기법들은 모드 Sticky Session이 필요
Recreate:

- 재가동임. 사용하고 있던 버전을 그냥 내렸다가 새로운 버전으로 올리는거임
- 쉽지만 변경시간동안 멈춤 그리고 리소스 하나씩 새 버전으로 변경
Ramped:


- 구버전과 새버전을 한번에 띄워서 트래픽 분산시킴 (조금씩 갈아탐)
- 기존 버전에서 세션이 끊기거나 새로운 사람들이 버전 2로 연결됨
- 시스템 자원이 많으면 maxserge를 많이 키워서 빠르게 버전 변경 가능
- 롤아웃/롤백 오래걸리고 복잡
Blue/Green:

- 새 버전에 필요한 리소스를 전부 업데이트하고 모두 준비 후 기존 버전에서 새 버전으로 바로 연결 (한번에 갈아탐)
- 리소스가 2배나 필요해서 현장에서는 잘 안씀
- 버전 자주 변경되는 프론트서비스에 적합
- 롤아웃/롤백 간단하고 금방함
canary:

- Blue/Green에서 한번에 변경하는게 아닌 10프로만 보내보고 위험 없으면 모두 옮김
- 리스크 감소
- 롤백이 빠르지만 롤아웃이 느림
A/B testing:

- 모바일이냐 ,데스크탑이냐처럼 서로 다른 웹 화면을 띄어야하는 경우 사용
- 지능형(모바일 or 데스크탑 중 어디로 연결할지) 로드밸런서가 필수
shadow:

- v1에 있던 요청이 v2로 복제되는거임
- 요청 필터 가능
- 2배의 리소스 사용함
배포 기법 정리
- 다운타임 허용 된다? Recrate
- Recreate와 Ramped는 Deployment 기능에 설정으로 포함 되어 있음
- Recreate와 Ramped 배포는 일반적으로 적용하기 쉬움
- Blue/Green 배포는 동일한 서버에서 버전이 변경되는 서비스를 로드하는 프론트에 적합
- Blue/Green과 Shadow는 리소스 2배 필요해서 비쌈
- Canary와 A/B Testing는 리스크를 줄이고 싶을때 좋음
Recreate, Rolling Update: Deployment의 기본 배포 전략
Blue/Green과 Canary 배포: Deployment 외 트래픽 제어 구성을 통해 구현 가능
A/B Testing과 Shadow 배포: Deployment 기능으로는 지원되지 않는다.
# A/B Testing, Shadow는 Deployment가 아니라 Load Balancer같은 얘들이 담당한다.
Stateless App
- 서버가 “사용자 기억”을 안 함
- 그래서 쿠키와 세션을 사용
- 세션은 Redis 같은 외부 저장소 사용
- 서버 죽어도 서비스 유지 가능
Stateful App
- 상태를 직접 보유 (ex: DB, Redis)
- 상태를 직접 들고 있기 때문에 재시작·재배포에 민감
'K8s' 카테고리의 다른 글
| K8s_Cloudwave: ConfigMap & Secret (0) | 2026.01.12 |
|---|---|
| k8s_cloudwave: 볼륨 (1) | 2026.01.09 |
| K8s_Cloudwave: Terraform 활용 EKS 생성 (0) | 2026.01.09 |
| K8s-Cloudwave: 로컬 K8s 생성 (0) | 2026.01.08 |
| K8s-Cloudwave: 쿠버네티스 기초 (0) | 2026.01.08 |