프로그레시브 딜리버리란? 카나리, 블루그린, 피처 플래그
요약
프로그레시브 딜리버리란 변경을 작은 단계로 프로덕션에 내보내고, 각 단계를 실제 지표로 확인한 뒤 다음 단계로 넘어가는 릴리스 방식입니다. 배포와 릴리스를 분리하고, 카나리 릴리스, 블루그린 배포, 피처 플래그를 결합하며, 사전에 정한 오류율이나 지연 시간 임계값을 넘으면 자동 롤백에 의존합니다.
프로그레시브 딜리버리란 소프트웨어를 작은 단계로, 통제된 방식으로 프로덕션에 내보내는 릴리스 방식입니다. 각 단계는 다음 단계로 넘어가기 전에 실제 지표로 확인되고, 수치가 나빠지면 릴리스가 멈추거나 스스로 롤백됩니다. 한 번의 배포에 전체 사용자 기반을 걸 필요가 없어집니다.
익숙한 상황일 겁니다. 풀 리퀘스트가 승인되고 CI도 초록불이며, 화요일 오후에 배포가 나갑니다. 20분 뒤 Slack에서 누군가 결제 화면 응답 지연이 왜 두 배가 됐는지 묻습니다. 프로그레시브 딜리버리는 이 대화를 짧게 만들고, 문제가 전체 트래픽 100%가 아니라 5%에서만 드러나도록 하려고 있습니다.
프로그레시브 딜리버리는 실제로 무엇을 바꿀까요?
전통적인 지속적 배포(Continuous Delivery)는 한 가지 질문에 답합니다. 이 변경을 프로덕션에 안전하게 올릴 수 있는가? 프로그레시브 딜리버리는 두 번째 질문을 더합니다. 누가 가장 먼저 보고, 무엇을 보고 멈춰야 하는가?
핵심은 배포와 릴리스를 분리하는 것입니다. 배포는 새 코드가 서버에서 실행되는 것이고, 릴리스는 사용자가 그 코드에 노출되는 것입니다. 두 가지가 분리되면 수요일 오후 2시에 배포하더라도, 원하는 시점에 선택한 사용자 집단에게 되돌릴 방법을 갖추고 릴리스할 수 있습니다.
읽게 될 자료 대부분은 세 가지 구성 요소를 말합니다. 점진적 트래픽 전환(카나리), 병렬 환경(블루그린), 그리고 피처 플래그입니다. 이들은 서로 경쟁하지 않습니다. 성숙한 팀은 서로 다른 계층에서 세 가지를 모두 씁니다.
카나리 릴리스: 트래픽을 얼마나, 누가 정하나요?
카나리 릴리스는 새 버전에 작은 비율의 트래픽, 예를 들어 5%를 보내고 나머지는 이전 버전에 둡니다. 오류율, 지연 시간, 포화도가 임계값 안에 머무르면 비율을 5%, 25%, 50%, 100%로 늘립니다. 그렇지 않으면 트래픽을 다시 돌립니다.
문제는 세밀한 분배에는 트래픽을 나눌 수 있는 무언가가 필요하다는 점입니다. Argo Rollouts 문서는 정밀한 카나리 비율에 서비스 메시나 인그레스 컨트롤러 같은 트래픽 관리자가 필요하다고 설명합니다. 그것이 없으면 레플리카 수 기준의 거친 제어만 가능해서, "5%"가 실제로는 파드 20개 중 1개를 뜻할 수도 있습니다.
단계별 카나리는 매니페스트에서 이렇게 보입니다. 일부러 짧게 썼습니다.
strategy:
canary:
steps:
- setWeight: 5
- pause: { duration: 10m } # 대시보드를 보거나 분석을 실행
- setWeight: 25
- pause: { duration: 10m }
- setWeight: 100서비스 트래픽이 너무 적어서 5%가 한 시간에 몇 건 수준이라면 카나리는 건너뛰세요. 신호를 한없이 기다리거나, 더 나쁘게는 잡음을 안전 신호로 착각하게 됩니다. 트래픽이 적은 서비스라면 내부 사용자를 대상으로 한 피처 플래그가 더 나은 첫 관문입니다.

