Pod는 Kubernetes가 컨테이너를 실행하는 가장 작은 단위이고, 운영에서는 Pod를 직접 만들지 않고 Deployment로 관리합니다. 이 글에서는 Pod, ReplicaSet, Deployment의 관계와 롤링 업데이트, 롤백, 그리고 컨테이너 상태를 확인하는 Probe를 정리합니다.
컨테이너부터 Kubernetes까지 시리즈 7편입니다. 이전 글은 [Kubernetes] 클러스터 구조 정리이고, 전체 순서는 시리즈 목차에 있습니다.
1. Pod
Pod는 컨테이너 하나 이상을 묶은 실행 단위입니다. 같은 Pod 안의 컨테이너는 1편에서 본 NET namespace를 함께 써서 IP 하나를 나눠 쓰고, localhost로 서로 통신하며, 볼륨도 함께 붙일 수 있습니다. 대부분은 Pod 하나에 컨테이너 하나를 두고, 로그 수집기처럼 앱 옆에 꼭 붙어 있어야 하는 보조 컨테이너(sidecar)만 같은 Pod에 넣습니다.
| 항목 | Docker 컨테이너 | Pod |
| 묶음 | 컨테이너 하나 | 컨테이너 하나 이상 |
| IP | 컨테이너마다 하나 | Pod마다 하나, 안의 컨테이너가 공유 |
| 재시작 | restart 정책 | restartPolicy에 따라 kubelet이 같은 노드에서 재시작 |
| 다른 서버로 이동 | 없음 | Pod 스스로는 없음, 컨트롤러가 새 Pod를 만듦 |
Pod는 일회용입니다. 노드가 고장 나면 그 위의 Pod는 사라지고, 같은 Pod가 다른 노드로 옮겨가지 않습니다. 다시 만들면 이름과 IP도 바뀝니다. 그래서 Pod 개수를 지켜보다가 모자라면 새로 만들어 주는 컨트롤러가 필요합니다.
2. ReplicaSet과 Deployment
ReplicaSet은 라벨(label)로 자기 Pod를 찾아 개수를 유지합니다. replicas가 3이면 Pod 하나가 지워질 때 하나를 새로 만들고, 많으면 줄입니다. Deployment는 그 위에서 이미지 버전마다 ReplicaSet을 만들고 바꿔 끼우면서 업데이트와 롤백을 맡습니다. 운영에서는 Deployment만 만들고, ReplicaSet과 Pod는 Deployment가 만들게 둡니다.

Deployment가 ReplicaSet을, ReplicaSet이 Pod를 만들며 이름 뒤에 임의 문자열이 차례로 붙습니다
| 리소스 | 하는 일 | 직접 만드는 경우 |
| Pod | 컨테이너 실행 | 잠깐 테스트할 때 |
| ReplicaSet | 라벨이 맞는 Pod 개수 유지 | 거의 없음 |
| Deployment | ReplicaSet을 버전별로 관리 롤링 업데이트와 롤백 |
상태 없는 앱의 기본 |
3. 롤링 업데이트와 롤백
이미지 버전을 바꾸면 Deployment는 새 ReplicaSet을 만들고, 새 Pod를 하나 늘릴 때마다 이전 Pod를 하나 줄여서 서비스를 멈추지 않고 교체합니다. 이전 ReplicaSet은 지우지 않고 Pod 0개로 남겨 두기 때문에, 롤백할 때는 그 ReplicaSet을 다시 늘리기만 하면 됩니다.

