배포 전략 — 롤링 업데이트, 카나리, Blue-Green을 Kubernetes에서 구현하기
새 버전을 배포할 때 "전체 사용자에게 한 번에" vs "일부에게 먼저", 어떤 전략이 안전할까요?
배포 전략에 정답은 없습니다. 서비스 특성, 팀 역량, 리스크 허용 범위에 따라 달라집니다. Kubernetes는 기본 롤링 업데이트 외에도 카나리, Blue-Green 같은 고급 배포 전략을 구현할 수 있는 도구를 제공합니다.
배포 전략 비교
| 전략 | 다운타임 | 리소스 | 롤백 속도 | 복잡도 |
|---|---|---|---|---|
| 롤링 업데이트 | 없음 | 약간 추가 | 중간 | 낮음 |
| Blue-Green | 없음 | 2배 | 매우 빠름 | 중간 |
| 카나리 | 없음 | 약간 추가 | 빠름 | 높음 |
| Recreate | 있음 | 추가 없음 | 느림 | 낮음 |
롤링 업데이트 (기본)
Kubernetes Deployment의 기본 전략입니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 추가로 생성할 수 있는 Pod
maxUnavailable: 0 # 동시에 사용 불가한 Pod 수
template:
spec:
containers:
- name: app
image: web-app:2.0
readinessProbe: # 필수! 새 Pod이 Ready여야 교체 진행
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
장점: 간단하고 무중단 배포 가능 단점: 문제 감지가 느림 — 모든 Pod이 교체될 때까지 확인 어려움
롤링 업데이트 최적화
spec:
minReadySeconds: 30 # Ready 후 30초 대기 — 안정성 확보
progressDeadlineSeconds: 300 # 5분 내 완료 안 되면 실패
strategy:
rollingUpdate:
maxSurge: 25% # 비율로 지정 가능
maxUnavailable: 0 # 무중단 보장
Blue-Green 배포
구 버전(Blue)과 새 버전(Green)을 동시에 배포한 후, 트래픽을 한 번에 전환합니다.
Service 셀렉터 전환 방식
# Blue Deployment (현재 운영)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-blue
spec:
replicas: 4
selector:
matchLabels:
app: web-app
version: blue
template:
metadata:
labels:
app: web-app
version: blue
spec:
containers:
- name: app
image: web-app:1.0
---
# Green Deployment (새 버전)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-green
spec:
replicas: 4
selector:
matchLabels:
app: web-app
version: green
template:
metadata:
labels:
app: web-app
version: green
spec:
containers:
- name: app
image: web-app:2.0
---
# Service — selector로 Blue/Green 전환
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web-app
version: blue # green으로 변경하면 트래픽 전환!
ports:
- port: 80
targetPort: 8080
# 트래픽 전환 (Blue → Green)
kubectl patch svc web-app -p '{"spec":{"selector":{"version":"green"}}}'
# 롤백 (Green → Blue)
kubectl patch svc web-app -p '{"spec":{"selector":{"version":"blue"}}}'
장점: 즉시 롤백 가능, 전환 전 새 버전 테스트 가능 단점: 리소스 2배, 데이터베이스 스키마 호환성 필요
카나리 배포
전체 트래픽의 일부만 새 버전으로 보내서 안전성을 확인한 후 전체 배포합니다.
Nginx Ingress 카나리 어노테이션
# 기존 서비스 Ingress (v1)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-stable
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-stable
port:
number: 80
---
# 카나리 Ingress (v2) — 10% 트래픽
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% 트래픽
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-canary
port:
number: 80
트래픽 비율을 점진적으로 올려가며 모니터링합니다.
# 10% → 25% → 50% → 100%
kubectl annotate ingress web-app-canary \
nginx.ingress.kubernetes.io/canary-weight="25" --overwrite
헤더 기반 카나리
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "true"
X-Canary: true 헤더를 보내는 요청만 카나리로 라우팅합니다. 내부 테스트에 유용합니다.
Argo Rollouts — 고급 배포 자동화
Argo Rollouts는 Deployment를 대체하는 Rollout CRD를 제공하여 카나리/Blue-Green을 선언적으로 구현합니다.
# 설치
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
카나리 Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web-app
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 10 # 10% 트래픽
- pause: { duration: 5m } # 5분 대기
- setWeight: 30 # 30% 트래픽
- pause: { duration: 5m }
- setWeight: 60
- pause: { duration: 5m }
- setWeight: 100 # 전체 배포
canaryService: web-app-canary
stableService: web-app-stable
trafficRouting:
nginx:
stableIngress: web-app-ingress
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: app
image: web-app:2.0
Blue-Green Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web-app
spec:
replicas: 4
strategy:
blueGreen:
activeService: web-app-active # 현재 활성 Service
previewService: web-app-preview # 미리보기 Service
autoPromotionEnabled: false # 수동 승인 필요
prePromotionAnalysis: # 프로모션 전 자동 분석
templates:
- templateName: success-rate
scaleDownDelaySeconds: 300 # 이전 버전 5분 후 스케일 다운
selector:
matchLabels:
app: web-app
template:
spec:
containers:
- name: app
image: web-app:2.0
AnalysisTemplate — 메트릭 기반 자동 판단
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 1m
count: 5 # 5번 측정
successCondition: result[0] >= 0.95 # 성공률 95% 이상
failureLimit: 2 # 2번 실패하면 롤백
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(rate(http_requests_total{status=~"2.."}[5m]))
/ sum(rate(http_requests_total[5m]))
Prometheus에서 성공률을 측정하여 95% 미만이면 자동 롤백합니다.
# Rollout 상태 확인
kubectl argo rollouts get rollout web-app --watch
# 수동 프로모션 (Blue-Green에서 autoPromotionEnabled: false일 때)
kubectl argo rollouts promote web-app
# 중단
kubectl argo rollouts abort web-app
전략 선택 가이드
| 상황 | 추천 전략 |
|---|---|
| 일반적인 서비스 업데이트 | 롤링 업데이트 |
| 빠른 롤백이 중요한 경우 | Blue-Green |
| 점진적 검증이 필요한 경우 | 카나리 |
| DB 스키마 변경이 포함된 경우 | Blue-Green + DB 마이그레이션 |
| 대규모 서비스, 자동화된 검증 필요 | Argo Rollouts |
정리
롤링 업데이트는 Kubernetes의 기본이며 대부분의 경우 충분합니다. 더 안전한 배포가 필요하면 카나리(일부 트래픽으로 검증)나 Blue-Green(전체 환경 전환)을 사용하고, Argo Rollouts를 도입하면 메트릭 기반 자동 분석과 프로모션으로 배포 안전성을 한 단계 끌어올릴 수 있습니다.