한양과학기술고등학교

에듀테크 프로젝트 대시보드

카나리 & 블루-그린 배포

카나리 배포 & 블루-그린 배포

새 버전을 배포했는데 버그가 있다면? 모든 사용자에게 한 번에 밀어 넣으면 전부 장애를 겪는다. 카나리(Canary)는 일부 트래픽만 새 버전으로 흘려보내 "탄광의 카나리"처럼 이상 징후를 미리 감지하고, 블루-그린(Blue-Green)은 새 버전을 별도 환경에 완전히 띄워둔 뒤 트래픽을 한 번에 전환해 문제가 생기면 즉시 되돌린다. 둘 다 목표는 같다 — 무중단으로, 안전하게 새 버전을 내보내는 것.

인터랙티브 데모

트래픽 분할

안정 버전 v1 90% 카나리 v2 10%

요청 흐름 (최근 60건)

v1 요청 / 에러율0 / 0%
v2(카나리) 요청 / 에러율0 / 0%
자동 롤백 임계값에러율 20% 초과 (최소 5건)

배포 설정

배포 로그

두 전략, 언제 무엇을

카나리 배포

  • 서서히 트래픽 비율을 늘려가며 검증
  • 일부 사용자만 위험에 노출 (blast radius 작음)
  • 실시간 지표(에러율·지연시간) 관찰이 필수
  • 같은 버전 두 벌을 동시에 운영 → 인프라 복잡도↑
  • Kubernetes/Istio, Flagger, AWS App Mesh 등에서 지원

블루-그린 배포

  • 한 번에 전체 트래픽을 전환 (all-or-nothing)
  • 배포 전 GREEN에서 충분히 검증 가능
  • 롤백이 즉각적 — 스위치만 되돌리면 끝
  • 동일 규모 환경을 두 벌 유지 → 비용 2배
  • DB 스키마 등 상태 공유 자원의 하위 호환이 까다로움

핵심 로직 (의사 코드)

# 카나리: 요청마다 가중치 기반으로 버전 선택
def route_canary(canary_pct):
    if random() * 100 < canary_pct:
        return "v2"   # 카나리로
    return "v1"       # 안정 버전으로

# 자동 롤백: 카나리 에러율이 임계값을 넘으면 즉시 0%로
if v2_requests >= MIN_SAMPLES and v2_error_rate > THRESHOLD:
    canary_pct = 0
    alert("카나리 에러율 초과 — 자동 롤백")

# 블루-그린: 로드밸런서가 가리키는 대상만 원자적으로 교체
def flip(current_live):
    return "green" if current_live == "blue" else "blue"
lb.upstream = flip(lb.upstream)   # 트래픽 100%가 한 번에 이동

현실에서는

  • 롤링 업데이트와 구분: 카나리·블루-그린은 "구버전 인스턴스를 하나씩 새 버전으로 교체"하는 롤링 업데이트와 다르다. 롤링은 중간에 신구 버전이 섞이지만 트래픽 비율을 의도적으로 제어하지는 않는다.
  • 피처 플래그와의 차이: 배포(코드를 서버에 올리는 것)와 릴리즈(사용자에게 기능을 보이는 것)를 분리하는 것이 피처 플래그다. 카나리·블루-그린은 배포 인프라 수준의 전략이고, 피처 플래그는 코드 수준의 스위치 — 둘을 함께 쓰면 더 세밀하게 제어할 수 있다.
  • 관측 가능성이 전제 조건: 카나리의 자동 판단(에러율·p99 지연시간 등)은 좋은 모니터링 없이는 불가능하다. Flagger, Argo Rollouts 같은 도구가 Prometheus 지표를 보고 자동으로 승격/롤백을 결정한다.
  • DB 마이그레이션 함정: 블루-그린 전환 순간에도 두 버전이 같은 DB를 볼 수 있어야 한다. 컬럼 삭제·타입 변경처럼 하위 호환이 깨지는 스키마 변경은 여러 배포에 걸쳐 단계적으로(expand-contract) 진행해야 한다.
  • 세션 고정 문제: 카나리 중 같은 사용자가 요청마다 다른 버전에 걸리면 혼란스러울 수 있어, 쿠키·사용자 ID 해시로 같은 사용자는 같은 버전에 계속 붙이는 sticky routing을 쓰기도 한다.