replicas 3에 기본값을 쓰면 Pod를 최대 4개까지 늘리고, 준비된 Pod는 3개 밑으로 내리지 않습니다
| 설정 | 기본값 | 의미 |
| maxSurge | 25%(올림) | replicas보다 더 만들 수 있는 Pod 수 3개면 1개 |
| maxUnavailable | 25%(내림) | 업데이트 중 준비되지 않아도 되는 Pod 수 3개면 0개 |
| revisionHistoryLimit | 10 | 롤백용으로 남겨 두는 이전 ReplicaSet 수 |
| strategy.type | RollingUpdate | Recreate로 바꾸면 이전 Pod를 모두 지운 뒤 새로 만듦 |
4. Probe
3편에서 Dockerfile의 HEALTHCHECK는 Kubernetes가 무시한다고 했습니다. Kubernetes에서는 kubelet이 Probe로 컨테이너 상태를 확인합니다. readinessProbe가 없으면 컨테이너가 시작되자마자 Ready가 되어서, 앱이 아직 준비되지 않았는데도 요청이 들어가고 롤링 업데이트도 그만큼 빨리 진행됩니다.
| Probe | 실패하면 | 용도 |
| startupProbe | 성공할 때까지 나머지 Probe를 미룸 정한 횟수를 넘기면 컨테이너 재시작 |
시작이 느린 앱 |
| readinessProbe | Service 대상에서 뺌(재시작하지 않음) | 요청을 받을 준비 확인 |
| livenessProbe | 컨테이너 재시작 | 멈춰서 스스로 회복하지 못하는 상태 감지 |
5. 직접 해 보기
6편에서 만든 kind 클러스터에 nginx Deployment를 올립니다.
# web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.30-alpine
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
selector.matchLabels와 template 안의 labels가 같아야 ReplicaSet이 자기가 만든 Pod를 찾습니다.
kubectl apply -f web.yaml
kubectl get deploy,rs,pods -o wide
ReplicaSet은 web 뒤에 임의 문자열이 붙고, Pod는 그 뒤에 한 번 더 붙습니다. NODE 열을 보면 Pod가 kind-worker와 kind-worker2에 나뉘어 있습니다. control-plane 노드에는 일반 Pod를 받지 않도록 taint가 걸려 있기 때문입니다.
Pod 하나를 지워 봅니다. Pod 이름은 앞의 목록에서 하나를 골라 넣습니다.
kubectl delete pod <Pod 이름>
kubectl get pods
지운 Pod 자리에 새 이름의 Pod가 바로 생깁니다. ReplicaSet이 Pod가 2개로 줄어든 것을 보고 하나를 채운 것입니다.
이번에는 이미지를 nginx:1.31-alpine으로 바꿔 롤링 업데이트를 합니다. nginx는 컨테이너 이름입니다.
kubectl set image deployment/web nginx=nginx:1.31-alpine
kubectl rollout status deployment/web
kubectl get rs
rollout status가 Pod를 하나씩 교체하는 과정을 보여 주고, 끝나면 새 ReplicaSet은 3, 이전 ReplicaSet은 0이 됩니다. 이제 이전 버전으로 되돌립니다.
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
history에는 REVISION 1, 2가 나오고, undo를 하면 이전 ReplicaSet이 다시 3개로 늘어나 이미지가 nginx:1.30-alpine으로 돌아갑니다. 되돌린 버전은 새 번호 3을 받고 1번은 목록에서 빠집니다. CHANGE-CAUSE 열은 kubernetes.io/change-cause 어노테이션을 달아야 채워지고, 없으면 <none>으로 나옵니다.
6. 운영 시 주의점
| 항목 | 조치 |
| Pod 직접 생성 | 노드가 고장 나면 되살아나지 않음 Deployment로 관리 |
| latest 태그 | 어떤 버전이 실행 중인지 알 수 없고 롤백해도 같은 이미지일 수 있음 버전 태그 사용 |
| readinessProbe | 없으면 준비되기 전의 Pod로 요청이 감 앱의 상태 확인 경로로 설정 |
| livenessProbe | 기준을 너무 짧게 잡으면 잠깐 느려진 앱을 계속 재시작 시작이 느리면 startupProbe와 함께 사용 |
| rollout undo | 클러스터만 되돌리고 YAML 파일은 그대로라, 다음 apply 때 다시 바뀜 Git의 YAML을 되돌려 apply(GitOps 방식) |
| 직접 만든 이미지 | kind 노드는 로컬 Docker의 이미지를 모름 kind load docker-image hello-go:1.0처럼 노드에 넣은 뒤 사용 |
7. 정리
- Pod는 IP를 공유하는 컨테이너 묶음이고 일회용이라, 개수 유지는 ReplicaSet이 라벨로 Pod를 찾아 맡습니다.
- Deployment는 버전마다 ReplicaSet을 만들어 롤링 업데이트하고, 이전 ReplicaSet을 남겨 두어 바로 롤백할 수 있습니다.
- readinessProbe를 설정해야 준비된 Pod에만 요청이 가고 롤링 업데이트도 안전하게 진행됩니다.
다음 글 8편에서는 이름과 IP가 계속 바뀌는 Pod에 고정된 주소로 접속하게 해 주는 Service와, 클러스터 밖의 HTTP 요청을 받는 Ingress, Gateway API를 다룹니다.
참고
'DevOps > Kubernetes' 카테고리의 다른 글
| [Kubernetes] ConfigMap과 Secret 정리 (0) | 2026.09.28 |
|---|---|
| [Kubernetes] Service와 Ingress, Gateway API 정리 (0) | 2026.09.28 |
| [Kubernetes] 클러스터 구조 정리 (0) | 2026.09.28 |
| [Kubernetes] 토큰 만료 후 워커 노드 추가 (0) | 2021.11.02 |
| [Kubernetes] Dashboard 설치하고 토큰으로 접속 (0) | 2021.07.05 |