오늘은 Deployment 의 롤링 업데이트와 롤백을 실습했다. 이미지 업데이트 → 잘못된 이미지로 배포 → 롤백 → 특정 리비전으로 롤백 순서로 진행했고, 롤백 시 리비전 번호가 재정렬되는 동작을 직접 확인했다.
Deployment 업데이트 전략은 두 가지다.
RollingUpdate (기본값) — 파드를 순차적으로 교체해 서비스 중단 없이 업데이트한다.
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25% # 동시에 내릴 수 있는 파드 비율
maxSurge: 25% # 동시에 추가로 띄울 수 있는 파드 비율
Recreate — 기존 파드를 전부 내린 뒤 새 파드를 올린다. 그 사이 구간에 다운타임이 발생한다.
strategy:
type: Recreate
Recreate 흐름
[🙆♀️🙆♀️🙆♀️] ← 기존 파드 전부 종료
[❌❌❌] ← 이 구간 접속 불가 (다운타임)
[🙆♀️🙆♀️🙆♀️] ← 새 파드 생성
| RollingUpdate | Recreate | |
|---|---|---|
| 다운타임 | 없음 | 있음 |
| 구버전/신버전 공존 | 잠깐 공존 | 절대 공존 안 함 |
| 주요 사용처 | 운영 환경 기본값 | DB 스키마 변경, 버전 간 비호환 |
Recreate 는 다운타임을 감수하는 대신 구버전과 신버전이 절대 동시에 존재하지 않음을 보장한다. DB 스키마가 바뀌거나 두 버전이 공존하면 안 되는 상황에서 쓴다.
nginx:1.19 로 배포된 web-app 을 nginx:1.20 으로 업데이트했다.
kubectl create deploy web-app --image=nginx:1.19 --replicas=3
kubectl set image deploy web-app nginx=nginx:1.20
kubectl rollout status deployment web-app
deployment "web-app" successfully rolled out
describe 로 Events 를 보면 RollingUpdate 가 파드를 1개씩 올리고 내리는 흐름을 확인할 수 있다.
ScalingReplicaSet Scaled up web-app-56c5f858bb from 0 to 1
ScalingReplicaSet Scaled down web-app-584b7c886b from 3 to 2
ScalingReplicaSet Scaled up web-app-56c5f858bb from 1 to 2
ScalingReplicaSet Scaled down web-app-584b7c886b from 2 to 1
...
backend 디플로이먼트가 nginx:broken-image 로 업데이트돼 파드 하나가 ImagePullBackOff 상태였다.
kubectl get pods
backend-59b7d7f9db-s5fkz 0/1 ImagePullBackOff 0 7m
backend-6b986449cd-f9m59 1/1 Running 0 7m
backend-6b986449cd-gxfxz 1/1 Running 0 7m
backend-6b986449cd-j4z7n 1/1 Running 0 7m
RollingUpdate 덕분에 기존 파드 3개는 살아있고 새 파드만 실패한 상태다. 히스토리 확인 후 롤백:
kubectl rollout history deployment backend
kubectl rollout undo deployment backend
kubectl rollout status deployment backend
deployment "backend" successfully rolled out
api-server 가 nginx:1.18 → 1.19 → 1.20 → 1.21 순으로 4번 업데이트된 상태에서 nginx:1.19 (revision 2) 로 롤백했다.
kubectl rollout history deployment api-server --revision=1 # nginx:1.18
kubectl rollout history deployment api-server --revision=2 # nginx:1.19
kubectl rollout history deployment api-server --revision=3 # nginx:1.20
kubectl rollout undo deployment --to-revision=2
deployment.apps/api-server rolled back
롤백 후 히스토리를 다시 보니 revision 2 가 사라지고 revision 5 로 재등록됐다. 기존 ReplicaSet 을 재활성화하는 방식이라 "현재 버전" 이 된 ReplicaSet 이 가장 마지막 번호로 올라가는 것이다.
REVISION CHANGE-CAUSE
1 <none> ← nginx:1.18
3 <none> ← nginx:1.20
4 <none> ← nginx:1.21
5 <none> ← nginx:1.19 (revision 2가 여기로 이동)
| 명령어 | 설명 |
|---|---|
kubectl set image deploy {name} {container}={image}:{tag} | 이미지 업데이트 |
kubectl rollout status deployment {name} | 롤아웃 진행 상태 확인 |
kubectl rollout history deployment {name} | 리비전 히스토리 조회 |
kubectl rollout history deployment {name} --revision=N | 특정 리비전 이미지 확인 |
kubectl rollout undo deployment {name} | 바로 이전 리비전으로 롤백 |
kubectl rollout undo deployment {name} --to-revision=N | 특정 리비전으로 롤백 |
Q. Create a deployment web-app with nginx:1.19 (3 replicas), then update the image to nginx:1.20 and confirm the rollout completes.
→ kubectl set image + kubectl rollout status 조합
Q. The deployment backend was updated with a broken image and one pod is in ImagePullBackOff. Roll back to the previous working version.
→ kubectl rollout undo deployment backend
Q. The deployment api-server has 4 revisions (nginx:1.18→1.19→1.20→1.21). Roll back to the revision that used nginx:1.19.
→ --revision=N 으로 각 리비전 이미지 확인 후 --to-revision=N 으로 롤백. 롤백 후 해당 revision 번호는 최신 번호로 재등록됨