LabHub
배우기 러닝패스 코스

CKAD — Kubernetesアプリケーション開発者

ローリングアップデート、切り戻し、ブルーグリーン、カナリア

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

Deployment 의 롤아웃 파라미터를 조절하고, 리비전을 쌓아 원하는 지점으로 되돌리며, 블루-그린과 카나리를 라벨·셀렉터·레플리카만으로 구성할 수 있게 된다.

왜 중요한가

Deployment 가 ReplicaSet 을 여러 개 관리한다는 사실을 이해하면 나머지가 전부 따라온다. 이미지를 바꾸면 새 ReplicaSet 이 생기고 옛 것은 레플리카 0 으로 남는다. rollout undo 가 즉각적인 이유는 이미지를 다시 받는 게 아니라 이미 있는 ReplicaSet 을 다시 부풀리기 때문이다. revisionHistoryLimit 을 0 으로 두면 그 안전망이 사라진다.

maxSurgemaxUnavailable 은 "얼마나 빠르게"와 "얼마나 안전하게"의 트레이드오프다. maxUnavailable: 0 은 배포 중에도 가용 파드 수를 유지하지만 새 파드가 Ready 가 될 때까지 기다려야 하므로 느리다. 그리고 이 안전장치는 Readiness Probe 가 있어야만 의미가 있다 — 프로브가 없으면 컨테이너가 뜬 즉시 Ready 로 간주된다.

블루-그린과 카나리는 별도 CRD 없이 라벨만으로 만들 수 있다. 차이는 Service 셀렉터의 좁기다. 셀렉터에 버전 라벨까지 넣으면 한쪽만 받고(블루-그린), 공통 라벨만 넣으면 양쪽이 다 들어와 개수 비율대로 나뉜다(카나리).

단계

  1. 네임스페이스 ckad-deploy 를 만들고 Deployment web 을 만든다. 이미지 nginx:1.25, 레플리카 4. (컨테이너 이름은 nginx 가 된다.)
  2. web 의 전략을 RollingUpdate 로 두고 maxSurge: 1, maxUnavailable: 0 으로 설정한다.
  3. web 의 이미지를 nginx:1.26 으로 올리고, Deployment 에 애너테이션 kubernetes.io/change-cause=nginx 1.26 으로 업데이트 를 붙인다.
  4. web 의 이미지를 nginx:1.27 로 한 번 더 올리고, 애너테이션 kubernetes.io/change-cause=nginx 1.27 으로 업데이트 로 갱신한다. 이 시점에 ReplicaSet 이 3개 이상 존재해야 한다.
  5. web 을 리비전 2 로 되돌린다. 되돌리기도 앞으로 나아가는 변경이므로 리비전 4 가 새로 생기고, 그 리비전의 이미지는 nginx:1.26 이어야 한다.
  6. 블루-그린을 만든다. Deployment checkout-blue(레플리카 2, 라벨 app=checkoutversion=blue, 이미지 nginx:1.26)와 checkout-green(레플리카 2, 라벨 app=checkoutversion=green, 이미지 nginx:1.27)을 만들고, Service checkout(포트 80, targetPort 80)의 셀렉터를 app=checkout + version=green 으로 준다.
  7. 카나리를 만든다. Deployment pay-stable(레플리카 9, 라벨 app=paytrack=stable, 이미지 nginx:1.26)와 pay-canary(레플리카 1, 라벨 app=paytrack=canary, 이미지 nginx:1.27)를 만들고, Service pay(포트 80, targetPort 80)의 셀렉터는 app=pay 하나만 준다.
  8. webkubectl rollout pause먼저 건 뒤, 이미지를 nginx:1.28 로 바꾸고 revisionHistoryLimit 을 3 으로 설정한다. 일시 중지 상태이므로 새 ReplicaSet 은 만들어지지 않아야 한다. (재개하지 않는다. 레플리카 4는 그대로 둔다.)

참고

네임스페이스와 Deployment 만들기

네임스페이스 ckad-deploy 를 만들고 Deployment web 을 만든다. 이미지 nginx:1.25, 레플리카 4. (컨테이너 이름은 nginx 가 된다.)

