IT/CI CD

Argo Rollouts vs Flagger, 카나리 배포 뭘 쓸까

gfrog 2026. 8. 4. 06:18

카나리 배포 도구를 다시 고를 일이 생겼다. 원래 팀에서 자체 스크립트로 트래픽을 조금씩 옮기던 방식을 쓰고 있었는데, 서비스가 늘어나면서 이런 로직을 CD 파이프라인에 직접 박아 넣는 게 한계에 왔다. "이제 진짜 프로그레시브 딜리버리 컨트롤러를 붙이자"는 결론에 도달했고, 후보는 사실상 둘이었다. Argo Rollouts와 Flagger.

둘 다 CNCF 프로젝트고, 둘 다 production 레퍼런스가 충분하다. 근데 이 둘이 문제를 푸는 방식이 꽤 다르다. 한 달 정도 병렬로 굴려보고 결국 하나를 골랐는데, 그 과정에서 정리한 내용을 남겨둔다.

워크로드를 대하는 태도가 다르다

가장 큰 구조적 차이는 이거다. Argo Rollouts는 Deployment 리소스를 Rollout이라는 커스텀 리소스로 대체한다. Flagger는 원래의 Deployment를 그대로 두고 옆에서 Canary CR로 감싼다.

이 차이가 실무에서 뭘 의미하냐면 — 기존에 Helm chart나 Kustomize 오버레이가 잔뜩 있는 프로젝트에 도입할 때, Flagger 쪽이 마이그레이션 부담이 훨씬 적다. Deployment YAML을 건드리지 않아도 되니까. 반면 Argo Rollouts는 kind: Deploymentkind: Rollout으로 바꾸는 작업이 필요하다. 물론 Argo Rollouts도 workloadRef로 기존 Deployment를 참조하는 방식을 지원하긴 하는데, 이걸 쓰면 Rollouts가 제공하는 기능 일부가 제한된다.

우리 팀 상황을 보면 마이크로서비스가 40개쯤 있고, 각각 Helm chart가 다르다. Deployment를 전부 Rollout으로 바꾸는 건 생각만 해도 피곤했다. 이 지점에서 Flagger가 매력적으로 보였다.

트래픽 제어 — 서비스 메시 의존도

Flagger는 트래픽 분할을 서비스 메시에 위임한다. Istio, Linkerd, App Mesh, Kuma, NGINX Ingress, Traefik, Gloo Edge, Contour 등을 지원한다. 즉 Flagger 자체는 트래픽을 직접 옮기지 않고, 메시의 VirtualService나 SMI TrafficSplit을 조작해서 비율을 바꾼다.

Argo Rollouts는 트래픽 라우팅 방식이 좀 더 다양하다. Istio, Linkerd, SMI 같은 메시도 지원하고, ALB, Nginx Ingress, Traefik, Apisix, Gateway API도 붙는다. 여기서 Gateway API 지원이 최근에 꽤 좋아졌다. Argo Rollouts 1.9에서 Gateway API 플러그인 GA 가까이 왔고, HTTPRoute 기반 트래픽 분할이 안정적으로 동작한다.

우리 팀은 마침 Nginx Ingress에서 Cilium Gateway로 넘어가는 중이었다. Cilium Gateway는 Gateway API 구현체다. 이 지점에서 Argo Rollouts의 Gateway API 지원이 갑자기 강력한 카드가 됐다. Flagger도 Gateway API를 지원하긴 하는데, 대상별 프로바이더 성숙도 차이가 아직 있었다.

자동 롤백 — 누가 언제 판단할까

여기가 두 도구의 철학이 가장 크게 갈리는 지점이다.

Flagger는 "선언적 자동화"에 가깝다. Canary CR에 이런 식으로 쓴다.

analysis:
  interval: 1m
  threshold: 5
  maxWeight: 50
  stepWeight: 10
  metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99
      interval: 1m

