쿠버네티스에서 애플리케이션을 “업그레이드”한다는 것은 단순히 이미지 태그를 바꾸는 것만이 아닙니다. Deployment의 스펙(spec)이 바뀌는 모든 변화(이미지, 레이블, 환경변수, 리소스, replicas 등)는 곧 새 Rollout을 트리거하고, 그 결과로 새 ReplicaSet이 만들어지며 Revision(리비전)이 증가합니다. 이 구조 덕분에 쿠버네티스는 배포 변경 이력을 남기고, 문제가 생기면 이전 Revision으로 안전하게 롤백할 수 있습니다.
1) Deployment의 Rollout과 Revision: “왜 ReplicaSet이 계속 생기나?”
1-1. 최초 배포 = 최초 Rollout
Deployment를 처음 만들면(예: kubectl apply -f deployment.yaml) 즉시 Rollout이 트리거됩니다.
- Deployment는 내부적으로 ReplicaSet을 하나 생성하고
- ReplicaSet은
replicas수만큼 Pod를 생성합니다.
이 시점이 Revision 1에 해당합니다.
1-2. 업데이트 = 새로운 ReplicaSet + 새로운 Revision
이미지 태그를 v1에서 v2로 바꾸는 등 Deployment의 pod template(spec.template)이 변경되면:
- 새 Rollout이 트리거되고
- 새 ReplicaSet이 만들어지며
- Deployment Revision이 증가합니다. (예: Revision 2)
즉, “Deployment는 상태를 관리하는 컨트롤러이고, 실제 Pod 집합은 ReplicaSet이 들고 있다”가 핵심입니다.
2) Rollout 상태/이력 확인: 운영에서 자주 쓰는 2가지 명령
2-1. 현재 Rollout 상태 확인
kubectl rollout status deployment/<deployment-name>
2-2. Revision 히스토리 확인
kubectl rollout history deployment/<deployment-name>
3) Deployment 전략 2가지: Recreate vs RollingUpdate
(1) Recreate: “다 내리고, 다시 올린다”
- 기존 Pod를 모두 종료(0으로 축소)한 뒤
- 새 버전 Pod를 다시 생성
- 단점: 신버전이 준비되기 전까지 다운타임이 발생할 수 있음
strategy:
type: Recreate
(2) RollingUpdate: “하나씩 교체한다” (기본값)
- 구버전 RS를 조금씩 줄이면서
- 신버전 RS를 조금씩 늘림
- 전략을 지정하지 않으면 기본이 RollingUpdate
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
maxSurge: 업데이트 중 추가로 더 띄울 수 있는 Pod 수/비율maxUnavailable: 업데이트 중 비가용 상태여도 되는 Pod 수/비율
4) Deployment 업데이트 방법 2가지: apply vs set image
방법 A) YAML 수정 + kubectl apply (권장)
kubectl apply -f deployment.yaml
방법 B) kubectl set image로 즉시 교체 (주의)
kubectl set image deployment/<deploy-name> <container-name>=myapp:v2
- 주의: YAML 파일과 클러스터 실상태가 달라질 수 있음(형상관리/GitOps 관점에서 위험)
5) Recreate vs RollingUpdate는 어디서 확인하나? (kubectl describe)
kubectl describe deployment/<deployment-name>
- Recreate: 이전 RS가 먼저 0으로 줄고 → 새 RS가 늘어남
- RollingUpdate: 이전 RS 축소와 새 RS 확장이 동시에 조금씩 진행됨
6) ReplicaSet 관점에서 배포 이해하기: “0개 RS”가 왜 남아있나?
업데이트 후 ReplicaSet 목록을 보면 보통 아래처럼 보입니다.
kubectl get rs
- 이전 ReplicaSet:
DESIRED=0, CURRENT=0(Pod 0개) - 새 ReplicaSet:
DESIRED=5, CURRENT=5(Pod 5개)
여기서 중요한 이유가 있습니다.
왜 기존 ReplicaSet을 수정하지 않고 “새 ReplicaSet”을 만들까?
Deployment는 기존 ReplicaSet을 덮어쓰기보다, 새 ReplicaSet을 생성해 교체합니다. 그래야:
- 업데이트 중 문제가 생겨도 이전 버전(구 RS)이 그대로 남아
- 롤백 시 “오브젝트를 복원”하는 게 아니라 스케일만 역전시키면 되며
- Revision별 변경 추적이 명확해집니다.
왜 “Pod 0개인 ReplicaSet”이 남아있나?
이전 ReplicaSet은 보통 0으로 줄어들지만 오브젝트는 남겨둡니다.
이 ReplicaSet이 사실상 이전 버전 템플릿의 스냅샷 역할을 하기 때문입니다.
- 롤백 = 신버전 RS scale down + 구버전 RS scale up
- 그래서 롤백이 빠르고 안전합니다.
오래된 RS가 너무 많이 쌓이지 않도록
revisionHistoryLimit으로 보관 개수를 제한할 수 있습니다.
revisionHistoryLimit: 10
7) 롤백: 문제가 생기면 rollout undo
7-1. 직전 리비전으로 롤백
kubectl rollout undo deployment/<deployment-name>
7-2. 특정 리비전으로 롤백
kubectl rollout history deployment/<deployment-name>
kubectl rollout undo deployment/<deployment-name> --to-revision=<n>
8) 실전에서 반드시 같이 챙기는 것들 (짧게 보강)
8-1. RollingUpdate 안전성의 핵심: readiness
RollingUpdate가 무중단에 가깝게 동작하려면 readinessProbe가 정확해야 합니다.
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
8-2. 배포 중 멈춤/재개
kubectl rollout pause deployment/<name>
kubectl rollout resume deployment/<name>
9) 명령어 요약
배포 생성/조회
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl describe deployment/<name>
업데이트
kubectl apply -f deployment.yaml
kubectl set image deployment/<name> <container>=<image:tag>
롤아웃 상태/히스토리 / ReplicaSet 확인
kubectl rollout status deployment/<name>
kubectl rollout history deployment/<name>
kubectl get rs
롤백
kubectl rollout undo deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=<n>
Practice Test: https://uklabs.kodekloud.com/topic/practice-test-rolling-updates-and-rollbacks-2/
'CKA' 카테고리의 다른 글
| Application Lifecycle Management - ConfigMap (0) | 2025.12.30 |
|---|---|
| Application Lifecycle Management - Docker CMD/Entrypoint와 쿠버네티스 (0) | 2025.12.30 |
| Logging - 쿠버네티스 로깅 기초 (0) | 2025.12.30 |
| Monitoring - Metric Server (0) | 2025.12.30 |
| Scheduling - 총 정리 (0) | 2025.12.30 |