Theme:

새 버전을 배포할 때 "전체 사용자에게 한 번에" vs "일부에게 먼저", 어떤 전략이 안전할까요?

배포 전략에 정답은 없습니다. 서비스 특성, 팀 역량, 리스크 허용 범위에 따라 달라집니다. Kubernetes는 기본 롤링 업데이트 외에도 카나리, Blue-Green 같은 고급 배포 전략을 구현할 수 있는 도구를 제공합니다.

배포 전략 비교

전략다운타임리소스롤백 속도복잡도
롤링 업데이트없음약간 추가중간낮음
Blue-Green없음2배매우 빠름중간
카나리없음약간 추가빠름높음
Recreate있음추가 없음느림낮음

롤링 업데이트 (기본)

Kubernetes Deployment의 기본 전략입니다.

YAML
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이 교체될 때까지 확인 어려움

롤링 업데이트 최적화

YAML
spec:
  minReadySeconds: 30          # Ready 후 30초 대기 — 안정성 확보
  progressDeadlineSeconds: 300  # 5분 내 완료 안 되면 실패
  strategy:
    rollingUpdate:
      maxSurge: 25%            # 비율로 지정 가능
      maxUnavailable: 0        # 무중단 보장

Blue-Green 배포

구 버전(Blue)과 새 버전(Green)을 동시에 배포한 후, 트래픽을 한 번에 전환합니다.

Service 셀렉터 전환 방식

YAML
# 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
SHELL
# 트래픽 전환 (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 카나리 어노테이션

YAML
# 기존 서비스 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

트래픽 비율을 점진적으로 올려가며 모니터링합니다.

SHELL
# 10% → 25% → 50% → 100%
kubectl annotate ingress web-app-canary \
  nginx.ingress.kubernetes.io/canary-weight="25" --overwrite

헤더 기반 카나리

YAML
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을 선언적으로 구현합니다.

SHELL
# 설치
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

카나리 Rollout

YAML
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

YAML
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 — 메트릭 기반 자동 판단

YAML
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% 미만이면 자동 롤백합니다.

SHELL
# 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를 도입하면 메트릭 기반 자동 분석과 프로모션으로 배포 안전성을 한 단계 끌어올릴 수 있습니다.

댓글 로딩 중...