롤링 업데이트로 애플리케이션 업데이트하기
롤링 업데이트로 애플리케이션 업데이트하기 (Update a Deployment Using Rolling Update)
이 페이지에서는 롤링 업데이트를 사용해 실행 중인 Deployment를 새 버전으로 업데이트하는 방법을 보여줘요. 롤링 업데이트는 오래된 파드를 새 파드로 점진적으로 교체하므로, 그 과정 내내 애플리케이션이 사용 가능하게 유지됩니다.
출처: 문서
본문
목표 (Objectives)
- Deployment에서 롤링 업데이트를 트리거한다.
- 롤아웃 진행 상황을 모니터링한다.
- 롤아웃을 일시 중지·재개한다.
- 롤링 업데이트 전략 파라미터를 구성한다.
- (필요하다면) 이전 리비전으로 롤백한다.
시작하기 전에
기존 Deployment가 필요해요. 없으면 무상태 애플리케이션 실행하기에서 nginx Deployment를 만드세요:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
Deployment가 파드 두 개를 실행하는지 확인한다:
kubectl get deployment nginx-deployment
출력은 다음과 비슷합니다:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 10s
롤링 업데이트 수행하기
Deployment의 .spec.template 필드에 대한 어떤 변경도 롤링 업데이트를 트리거합니다. 쿠버네티스는 갱신된 구성으로 새 파드를 만들고 오래된 파드를 점진적으로 종료합니다.
kubectl apply로 업데이트하기
Deployment 매니페스트를 편집하고 변경 사항을 적용하면 롤링 업데이트를 트리거할 수 있어요. 이 방식은 매니페스트를 버전 관리에 둘 때 잘 동작합니다.
현재 Deployment를 로컬 파일로 내보낸다:
kubectl get deployment nginx-deployment -o yaml > /tmp/nginx-deployment.yaml
/tmp/nginx-deployment.yaml을 편집하고 .spec.template.spec.containers[0].image를 nginx:1.14.2에서 nginx:1.16.1로 바꾼다.
적용 전에 로컬 변경 사항을 클러스터 상태와 비교한다:
kubectl diff -f /tmp/nginx-deployment.yaml
출력은 다음과 비슷합니다:
diff -u -N /tmp/LIVE/apps.v1.Deployment.default.nginx-deployment /tmp/MERGED/apps.v1.Deployment.default.nginx-deployment
--- /tmp/LIVE/apps.v1.Deployment...
+++ /tmp/MERGED/apps.v1.Deployment...
@@ -29,7 +29,7 @@
containers:
- - image: nginx:1.14.2
+ - image: nginx:1.16.1
name: nginx
갱신된 매니페스트를 적용한다:
kubectl apply -f /tmp/nginx-deployment.yaml
컨테이너 이미지만 업데이트하기
매니페스트 파일을 편집하지 않고 컨테이너 이미지를 업데이트하려면 kubectl set image를 사용하세요:
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
출력은 다음과 비슷합니다:
deployment.apps/nginx-deployment image updated
이미지가 업데이트되었는지 확인한다:
kubectl get deployment nginx-deployment -o jsonpath='{.spec.template.spec.containers[0].image}'
출력은 다음과 비슷합니다:
nginx:1.16.1
롤아웃 진행 상황 모니터링하기
kubectl rollout status를 사용해 롤링 업데이트의 진행 상황을 지켜본다:
kubectl rollout status deployment/nginx-deployment
출력은 다음과 비슷합니다:
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
롤아웃이 완료된 후 Deployment를 확인한다:
kubectl get deployment nginx-deployment
출력은 다음과 비슷합니다:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 2m
롤아웃 일시 중지·재개하기
부분 업데이트를 검사하거나 여러 변경 사항을 하나의 롤아웃으로 묶으려면 롤아웃을 일시 중지할 수 있어요.
롤아웃 일시 중지하기
kubectl rollout pause deployment/nginx-deployment
출력은 다음과 비슷합니다:
deployment.apps/nginx-deployment paused
일시 중지된 동안 추가 변경하기
롤아웃이 일시 중지된 동안 추가 변경을 할 수 있어요. 이런 변경은 재개할 때까지 새 롤아웃을 트리거하지 않습니다:
kubectl set image deployment/nginx-deployment nginx=nginx:1.17.0
일시 중지된 Deployment에 여러 변경을 할 수 있습니다. 쿠버네티스는 롤아웃을 재개할 때 모든 변경을 함께 적용합니다.
롤아웃 재개하기
kubectl rollout resume deployment/nginx-deployment
출력은 다음과 비슷합니다:
deployment.apps/nginx-deployment resumed
롤아웃이 완료되는지 확인한다:
kubectl rollout status deployment/nginx-deployment
롤링 업데이트 전략 구성하기
Deployment는 두 가지 업데이트 전략 유형을 지원합니다:
- RollingUpdate (기본값): 오래된 파드를 새 파드로 점진적으로 교체한다.
- Recreate: 새 파드를 만들기 전에 모든 기존 파드를 종료한다. 이는 다운타임을 유발한다.
RollingUpdate 전략에서는 다음 파라미터가 쿠버네티스가 업데이트를 수행하는 방식을 제어합니다:
| 파라미터 | 제어 | 기본값 | 예시 |
|---|---|---|---|
maxUnavailable |
업데이트 중 사용 불가할 수 있는 최대 파드 수 | 25% | 1 또는 25% |
maxSurge |
업데이트 중 생성될 수 있는 추가 파드의 최대 수 | 25% | 1 또는 25% |
maxUnavailable과 maxSurge는 절대 수 또는 백분율을 허용합니다. 쿠버네티스는 원하는 replica 수에서 백분율을 계산하며, maxUnavailable은 내림, maxSurge는 올림합니다.
이 파라미터들을 구성하려면 kubectl patch를 사용하세요:
kubectl patch deployment nginx-deployment -p \
'{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable":"25%","maxSurge":"25%"}}}}'
이 필드들은 Deployment 매니페스트의 .spec.strategy.rollingUpdate 아래에서도 설정할 수 있어요. 자세한 예시는 Deployment 개념 문서의 max unavailable과 max surge를 참조하세요.
정체된 롤아웃 감지하기
롤아웃이 .spec.progressDeadlineSeconds(기본값: 600초)에 지정된 시간 안에 진행되지 않으면, 쿠버네티스는 Deployment 조건 Progressing을 False로 표시합니다. Deployment를 describe해 이 조건을 확인할 수 있어요:
kubectl describe deployment nginx-deployment
출력의 Conditions 섹션에서 Progressing 조건을 찾아보세요. 정체된 롤아웃은 대개 새 파드가 시작에 실패하고 있음을 나타냅니다. 출력의 Events 섹션은 문제 진단에 도움이 됩니다.
이전 리비전으로 롤백하기 {#rollback}
새 버전이 문제를 일으키면 이전 리비전으로 롤백할 수 있어요.
롤아웃 기록 보기
kubectl rollout history deployment/nginx-deployment
출력은 다음과 비슷합니다:
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
CHANGE-CAUSE 열은 각 리비전 시점의 kubernetes.io/change-cause 어노테이션 값을 보여줍니다. 이 어노테이션은 자동으로 설정되지 않지만, Deployment를 관리하는 자동화 솔루션을 사용 중이라면 그 도구가 어노테이션에 어떤 텍스트를 쓸 수도 있습니다.
이전 리비전으로 롤백하기
kubectl rollout undo deployment/nginx-deployment
출력은 다음과 비슷합니다:
deployment.apps/nginx-deployment rolled back
특정 리비전으로 롤백하기
kubectl rollout undo deployment/nginx-deployment --to-revision=1
롤백이 완료되는지 확인한다:
kubectl rollout status deployment/nginx-deployment
Deployment의 리비전 기록은 그것이 제어하는 ReplicaSet에 저장됩니다. 기본적으로 쿠버네티스는 오래된 ReplicaSet 10개를 보존합니다. 이 제한은 Deployment 매니페스트의 .spec.revisionHistoryLimit을 설정해 바꿀 수 있어요. 0으로 설정하면 롤백이 완전히 비활성화됩니다.
정리하기
Deployment를 삭제한다:
kubectl delete deployment nginx-deployment
더 알아보기 (Learn more)
- Deployment에 대해 더 알아보기.
- Deployment 수동 스케일링 방법 알아보기.
- Horizontal Pod Autoscaling 실습하기.
- DaemonSet에서 롤링 업데이트 수행 방법 알아보기.