kubectl create deployment--image--replicas 를 준다. 생성된 Deployment 의 라벨과 셀렉터가 무엇인지 확인해 둔다 — 뒤 단계에서 쓴다.

롤링 업데이트 파라미터 조정

web 의 전략을 RollingUpdate 로 두고 maxSurge: 1, maxUnavailable: 0 으로 설정한다.

spec.strategy.rollingUpdate 밑에 두 값이 있다. kubectl edit 로 고치거나 kubectl patch 에 JSON 을 주면 된다. maxUnavailable: 0 은 배포 중에도 원래 개수를 유지하겠다는 뜻이다.

이미지 갱신과 change-cause 기록

web 의 이미지를 nginx:1.26 으로 올리고, Deployment 에 애너테이션 kubernetes.io/change-cause=nginx 1.26 으로 업데이트 를 붙인다.

kubectl set image deployment/이름 컨테이너=이미지 형태다. 컨테이너 이름을 정확히 써야 한다. CHANGE-CAUSE 는 kubernetes.io/change-cause 애너테이션으로 직접 붙인다.

한 번 더 올려 리비전 쌓기

web 의 이미지를 nginx:1.27 로 한 번 더 올리고, 애너테이션 kubernetes.io/change-cause=nginx 1.27 으로 업데이트 로 갱신한다. 이 시점에 ReplicaSet 이 3개 이상 존재해야 한다.

리비전은 ReplicaSet 으로 남는다. kubectl get rs -n <ns> 로 몇 개가 쌓였는지, kubectl rollout history 로 리비전 번호가 어디까지 왔는지 확인한다.

특정 리비전으로 되돌리기

web 을 리비전 2 로 되돌린다. 되돌리기도 앞으로 나아가는 변경이므로 리비전 4 가 새로 생기고, 그 리비전의 이미지는 nginx:1.26 이어야 한다.

kubectl rollout undo--to-revision=번호 를 준다. 되돌려도 리비전 번호는 줄어들지 않고 새 번호가 붙는다. 어느 리비전이 어떤 이미지였는지는 kubectl rollout history --revision=N 으로 본다.

블루-그린 — Service 셀렉터 전환

블루-그린을 만든다. Deployment checkout-blue(레플리카 2, 라벨 app=checkoutversion=blue, 이미지 nginx:1.26)와 checkout-green(레플리카 2, 라벨 app=checkoutversion=green, 이미지 nginx:1.27)을 만들고, Service checkout(포트 80, targetPort 80)의 셀렉터를 app=checkout + version=green 으로 준다.

두 Deployment 는 공통 라벨 하나와 서로 다른 버전 라벨을 갖는다. Service 셀렉터에 버전 라벨까지 넣으면 그쪽만 엔드포인트에 들어온다. Service 를 만든 뒤 셀렉터만 바꿔 보는 것이 이 패턴의 전부다.

카나리 — 레플리카 비율로 트래픽 나누기

카나리를 만든다. Deployment pay-stable(레플리카 9, 라벨 app=paytrack=stable, 이미지 nginx:1.26)와 pay-canary(레플리카 1, 라벨 app=paytrack=canary, 이미지 nginx:1.27)를 만들고, Service pay(포트 80, targetPort 80)의 셀렉터는 app=pay 하나만 준다.

카나리는 반대로 Service 셀렉터를 좁게 잡아 두 Deployment 의 파드가 모두 들어오게 한다. 그러면 트래픽 비율은 레플리카 개수 비율이 된다. 각 Deployment 에는 구분용 라벨을 따로 둔다.

일시 중지 상태로 변경 모으기 (종합)

webkubectl rollout pause먼저 건 뒤, 이미지를 nginx:1.28 로 바꾸고 revisionHistoryLimit 을 3 으로 설정한다. 일시 중지 상태이므로 새 ReplicaSet 은 만들어지지 않아야 한다. (재개하지 않는다. 레플리카 4는 그대로 둔다.)

kubectl rollout pause 를 먼저 걸면 이후의 템플릿 변경이 즉시 새 ReplicaSet 을 만들지 않고 쌓인다. 순서가 바뀌면 롤아웃이 이미 시작된다. 보관할 이전 ReplicaSet 개수를 정하는 필드도 함께 설정한다.