Argo Rollouts BlueGreen 배포 전략 — 카나리와 다른 점, 그리고 언제 선택해야 하는가
배포 전략을 고민할 때마다 "카나리로 할까, BlueGreen으로 할까?" 앞에서 잠깐 멈추게 됩니다. 저도 처음엔 카나리가 더 안전하다고 막연히 생각했는데, 막상 DB 스키마를 바꾸는 릴리스를 카나리로 밀어붙였다가 꽤 곤란한 상황을 겪었습니다. 구버전 Pod이 새 스키마를 읽다가 오류를 뿜기 시작했고, 롤백하는 데 40분이 걸렸습니다. 그동안 서비스 오류율이 12%까지 치솟았어요. 그날 이후 "아, 이건 BlueGreen이어야 했구나"를 뼈저리게 실감했습니다.
이 글은 Argo Rollouts로 BlueGreen 전략을 직접 구성하면서, 카나리와의 차이를 실무 맥락에서 이해하는 것을 목표로 합니다. 단순 YAML 복붙이 아니라, 왜 BlueGreen의 즉각 전환이 특정 상황에서 결정적인 차이를 만드는지, 어떤 기준으로 두 전략을 고르면 좋은지를 같이 짚어볼 것입니다.
이 글을 읽기 전에: Kubernetes Service, Deployment, ReplicaSet 기본 개념에 익숙한 분에게 가장 도움이 됩니다. DB 마이그레이션이 포함된 릴리스나 API 브레이킹 체인지를 앞두고 있다면 특히 도움이 될 것입니다.
핵심 개념
BlueGreen이 "즉각 전환"이라는 게 정확히 무슨 뜻인가
BlueGreen 배포는 개념 자체는 단순합니다. 지금 운영 중인 환경(Blue)과 새 버전 환경(Green)을 동시에 띄워두고, Green이 준비되면 트래픽을 한 번에 넘깁니다. 핵심은 이 전환이 부분적으로 이루어지지 않는다는 점입니다.
Kubernetes에서 Argo Rollouts가 이걸 구현하는 방식은 꽤 우아합니다. activeService라는 Kubernetes Service의 selector를 새 ReplicaSet 해시로 업데이트하는 단일 API 호출 하나로 전환이 일어납니다. etcd에 대한 이 API 호출 자체는 원자적이기 때문에, 전환 명령이 "절반은 적용되고 절반은 안 된" 상태는 존재하지 않습니다. 다만 각 노드의 kube-proxy가 iptables/ipvs 규칙을 실제로 갱신하는 데는 수백 밀리초에서, 대규모 클러스터에서는 수 초의 전파 지연이 있을 수 있습니다. 실제로 이 시간이 문제가 되는 경우는 드물지만, "완벽히 동시에"보다는 "사실상 즉각적으로" 전환된다고 이해하는 것이 더 정확합니다.
즉각 전환(Atomic-like Switch): 트래픽이 구버전과 신버전에 동시에 분산되어 운영 트래픽을 동시 처리하는 구간이 없는 전환 방식. BlueGreen의 핵심 특성입니다.
카나리와 비교하면 이 차이가 더 선명해집니다.
| 구분 | BlueGreen | Canary |
|---|---|---|
| 트래픽 전환 방식 | 즉각적(사실상 원자적) 전환 | 점진적 비율 이동 |
| 운영 트래픽 동시 처리 기간 | 없음 | 전체 롤아웃 동안 공존 |
| 롤백 방식 | 서비스 포인터 재전환 | 가중치 0%로 축소 |
| 인프라 비용 | 2배 리소스 필요 | 추가 리소스 최소화 |
| 적합 상황 | 브레이킹 체인지, 대규모 릴리스 | 점진적 기능 검증, 고빈도 배포 |
Argo Rollouts BlueGreen의 생명주기
Rollout이 시작되면 내부적으로 다음 순서로 진행됩니다.
- Green ReplicaSet 생성 →
previewService가 Green을 가리키도록 전환됩니다. 이 시점에서 운영 트래픽은 여전히 Blue가 처리합니다. prePromotionAnalysis실행 (선택) → Prometheus나 Datadog 메트릭을 기반으로 Green의 상태를 자동 검증합니다.- 프로모션 →
activeService가 Green으로 전환됩니다. 이 순간이 즉각적 트래픽 전환입니다. postPromotionAnalysis실행 (선택) → 전환 후 스모크 테스트나 추가 검증을 수행합니다.- Blue ReplicaSet 제거 →
scaleDownDelaySeconds이후 구버전이 정리됩니다.
실전 적용
예시 1: 기본 BlueGreen Rollout 구성
Argo Rollouts의 BlueGreen을 사용하려면 먼저 activeService와 previewService 두 개의 Kubernetes Service가 필요합니다. 처음 보면 두 서비스가 selector만 빼고 거의 동일해서 "왜 이렇게 쓰지?" 싶을 수 있는데, 사실 초기에는 두 서비스 모두 같은 app: my-app selector를 갖습니다. Argo Rollouts가 배포를 진행하면서 각 서비스에 ReplicaSet 해시 라벨을 추가로 주입해 Blue와 Green을 구분하는 방식으로 동작합니다.
# active-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-active
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
---
# preview-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-preview
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080# rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v2
strategy:
blueGreen:
activeService: my-app-active
previewService: my-app-preview
autoPromotionEnabled: false # 수동 프로모션
previewReplicaCount: 1 # 비용 절감: Green은 1개로 검증 후 프로모션 시 풀 스케일
scaleDownDelaySeconds: 300 # 운영에서는 30초보다 넉넉하게
prePromotionAnalysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: my-app-preview
postPromotionAnalysis:
templates:
- templateName: smoke-test| 필드 | 역할 |
|---|---|
activeService |
운영 트래픽을 받는 Service (필수) |
previewService |
Green(신버전) 접근용 Service (선택, QA 검증에 활용) |
autoPromotionEnabled: false |
수동 프로모션 — 검증 후 직접 승인 |
previewReplicaCount: 1 |
Green을 최소 레플리카로 유지해 비용 절반 이하로 절감 |
scaleDownDelaySeconds: 300 |
프로모션 후 Blue를 5분간 유지 (롤백 여유 확보) |
prePromotionAnalysis |
프로모션 전 자동 메트릭 게이트 |
배포 후 수동으로 프로모션하려면 다음 명령어를 사용할 수 있습니다.
kubectl argo rollouts promote my-app문제가 생기면 즉시 이전 상태로 되돌릴 수 있습니다.
kubectl argo rollouts undo my-app예시 2: DB 브레이킹 체인지 배포 — 카나리가 아닌 BlueGreen이어야 하는 상황
기본 구성을 이해했다면, 이제 BlueGreen이 진짜 빛나는 시나리오를 볼 차례입니다. 실무에서 가장 전형적인 케이스는 DB 스키마를 하위 호환 없이 바꿔야 할 때입니다. 카나리를 쓰면 구버전(old schema 기대)과 신버전(new schema 사용)이 같은 DB를 동시에 바라보는 구간이 생깁니다. 저는 이 상황에서 데이터 충돌 오류를 경험했고, 그 이후로는 이런 릴리스에는 무조건 BlueGreen을 씁니다.
BlueGreen에서는 전환 전까지 구버전만 운영 트래픽을 처리하기 때문에, DB 마이그레이션 완료 여부를 확인한 뒤 수동으로 프로모션하는 흐름을 안전하게 구성할 수 있습니다.
# rollout-db-migration.yaml (strategy 부분)
strategy:
blueGreen:
activeService: api-active
previewService: api-preview
autoPromotionEnabled: false # 마이그레이션 확인 후 수동 프로모션
scaleDownDelaySeconds: 600 # 롤백 여유를 위해 10분 유지실제 배포 흐름은 이렇습니다. Rollout 이미지를 업데이트할 때는 kubectl argo rollouts set image를 사용하는 것이 공식 권장 방식입니다.
# 1. 새 이미지 배포 (Green 환경 생성됨, 트래픽은 여전히 Blue)
kubectl argo rollouts set image api app=api:v2
# 2. preview 서비스로 Green 상태 확인
curl http://api-preview/health
# 3. DB 마이그레이션 완료 확인 후 수동 프로모션
kubectl argo rollouts promote api
# 4. 문제 발생 시 즉시 롤백
kubectl argo rollouts undo apiExpand-Contract 패턴: 브레이킹 스키마 변경을 안전하게 하려면 두 단계가 필요합니다. 먼저 신구 컬럼을 모두 지원하는 중간 버전을 배포(Expand)하고, 이후 구버전 컬럼을 제거(Contract)하는 두 번의 배포로 나누는 전략입니다. 구체적으로는: ① 신 컬럼 추가 + 구 컬럼 유지 버전 배포 → ② 코드가 신 컬럼만 사용 확인 후 구 컬럼 제거 버전 배포. BlueGreen은 각 단계를 명확히 분리해주기 때문에 이 패턴의 Contract 단계에 가장 잘 맞는 배포 방식입니다.
예시 3: Prometheus 기반 자동 프로모션 게이트
수동 프로모션 흐름을 익혔다면, 메트릭 기반으로 프로모션 여부를 자동 판단하는 AnalysisTemplate도 붙여볼 수 있습니다. 이 예시에서는 30초 간격으로 5회, 총 2.5분간 성공률을 측정합니다. 이 수치는 "충분히 짧아 빠른 피드백을 주면서, 일시적인 스파이크를 평균화할 수 있는 최소 측정 시간"으로 잡은 것입니다. 처음 쓸 때는 successCondition을 넉넉하게 잡고 실제 메트릭 패턴을 관찰한 뒤 임계치를 조정해나가는 방식이 안전합니다.
# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 30s
count: 5
successCondition: result[0] >= 0.95
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(rate(http_requests_total{
service="{{ args.service-name }}",
status!~"5.."
}[2m]))
/
sum(rate(http_requests_total{
service="{{ args.service-name }}"
}[2m]))이 템플릿을 Rollout의 prePromotionAnalysis에 연결하면, Green의 에러율이 5% 미만일 때만 자동으로 프로모션이 진행됩니다. 조건을 충족하지 못하면 Rollout이 자동으로 중단되고 Blue가 계속 운영 트래픽을 처리합니다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| 즉각적 전환 | 운영 트래픽을 동시 처리하는 중간 구간이 없어 버전 혼재로 인한 엣지 케이스를 원천 차단 |
| 즉각적 롤백 | 서비스 포인터만 되돌리면 수 초 내 롤백 완료 |
| 격리된 검증 환경 | previewService로 프로덕션 트래픽 없이 신버전을 완전히 테스트 가능 |
| 명확한 운영 상태 | 언제나 Blue 또는 Green 중 하나 — 운영 복잡도 최소화 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 2배 인프라 비용 | 프로모션 전까지 두 세트의 ReplicaSet이 동시 실행 | previewReplicaCount로 Green을 최소 레플리카로 유지하다 프로모션 시 스케일업 |
| 실 트래픽 검증 불가 | 전환 전 신버전은 실사용자 부하를 받지 않아 프로덕션 동작 예측이 제한됨 | 부하 테스트를 preview 환경에 별도 수행하거나, 일부 기능은 카나리로 먼저 검증 |
| 세션 유지 문제 | 스티키 세션 사용 시 전환 후 세션이 끊길 수 있음 | 전환 전 세션 재발급 전략 수립 또는 stateless 설계 권장 |
| scaleDownDelay 오설정 | 너무 짧으면 롤백 시 Blue가 이미 삭제됨 | 운영에서는 기본값 30초보다 300초 이상 권장 |
previewReplicaCount:
spec.strategy.blueGreen.previewReplicaCount로 Green 환경의 레플리카 수를 별도 지정할 수 있습니다. 비용이 걱정된다면 Green을 1개 레플리카로 띄워 검증하고, 프로모션 시점에 전체 레플리카 수로 확장되는 방식으로 비용을 절반 이하로 줄일 수 있습니다.
실무에서 가장 흔한 실수
-
scaleDownDelaySeconds를 기본값(30초)으로 두는 것 — 저는 실제로 이 실수를 운영에서 한 번 겪었습니다. 프로모션 직후 문제를 발견해 롤백하려 했는데, 30초 만에 Blue가 이미 삭제된 뒤였어요. 그날 밤이 꽤 길었습니다. 운영에서는 최소 5분(300초) 이상 유지하는 것을 권장합니다. -
autoPromotionEnabled: false로 설정해놓고 CI/CD 파이프라인에서 프로모션 단계를 빠뜨리는 것 — Green이 생성된 채로 트래픽 전환이 영원히 일어나지 않아, 두 세트의 ReplicaSet이 계속 실행되는 상황이 생깁니다.kubectl argo rollouts promote호출을 파이프라인에 명시적으로 포함시켜두는 것을 권장합니다. -
DB 마이그레이션을 BlueGreen과 함께 쓸 때 Expand-Contract 패턴을 건너뛰는 것 — BlueGreen이 즉각 전환을 보장하더라도, 이전 버전으로 롤백했을 때 신 스키마와 충돌이 없는지는 별도로 설계해야 합니다. 롤백 경로까지 포함한 스키마 설계가 없으면 BlueGreen이 주는 빠른 롤백 보장이 무색해집니다.
마치며
BlueGreen은 "두 버전이 절대 동시에 운영 트래픽을 처리하면 안 된다"는 제약이 있을 때 선택하는 전략이고, 카나리는 "실 사용자로 점진적으로 검증하고 싶을 때" 선택하는 전략입니다.
두 전략은 경쟁 관계가 아니라 상황에 따라 고르는 도구입니다. 현장에서 보면, 안정성이 중요한 서비스에는 BlueGreen, 고빈도 배포와 기능 검증이 필요한 서비스에는 카나리를 조합하는 팀이 점점 늘고 있습니다.
지금 바로 시작해볼 수 있는 3단계:
-
Argo Rollouts 설치 및 BlueGreen 환경 구성 — 로컬 kind 클러스터에 Argo Rollouts를 설치하고(공식 문서의 설치 가이드를 참고하시면 됩니다), 위의
active-service.yaml과rollout.yaml을 적용해 기본 BlueGreen 흐름을 직접 확인해볼 수 있습니다. -
kubectl 플러그인으로 Rollout 상태 모니터링 —
kubectl argo rollouts get rollout my-app --watch로 Green 생성 → 프로모션 → Blue 제거 단계가 실시간으로 어떻게 진행되는지 눈으로 확인해볼 수 있습니다.promote,undo,abort명령어를 직접 실행해보면 롤백 흐름도 자연스럽게 익힐 수 있습니다. -
AnalysisTemplate 연결 — Prometheus가 이미 있는 환경이라면 예시 3의
success-rate템플릿을 그대로 적용해서 자동 프로모션 게이트를 붙여볼 수 있습니다. 처음엔successCondition을 넉넉하게 잡아두고 실제 메트릭 값을 관찰하면서 임계치를 조정해나가는 방식이 안전합니다.
참고 자료
- BlueGreen Deployment Strategy — Argo Rollouts 공식 문서 — BlueGreen의 모든 설정값 레퍼런스
- Blue/green deployment strategy with Argo Rollouts — Red Hat Developer — 실제 적용 예시 중심의 실용적인 설명
- How to Automate Blue-Green & Canary Deployments with Argo Rollouts — Akuity — CI/CD 파이프라인 자동화 패턴
- Blue/green Versus Canary Deployments: 6 Differences And How To Choose — Octopus Deploy — 두 전략의 차이를 비교하는 포괄적인 가이드
- Chapter 1. Using Argo Rollouts for progressive deployment delivery — Red Hat OpenShift GitOps 1.11 — 엔터프라이즈 환경 적용 레퍼런스
- GitOps in 2025: From Old-School Updates to the Modern Way — CNCF — 최신 GitOps 트렌드와 Argo Rollouts의 위치
- Blue-green vs canary deployments: safer API and DB changes — AppMaster — API·DB 변경 시나리오별 전략 선택 기준
- Progressive Delivery on Kubernetes: From Blue-Green to GitOps-Powered Rollouts — Medium — BlueGreen에서 GitOps 통합까지의 흐름 정리