이렇게 설정해두면 Flagger가 알아서 10%씩 트래픽을 올리고, 매 1분마다 성공률이 99% 이상인지 확인하고, 5번 실패하면 롤백한다. 릴리스마다 사람이 개입할 필요가 없다. "돌려두면 알아서 굴러가는" 자동화를 원한다면 Flagger가 편하다.

Argo Rollouts는 "명시적 스텝"이다. 롤아웃 스텝을 순서대로 나열한다.

strategy:
  canary:
    steps:
    - setWeight: 5
    - pause: {duration: 10m}
    - setWeight: 20
    - pause: {}
    - analysis:
        templates:
        - templateName: success-rate
    - setWeight: 50
    - pause: {duration: 30m}

pause: {}가 눈에 띈다. 무기한 정지다. 사람이 UI에서 "promote" 버튼을 눌러야 다음 스텝으로 넘어간다. 이게 처음엔 번거로워 보였는데, 배포가 무거운 서비스에서는 오히려 안정감이 있다. "새벽에 자동으로 100% 트래픽이 이동되어 있는" 시나리오가 무섭다면 명시적 pause가 답이다.

메트릭 분석 자체는 둘 다 Prometheus, Datadog, CloudWatch, NewRelic 등을 지원해서 큰 차이는 없다. 다만 Argo Rollouts는 AnalysisTemplate이라는 재사용 가능한 리소스가 별도로 있어서 여러 서비스에 같은 분석 로직을 붙이기 편하다.

GitOps 궁합

이건 좀 뻔한 얘기다. ArgoCD 쓰면 Argo Rollouts, Flux 쓰면 Flagger. 만든 팀이 다르니까 인테그레이션도 자연스럽게 각자 쪽에 최적화돼 있다.

우리는 ArgoCD를 이미 쓰고 있었다. Application 리소스에서 Rollout의 상탗(healthy, degraded, progressing)를 그대로 인식하고, ArgoCD UI에서 카나리 진행 상황이 보인다. Flagger는 Flux와의 연동은 강력한데, ArgoCD와 붙이면 좀 어색해진다. Flagger가 Deployment를 조작하면 ArgoCD가 "이거 왜 spec이 바뀌었지?" 하고 out-of-sync로 인식하는 이슈가 있다. Argo CD에 ignoreDifferences를 잔뜩 넣어야 조용해진다.

그래서 우린 뭘 골랐냐

Argo Rollouts로 갔다. 이유는 셋이다.

첫째, 이미 ArgoCD를 쓰고 있어서 UI와 상태 관측이 일관됐다. 새 대시보드를 붙일 필요가 없었다.

둘째, Gateway API 마이그레이션과 시점이 맞았다. Cilium Gateway로 넘어가면서 Argo Rollouts의 Gateway API 플러그인을 붙였는데 정상 동작이 잘 됐다.

셋째, pause: {}. 아직 우리 팀은 100% 자동 승격에 대한 심리적 저항이 있다. 수동 promote 스텝을 넣을 수 있다는 게 무엇보다 중요했다. 나중에 조직이 성숙해지면 이 pause를 제거하면 그만이다.

물론 Flagger가 나쁘다는 얘기는 아니다. 정반대 상황 — Flux 쓰고, 이미 Istio가 안정적으로 깔려 있고, 릴리스마다 사람 개입 없이 자동으로 굴러가야 하는 조직이라면 나는 주저 없이 Flagger를 추천할 거다. 실제로 지인 회사에서는 Flagger로 하루에 200번씩 카나리를 굴리고 있고, 사람이 손대는 일이 거의 없다고 한다.

결론

결국 두 도구 중 뭐가 낫냐는 질문 자체가 잘못 잡혔다. 우리 팀 GitOps 스택이 뭐냐, 트래픽 라우팅이 뭐냐, 자동화 신뢰도가 어느 정도냐. 이 세 개 답하고 나면 답이 나온다.

혹시 Flagger에서 Argo Rollouts로 넘어간 경험 있는 분 있으면 댓글 남겨주세요. 반대 방향은 케이스가 좀 있는 것 같은데, 그 반대는 잘 못 봤다.