왜 한 번에 전환하면 위험한가
새 버전을 배포할 때 모든 트래픽을 즉시 신규 파드로 넘기면, 문제가 있어도 100% 사용자가 즉시 영향을 받는다. 헬스체크는 통과하지만 특정 요청 패턴에서만 터지는 결함, 메모리 누수, 다운스트림 의존성의 타임아웃 증가는 배포 직후 몇 분이 지나야 드러난다. 이런 지연 신호를 감지하기 전에 전체 트래픽을 옮기면 롤백 비용이 최대가 된다. 점진적 전환은 폭발 반경(blast radius)을 초기에는 1~5%로 제한해, 지표가 나빠지면 소수 사용자만 영향받은 상태에서 되돌리는 것이 핵심이다.
카나리 vs 블루-그린
두 전략은 목적이 다르다. 트래픽을 나눠 지표를 관찰하며 늘려가는 카나리와, 완성된 새 환경으로 한 번에 스위칭하는 블루-그린을 혼동하면 자동화 설계가 어긋난다.
| 항목 | 카나리 | 블루-그린 |
|---|---|---|
| 트래픽 전환 | 1%→10%→50%→100% 점진 | 0%→100% 즉시 |
| 리소스 | 구/신 일부 공존 | 두 환경 완전 이중화 |
| 롤백 속도 | 가중치 되돌림 | 라우터 스위칭(가장 빠름) |
| 지표 기반 판단 | 단계마다 가능 | 전환 후에만 |
지연 결함 감지가 중요하면 카나리, 스키마 호환성이 확실하고 즉시 롤백이 최우선이면 블루-그린이 유리하다.
자동 분석이 없으면 자동화가 아니다
가중치만 스케줄대로 올리는 것은 "타이머 배포"일 뿐이다. 진짜 자동화는 각 단계에서 지표를 평가해 승격/롤백을 스스로 결정한다. 최소한 에러율, p99 지연, 그리고 비즈니스 지표(주문 성공률 등) 세 축을 본다. 아래는 프로메테우스 쿼리로 카나리 파드의 에러율을 뽑는 예시다.
sum(rate(http_requests_total{app="checkout",version="canary",code=~"5.."}[2m]))
/
sum(rate(http_requests_total{app="checkout",version="canary"}[2m]))
이 값이 baseline 대비 유의미하게 높으면 승격을 멈춘다. 절대 임계치만 쓰면 트래픽이 적은 초기 단계에서 요청 몇 건에 값이 튀므로, 반드시 baseline(안정 버전)과 비교하고 최소 요청 수 조건을 함께 건다.
Argo Rollouts로 선언형 카나리 구성
쿠버네티스라면 Argo Rollouts가 가중치 조정과 분석을 선언형으로 묶어준다. 단계마다 pause를 두고, analysis가 실패하면 자동 롤백된다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: checkout
spec:
strategy:
canary:
analysis:
templates:
- templateName: error-rate
startingStep: 1
steps:
- setWeight: 5
- pause: {duration: 5m}
- setWeight: 25
- pause: {duration: 10m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
analysis 템플릿이 실패 조건을 반환하면 rollout은 즉시 이전 안정 리비전으로 되돌아간다. 사람이 새벽에 그래프를 지켜볼 필요가 없어진다.
승격/롤백 판단 로직 예시
매니지드 도구를 못 쓰는 환경이라면 판정 로직을 직접 구현해야 한다. 핵심은 baseline 대비 상대 비교와 관측 창(observation window)이다.
def should_promote(canary_err, base_err, canary_reqs, min_reqs=200):
if canary_reqs < min_reqs:
return "wait" # 샘플 부족, 판단 보류
# baseline보다 에러율이 1.5%p 이상 높으면 롤백
if canary_err - base_err > 0.015:
return "rollback"
return "promote"
"wait"를 별도 상태로 둔 이유가 중요하다. 데이터가 부족한데 promote나 rollback을 강제하면, 통계적으로 무의미한 노이즈에 배포 운명을 맡기게 된다.
실무에서 자주 놓치는 주의점
- 세션 고정: 가중치 기반 라우팅은 요청마다 버전이 바뀔 수 있다. 장바구니처럼 상태가 있으면 쿠키/헤더 기반 스티키 라우팅이 필요하다.
- DB 마이그레이션: 구/신 버전이 동시에 도는 동안 스키마는 양쪽 모두와 호환돼야 한다. 컬럼은 추가 먼저, 삭제는 전환 완료 후로 분리한다(expand-contract).
- 지표 워밍업: JIT 컴파일, 캐시 미적재로 신규 파드의 초기 지연이 나쁠 수 있다. pause 첫 구간은 워밍업을 고려해 판정 창을 늦춘다.
- 관측 창 vs 지연 결함: 5분 관측으로는 30분 뒤 터지는 메모리 누수를 못 잡는다. 리소스 지표는 전환 완료 후에도 일정 시간 감시를 유지한다.
점진적 전환의 가치는 트래픽을 나누는 데 있지 않고, 각 단계에서 객관적 지표로 다음 단계를 결정하는 데 있다. 이 판단을 자동화하지 못하면 결국 사람이 지켜보는 수동 배포로 되돌아간다.