목요일 14:22, 스테이징에서 이틀 돌린 결제 API 핫픽스가 프로덕션 카나리 5%에 올라갔다. 레디니스 프로브는 초록, 배포 파이프라인은 초록, 슬랙 배포 채널에도 "canary healthy" 알림이 떴다. 14분 뒤 결제 5xx가 정상의 6배로 뛰었고, 온콜은 전량 롤백 버튼을 눌렀다.
문제는 코드 한 줄이 아니었다. 카나리 트래픽을 "살아 있음"만으로 통과시킨 관측이 문제였다. 헬스체크는 통과하는데 비즈니스 에러율·지연·특정 테넌트만 깨지는 회귀를 보지 못했다. 이 기록은 B2B 구독 결제 백엔드 팀이 카나리 5% 실패 → 전량 롤백 → 분석 파이프라인 재설계까지 간 문제·시도·결과를 시간순으로 복원한 케이스다. 기업명과 일부 수치는 익명 처리했다.
서비스는 쿠버네티스 Deployment 2개(stable / canary) 앞에 인그레스 가중치 라우팅을 둔 구조였다. 새 버전은 이미지 태그 한 칸, 환경 변수 두 개, 결제 벤더 SDK 마이너 업데이트가 묶여 있었다. 카나리 비율은 5% 고정, 승격은 수동 승인 한 번이었다.
시각
사건
관측
14:22
canary 파드 3대 Ready
/healthz 200, 배포 초록
14:24
인그레스 가중치 95/5 적용
전체 5xx 아직 정상 범위
14:31
canary 쪽 p95 지연 상승
대시보드는 전체 평균만 봄 → 미탐
14:36
결제 확인 API 4xx/5xx 혼합 증가
특정 테넌트 3곳이 먼저 티켓
14:48
온콜 호출, 카나리 로그 필터 시작
version=canary 라벨 누락 구간 발견
15:02
가중치 0/100 롤백
에러율 4분 내 정상대 복귀
15:18
포스트모템 킥오프
장애 체감 약 56분
전체 트래픽 기준으로 보면 5xx 상승폭은 "살짝 빨간" 정도였다. 카나리 5%에 몰린 실패가 평균에 희석된 탓이다. 고객 티켓은 평균보다 먼저 왔다.
전체 평균은 초록인데 카나리 슬라이스만 빨간 전형적인 희석 패턴
원인 분해 | 헬스체크 초록이 가린 네 가지
레디니스 프로브는 프로세스 기동과 DB 핑만 봤다. 결제 벤더 SDK 초기화 경로의 타임아웃·서명 헤더 변경은 프로브 범위 밖이었다. 포스트모템에서 묶은 원인은 네 갈래다.
관측 단위 오류 — 성공률·지연·에러를 Deployment 전체 평균으로만 알림. canary 라벨 슬라이스가 대시보드에 없었다.
라벨·트레이스 누락 — 일부 미들웨어가 version 라벨을 응답 메트릭에 안 붙였다. 카나리 실패를 stable로 오인하는 구간이 생겼다.
스티키·캐시 혼선 — 세션 스티키가 있는 경로에서 같은 사용자가 stable과 canary를 오가며 서명 키 불일치 4xx가 났다.
승격 기준이 기술 헬스뿐 — "파드 Ready + 5분간 전체 5xx < 1%" 만 있으면 수동 승격 가능. 결제 성공률·특정 엔드포인트·테넌트 슬라이스가 기준에 없었다.
포스트모템 한 줄: "카나리는 5%만 태운 것이 아니라, 실패 신호도 5%로 희석했다. 평균이 아니라 슬라이스를 봤어야 했다."
시도 1 | 전량 롤백과 이미지 고정
당일 응급 조치는 단순했다. 인그레스 가중치를 0/100으로 돌리고 canary Deployment 레플리카를 0으로 내렸다. 에러율은 4분 안에 정상대로 돌아왔다. 이미지는 이전 태그로 고정했고, 벤더 SDK 업데이트가 들어간 커밋은 release 브랜치에서 분리했다.
롤백 자체는 성공했다. 다만 사후에 보면 롤백 결정까지 40분이 걸렸다. 그 사이 온콜은 전체 로그를 뒤졌고, 카나리만 필터하는 쿼리가 런북에 없었다. "배포 직후 이상이면 가중치 0" 한 줄이 런북 맨 위에 없었던 것이 1차 교훈이다.
프로덕션 배포 전 점검 목록에 카나리 롤백 한 줄 명령을 넣어 두라는 조언과 맞닿는다. 참고: 프로덕션 배포 체크리스트.
시도 2 | 슬라이스 메트릭과 승격 게이트
다음 주 스프린트에서 관측을 손봤다. 응답 메트릭·로그·트레이스에 deploy_group=stable|canary 라벨을 강제했고, 대시보드에 카나리 전용 패널 네 개를 고정했다.
게이트 항목
이전
이후(이 팀 값)
헬스
/healthz 200
healthz + 결제 벤더 핑(별도 프로브)
에러율
전체 5xx < 1%
canary 5xx ≤ stable+0.5%p, 최소 표본 200
지연
없음
canary p95 ≤ stable p95 × 1.2
비즈니스
없음
결제 승인 성공률 슬라이스 비교
승격
5분 후 수동
게이트 15분 연속 통과 후 승인
알림도 바꿨다. 전체 5xx 임계값만 있던 채널에 canary_error_budget_burn 을 추가했다. 카나리 실패율이 stable 대비 벌어지면 배포 채널에 바로 멘션된다. 구조화 로그에 deploy_group이 들어가면 온콜 쿼리 시간이 크게 줄었다. 관련: 프로덕션 구조화 로깅 체크리스트, Sentry 런타임 에러 모니터링.
승격 게이트는 전체 평균이 아니라 stable 대비 상대 비교로 바꿨다
시도 3 | 단계 승격과 자동 중단
3주차에는 비율을 5% 고정에서 5% → 20% → 50% → 100% 단계로 바꿨다. 각 단계는 게이트 통과 시간이 필요하다. 한 단계라도 실패하면 가중치를 0으로 돌리고 canary 파드를 스케일 다운한다. 도구는 팀 인프라에 맞춰 인그레스 가중치 + 간단한 분석 잡(cron)으로 시작했고, 이후 프로그레시브 딜리버리 컨트롤러 도입을 검토했다.
자동 중단 조건은 공격적으로 잡았다. 표본이 부족할 때는 승격하지 않고 기다린다. 트래픽이 적은 심야 카나리는 "에러 0건"이 곧 안전이 아니다. 최소 요청 수(이 팀은 단계당 200)를 못 채우면 다음 영업일 피크로 연다.