블루그린 배포: 완전한 두 번째 환경이 값어치를 하는 경우는?
블루그린은 완전한 프로덕션 환경을 둘 운영합니다. 블루가 사용자에게 응답하고, 그린은 새 버전을 받아 유휴 상태에서 테스트합니다. 만족스러우면 트래픽을 한쪽에서 다른 쪽으로 전환합니다.
Argo Rollouts 문서에 따르면 전환은 한 번에 이뤄집니다. 새 버전이 검증될 때까지 이전 버전이 프로덕션 트래픽을 모두 받고, 그 뒤에 분배가 0%에서 100%로 바뀝니다. 이것이 장점이자 약점입니다. 롤백은 한 번 되돌리는 것이라 빠르지만, 테스트는 실제 사용자가 들어오기 전에 이뤄지고, 두 환경이 동시에 도는 동안 인프라 비용은 두 배가 됩니다.
부분 롤아웃이 혼란을 주거나 위험한 서비스라면 가치가 있습니다. 예를 들어 두 버전이 동시에 요청을 처리하면 안 되는 결제 경로가 그렇습니다. 두 버전이 동시에 실행될 수 없는 데이터베이스 마이그레이션이 있다면 건너뛰세요. 그렇지 않으면 "즉시 롤백"은 허구가 됩니다.

피처 플래그는 어디에 들어가나요?
카나리와 블루그린은 인프라 수준에서 동작합니다. 피처 플래그는 애플리케이션 안에서 동작합니다. 플래그는 코드 경로를 조건문으로 감싸서, 재배포 없이 런타임에 켜고 끌 수 있게 합니다.
그래서 플래그는 도구 상자에서 가장 세밀한 수단입니다. 기능을 직원에게 먼저 열고, 그다음 계정의 1%에, 그다음 특정 고객 세그먼트에 열 수 있고, 문제가 생기면 몇 초 안에 끌 수 있습니다. 어떤 팀은 플래그를 여러 기법 중 하나로만 보고, 다른 팀은 전체 접근법을 가능하게 하는 요소로 봅니다. 실무에서는 두 번째 관점이 맞습니다. 서버 단위가 아니라 사용자 단위로 릴리스하고 싶은 순간 플래그가 필요해지기 때문입니다.
다만 플래그에는 비용이 있습니다. 모든 플래그는 테스트가 커버해야 하는 분기이고, 누군가 닫아야 하는 정리 티켓입니다. 메커니즘과 기술 부채에 대한 더 긴 설명은 피처 플래그란 무엇인가에서 다뤘습니다. 기본적으로 각 플래그를 짧은 수명으로 보고, 담당자와 제거 날짜를 정해 두세요.
LaunchDarkly와 Statsig는 관리 계층을 판매합니다. 타기팅 규칙, 감사 로그, 점진적 비율 롤아웃, 실험 기능이 여기에 포함됩니다.
롤아웃이 단지 느린 것이 아니라 "점진적"이 되려면?
자동화입니다. 사람이 대시보드를 들여다보는 동안 10분씩 멈춰 있는 롤아웃은 느린 배포일 뿐입니다. 기계가 지표를 확인하고 판단을 내릴 때 비로소 프로그레시브 딜리버리가 됩니다.
패턴은 어디서나 같습니다.
릴리스 전에 신호를 정의합니다. 오류율, p95 지연 시간, 결제 완료율 같은 비즈니스 지표 하나입니다.
"중단"을 의미하는 임계값을 정하고, 머릿속이 아니라 설정 파일에 적습니다.
컨트롤러가 그 신호를 바탕으로 승격, 보류, 롤백을 결정하게 합니다.
Argo Rollouts는 지표 공급자와 통합되어, 검사 통과 여부에 따라 롤아웃을 자동으로 승격하거나 중단할 수 있습니다. 우리가 검토한 자료 중 하나는 이렇게 단언합니다. 자동 롤백이 없는 프로그레시브 딜리버리는 그냥 느린 배포일 뿐이라고요. 우리도 같은 생각입니다.

