LabHub

CAPA — Argo 프로젝트 인증 어소시에이트 · Argo Rollouts 점진적 배포 · 이론

Deployment 의 롤링 업데이트로는 왜 부족한가

LabHub 에서 이어서 보기

한 줄 요약

Rollout 은 Deployment 를 대체하는 워크로드 리소스다. 대체하는 이유는 단 하나, Deployment 의 롤링 업데이트에는 "잠깐 멈추고 지켜본다" 는 개념이 없기 때문이다. Rollout 은 그 자리에 setWeight·pause·analysis 라는 스텝을 넣었다.

왜 이게 필요했나

Deployment 의 RollingUpdate 는 maxSurge 와 maxUnavailable 두 숫자로 교체 속도를 정한다. 이 모델의 전제는 "새 파드가 Ready 면 정상" 이다. 그런데 대부분의 배포 사고는 파드가 안 뜨는 사고가 아니라 파드는 잘 떴는데 응답이 틀린 사고다. readinessProbe 가 200을 돌려주는 동안 결제 API 가 5xx 를 뿜을 수 있고, 지연 시간이 세 배가 될 수 있다. Deployment 는 이걸 볼 눈이 없어서 문제 있는 버전을 끝까지 밀어 넣는다.

사람이 개입할 자리도 없다. kubectl rollout pause 가 있지만 이것은 사람이 타이밍을 맞춰 손으로 쳐야 하는 명령이라 자동화에 못 넣는다. 그래서 실제 현장은 대개 "배포하고 그라파나를 보다가 이상하면 rollout undo" 라는 수동 절차로 굴러가고, 이 절차의 품질은 그날 당직의 집중력에 좌우된다. Rollout 은 이 절차를 오브젝트 안에 선언으로 옮긴 것이다.

어떻게 동작하나

카나리 전략은 steps 배열로 표현한다. 대표적인 스텝은 세 종류다.

| 스텝 | 뜻 |
| --- | --- |
| setWeight | 새 버전으로 보낼 트래픽 비율(또는 파드 비율)을 이만큼으로 올린다 |
| pause | 멈춘다. duration 을 주면 그 시간만큼, 안 주면 사람이 promote 할 때까지 무한히 |
| analysis | AnalysisRun 을 띄워 지표를 재고, 실패하면 롤아웃을 중단·되돌린다 |

duration 없는 pause 가 중요하다. 이것이 사람의 승인을 그래프 안에 넣는 방법이고, 자동화된 파이프라인 한가운데 수동 게이트를 두는 표준 관용구다.

analysis 스텝이 참조하는 것이 AnalysisTemplate 이다. 여기에는 metrics 배열이 들어가고 각 지표는 interval(얼마마다 잴지), successCondition 또는 failureCondition(무엇을 성공으로 볼지), failureLimit(몇 번 실패까지 봐줄지), provider(어디서 가져올지)를 갖는다. successCondition 을 result[0] >= 0.95 처럼 쓰고 provider 를 프로메테우스로 두면, 성공률이 95% 밑으로 failureLimit 회 떨어지는 순간 롤아웃이 스스로 멈추고 되돌아간다. 사람의 집중력에 의존하던 절차가 선언이 된 지점이다.

트래픽을 실제로 나누려면 데이터플레인의 협조가 필요하다. Rollout 은 파드 비율만 바꿀 수도 있지만(레플리카 4개에 setWeight 25 면 한 개), 정확한 비율 제어는 인그레스 컨트롤러나 서비스 메시가 해야 한다. 그래서 trafficRouting 아래에 nginx·istio·alb 같은 구현별 설정이 있고, canaryService 와 stableService 두 서비스를 함께 지정한다. 컨트롤러가 두 서비스의 셀렉터를 조작해 어느 파드 집합이 어느 서비스 뒤에 붙을지 바꾸는 구조다.

블루그린은 다른 모양이다. 새 버전을 전량 띄워 두고 previewService 로만 접근하게 하다가, 승격하는 순간 activeService 를 새 것으로 갈아 끼운다. autoPromotionEnabled 를 false 로 두면 사람이 승격할 때까지 기다리고, scaleDownDelaySeconds 는 승격 후 옛 버전을 몇 초나 살려 둘지 정한다. 이 값이 0 이 아닌 이유는 즉시 되돌릴 여지를 남기기 위해서다.

현장에서 만나는 모습

저자 홈랩에서 이 주제와 맞물린 사고가 GPU Operator 였다. 컨테이너 런타임 설정이 어긋나 있었는데 상태 표시는 정상이었고, 실제로 파드를 띄워 보고서야 드러났다. 배포 도구가 보여주는 상태와 서비스가 실제로 하는 일 사이의 간극이 이 코스에서 반복되는 주제인데, Rollout 의 analysis 스텝은 바로 그 간극을 메우려고 만들어진 장치다. 파드가 Ready 라는 신호가 아니라 응답 성공률이라는 신호를 보게 만드는 것이다.

한 가지 더. Rollout 으로 갈아탈 때 실무에서 가장 많이 부딪히는 것은 기존 Deployment 와의 공존이다. 같은 셀렉터를 가진 Deployment 와 Rollout 이 동시에 있으면 두 컨트롤러가 같은 파드를 서로 자기 것이라 주장한다. 그래서 전환은 workloadRef 로 기존 Deployment 를 참조하게 두거나, Deployment 를 0으로 줄이고 Rollout 을 올리는 순서로 한다. 그리고 되돌리기의 기본은 여전히 쿠버네티스가 갖고 있다. Deployment 는 ReplicaSet 을 리비전으로 남겨 두기 때문에 rollout undo 로 직전 상태로 돌아갈 수 있고, 이 메커니즘을 이해하지 못한 채 Rollout 을 쓰면 되돌리기가 마법처럼 보인다.

다음 실습에서 할 것

/root/capa-rollout/ 에 카나리 Rollout, AnalysisTemplate, 블루그린 Rollout 을 작성하고, 대응되는 Service 두 개와 Deployment 를 실제 클러스터에 올린 뒤 이미지를 바꿨다가 rollout undo 로 되돌려 리비전이 어떻게 쌓이는지 직접 본다.