롤링 업데이트로 애플리케이션 업데이트하기

롤링 업데이트로 애플리케이션 업데이트하기 (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].imagenginx: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%

maxUnavailablemaxSurge는 절대 수 또는 백분율을 허용합니다. 쿠버네티스는 원하는 replica 수에서 백분율을 계산하며, maxUnavailable은 내림, maxSurge는 올림합니다.

이 파라미터들을 구성하려면 kubectl patch를 사용하세요:

kubectl patch deployment nginx-deployment -p \
  '{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable":"25%","maxSurge":"25%"}}}}'

이 필드들은 Deployment 매니페스트의 .spec.strategy.rollingUpdate 아래에서도 설정할 수 있어요. 자세한 예시는 Deployment 개념 문서의 max unavailablemax surge를 참조하세요.

정체된 롤아웃 감지하기

롤아웃이 .spec.progressDeadlineSeconds(기본값: 600초)에 지정된 시간 안에 진행되지 않으면, 쿠버네티스는 Deployment 조건 ProgressingFalse로 표시합니다. 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)