어떤 지표가 롤아웃을 통제해야 할까요?
적게 유지하세요. 이미 신뢰하는 지표 3~4개가, 한 번도 알람을 설정해 본 적 없는 지표 20개보다 낫습니다.
시작점으로 쓸 만한 집합은 이렇습니다. 기준 버전 대비 카나리의 HTTP 5xx 비율, 기준 대비 카나리의 p95 지연 시간, 포화도(CPU, 메모리, 큐 깊이), 그리고 제품 지표 하나입니다. 카나리를 "지난주"가 아니라 같은 시점의 기준 버전과 비교하세요. 트래픽 패턴은 계속 바뀌기 때문입니다.
여기서 관측 가능성 스택은 선택 사항이 아니게 됩니다. 버전별 또는 플래그 변형별로 지표를 나눠 볼 수 없다면 카나리와 기준을 구분할 수 없고, 이 접근법 전체가 무너집니다. 관측 가능성이 무엇인지, 그곳까지 어떻게 가는지는 관측 가능성이란 무엇인가에서 다뤘습니다.
프로그레시브 딜리버리는 트렁크 기반 개발과 어떤 관계인가요?
잘 맞습니다. 트렁크 기반 개발은 브랜치를 짧게 유지하고 작은 변경을 자주 병합합니다. 위험은 완성되지 않았거나 충분히 테스트되지 않은 작업이 메인에 더 자주 들어간다는 점입니다. 프로그레시브 딜리버리가 이를 안전하게 만듭니다. 코드가 트렁크에 들어가고, 플래그 뒤에 숨겨진 채 배포되고, 점진적으로 릴리스됩니다.
작은 배치와 점진적 노출은 디버깅 비용도 낮춥니다. 카나리가 실패하면 의심할 목록이 40개 변경이 아니라 1개 변경입니다. 밤 11시에 한 주 동안 병합된 커밋을 이분 탐색해 본 사람이라면 그 가치를 알 겁니다.
10~30명 규모 팀의 현실적인 첫 단계는 무엇인가요?
서비스 메시를 설치하는 것으로 시작하지 마세요. 멈춤 버튼을 얻는 가장 작은 방법부터 시작하세요.
1주차: 위험한 기능 하나를 플래그 뒤에 두고, 먼저 팀 내부에만 여세요.
2주차: 오류율과 지연 시간을 버전별로 보여 주는 대시보드를 추가하세요. 도구가 버전별 분할을 지원하지 않는다면 그것부터 고치세요.
3주차 이후: 상태가 없는(stateless) 서비스 하나를 2~3단계와 오류율 기준 자동 중단을 갖춘 카나리 컨트롤러로 옮기세요.
시간 단위로 측정하세요. "안전하다는 느낌"이 아니라 숫자로요. 사용자 중 작은 일부에 국한된 장애가 몇 건이었는지, 롤백에 얼마나 걸렸는지 세어 보세요. 이 두 숫자가 팀에서 효과가 있는지 알려 줄 겁니다.
프로그레시브 롤아웃은 보통 어디서 깨지나요?
세 곳이 있고, 컨트롤러는 그중 하나가 아닙니다.
데이터베이스 마이그레이션. 카나리는 같은 데이터베이스에 두 버전의 코드가 동시에 접근한다는 뜻입니다. N+1 버전이 N 버전이 아직 읽는 컬럼을 삭제하거나 이름을 바꾸면, 카나리가 기준 버전을 무너뜨립니다. 지루하지만 확실한 해결책은 확장 후 축소(expand and contract)입니다. 새 컬럼을 먼저 추가하고, 두 곳에 쓰는 코드를 배포하고, 백필하고, 읽기를 전환한 뒤, 나중에야 예전 컬럼을 제거합니다.
고정 세션과 캐시. 사용자가 요청마다 이전 버전과 새 버전 사이를 오가면, 아무도 재현하지 못하는 버그가 생깁니다. 롤아웃 기간 동안 쿠키, 계정 ID 또는 플래그 평가로 사용자를 한 변형에 고정하세요.
지연되는 지표. 한 시간 단위로 갱신되는 전환 지표로는 10분짜리 카나리 단계를 통제할 수 없습니다. 롤아웃 중에는 빠른 신호(오류, 지연 시간)로 통제하고, 50%에서 100%로 넘어가기 전에 느린 비즈니스 지표를 검토하세요.
저장소에서 무엇이 라이브 상태인지 어떻게 추적하나요?
프로그레시브 딜리버리는 릴리스를 설정 파일, 플래그 정의, 롤아웃 매니페스트, 대시보드에 걸쳐 퍼뜨립니다. 몇 달이 지나면 "새 결제 경로를 보호하는 플래그가 무엇이고 담당자는 누구인가?"라는 질문이 익숙한 일과가 됩니다. grep, blame, 그리고 누군가에게 묻기.
이것은 도구 문제가 아니라 코드를 읽는 문제입니다. 플래그 키로 저장소를 검색하고 각 참조를 호출 지점까지 따라가는 것이, 죽은 플래그와 반쯤 끝난 롤아웃을 찾는 가장 빠른 방법입니다. "이 플래그는 어디서 평가되고, 꺼지면 무슨 일이 일어나는가?"에 실제 코드를 기반으로 답해 주는 도구는, 또 하나의 대시보드보다 이 작업에서 더 많은 시간을 아껴 줍니다.
무엇을 건너뛸까요?
인프라 비용이 이미 회의 안건이라면 모든 것에 블루그린을 쓰지 마세요. 트래픽이 거의 없는 서비스에는 카나리를 쓰지 마세요. 새벽 3시에 팀 중 누구도 디버그할 수 없는 롤아웃 도구도 건너뛰세요.
진짜 문제는 고른 전략이 아닙니다. 코드를 배포하는 것과 그것이 프로덕션에서 무엇을 하는지 아는 것 사이의 간극입니다. 프로그레시브 딜리버리는 트래픽 조각 하나씩 그 간극을 줄입니다. 그리고 가장 중요한 것은 첫 조각입니다. 작게 만들고, 관찰 가능하게 만들고, 끌 수 있는 스위치를 주세요.