개인정보처리방침© 2026 DEV BAK - 기술블로그. All rights reserved.
DEV BAK - 기술블로그
DevOps

Istio + Argo Rollouts로 구성하는 카나리 배포: 파드 메트릭 격리부터 헤더 기반 테스트 라우팅까지

카나리 배포를 처음 도입했을 때 저도 비슷한 실수를 했습니다. Kubernetes 기본 Deployment로 레플리카 비율을 나눠서 "10% 카나리"라고 부르면 된다고 생각했거든요. 그런데 파드가 3개면 1개가 카나리인데, 그게 정확히 33%입니다. 여기서 문제가 끝나면 좋았을 텐데, 카나리와 stable 파드의 메트릭이 뒤섞이면서 성공률이 이상하게 측정됐습니다. 오염된 집계치를 기준으로 AnalysisTemplate 롤백 조건이 트리거됐고, 실제로는 아무 문제 없는 배포가 의미 없는 롤백으로 끝난 경험이 있습니다.

Istio의 VirtualService 가중치와 Argo Rollouts를 결합하면, 파드 수와 무관하게 트래픽 비율을 정밀하게 제어하면서 카나리 파드에 실제로 도달한 요청만 골라내 메트릭 분석까지 자동화됩니다. 여기에 setHeaderRoute를 더하면 일반 사용자는 stable 버전을 그대로 사용하면서 QA 팀만 헤더 하나로 카나리를 미리 검증하는 구성도 가능합니다.

이 글에서는 정밀한 트래픽 분배, 파드 레벨 메트릭 격리, 헤더 기반 테스트 라우팅 이 세 가지를 실제 YAML과 PromQL을 중심으로 풀어보겠습니다. Kubernetes를 운영 중이고 Prometheus로 메트릭을 수집하고 있으며, Istio나 Argo Rollouts를 도입했거나 도입을 고려 중인 분들을 대상으로 합니다. Kubernetes 기본 개념(Deployment, Service, ReplicaSet)은 알고 계신다는 전제로 진행합니다.


핵심 개념

왜 레플리카 비율이 아닌 VirtualService 가중치인가

Kubernetes 기본 방식은 파드 수의 비율로 트래픽이 결정됩니다. 정확히 5%만 카나리로 보내고 싶다면 파드를 20개 띄워야 한다는 계산이 나옵니다. 카나리 파드 2개 vs stable 파드 38개 같은 비율은 비용도 문제지만, 현실적으로 유지하기 어렵습니다.

Istio의 VirtualService는 이 문제를 레이어를 바꿔서 해결합니다. Envoy 사이드카가 각 파드에 주입되어 있고, VirtualService의 weight 값이 Envoy의 라우팅 결정을 직접 제어합니다. 파드가 몇 개이든 트래픽 비율은 YAML에 쓴 숫자 그대로입니다.

VirtualService: Istio에서 HTTP/gRPC 트래픽의 라우팅 규칙을 정의하는 CRD입니다. 어떤 요청을 어디로 얼마만큼 보낼지를 선언하며, Argo Rollouts가 카나리 단계를 진행하면서 이 리소스의 weight 값을 동적으로 수정합니다.

전체 아키텍처 흐름

글을 읽기 전에 전체 그림을 한 번 보면 각 구성 요소의 역할이 훨씬 명확하게 들어옵니다.

                     ┌────────────────────────────────────┐
  일반 요청 ─────────▶│       Istio Ingress Gateway         │
  X-Canary: true ───▶│          (Envoy Proxy)              │
                     └─────────────┬──────────────────────┘
                                   │ VirtualService
                           ┌───────┴─────────┐
                    weight │ 90%             │ 10% (또는 헤더 매칭)
                           ▼                 ▼
              ┌─────────────────┐   ┌─────────────────┐
              │  Stable Service │   │  Canary Service │
              └────────┬────────┘   └────────┬────────┘
                       │                     │
                       ▼                     ▼
              ┌─────────────────┐   ┌─────────────────┐
              │   Stable Pods   │   │   Canary Pods   │
              │ [Envoy Sidecar] │   │ [Envoy Sidecar] │
              └────────┬────────┘   └────────┬────────┘
                       │  메트릭              │  메트릭
                       └──────────┬──────────┘
                                  ▼
                           ┌────────────┐
                           │ Prometheus │◀── AnalysisTemplate 쿼리
                           └────────────┘
                                  ▲
                    ┌─────────────┴───────────────┐
                    │  Argo Rollouts Controller    │
                    │ (자동 프로모션 / 롤백 판단)   │
                    └─────────────────────────────┘

각 구성 요소의 역할을 정리하면 이렇습니다.

구성 요소 역할
Rollout CRD 카나리 단계(steps), 분석 연결, 트래픽 가중치 정의
VirtualService HTTP 라우팅 가중치(stable/canary) 동적 수정
DestinationRule stable·canary 서브셋을 파드 레이블로 구분
AnalysisTemplate Prometheus 쿼리로 자동 프로모션/롤백 판단
setHeaderRoute 특정 헤더가 있는 요청만 카나리 파드로 라우팅

AnalysisTemplate: Argo Rollouts에서 카나리 파드의 성능을 자동으로 평가하는 CRD입니다. Prometheus, Datadog, New Relic 등 다양한 메트릭 제공자를 지원하며, 조건을 만족하지 못하면 자동으로 롤백합니다.

파드 레벨 메트릭 격리의 원리

Istio 사이드카는 각 파드에서 수신하는 모든 요청에 대해 Prometheus 메트릭을 노출합니다. 핵심은 이 메트릭에 destination_workload 레이블이 붙는다는 점입니다.

promql
# 카나리 워크로드에 도달한 요청만 필터링
istio_requests_total{destination_workload="my-service-canary"}

my-service-canary는 Argo Rollouts가 생성하는 카나리 ReplicaSet의 이름입니다. 이 레이블 덕분에 전체 서비스의 메트릭이 아니라 "카나리 파드에 실제로 전달된 요청"만 쿼리할 수 있습니다.

Istio 레이블 의미
destination_workload 요청을 받은 워크로드 이름 (카나리/stable 구분 핵심)
source_workload 요청을 보낸 워크로드 이름
reporter "source" 또는 "destination" — 중복 집계를 막으려면 "destination"으로 고정
response_code HTTP 응답 코드

실전 적용

예시 1: stable/canary Service와 DestinationRule 준비

Argo Rollouts의 Istio 통합은 두 개의 별도 Kubernetes Service 오브젝트를 필요로 합니다. stableService와 canaryService는 Rollout manifest에서 참조하는 이름인데, 이 Service를 사전에 직접 생성해야 한다는 점이 처음에 놓치기 쉬운 포인트입니다. 이게 없으면 Rollout 컨트롤러가 오류를 내면서 배포가 진행되지 않습니다.

yaml
# 사전 준비: stable과 canary를 위한 별도 Service 생성
apiVersion: v1
kind: Service
metadata:
  name: my-service-stable
spec:
  selector:
    app: my-service
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: my-service-canary
spec:
  selector:
    app: my-service
  ports:
    - port: 80
      targetPort: 8080

처음에는 두 Service의 selector가 동일해도 됩니다. Argo Rollouts 컨트롤러가 롤아웃이 시작되면 각 Service의 selector에 rollouts-pod-template-hash 레이블을 자동으로 추가해서 stable 파드와 canary 파드를 각각의 Service로 분리해줍니다.

다음으로 DestinationRule로 stable과 canary 서브셋을 정의합니다.

yaml
# DestinationRule — stable/canary 서브셋 정의
# rollouts-pod-template-hash 값은 Argo Rollouts가 자동으로 관리하므로
# 수동으로 해시값을 채우거나 편집할 필요가 없습니다
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: my-service-dr
spec:
  host: my-service
  subsets:
    - name: stable
      labels:
        rollouts-pod-template-hash: stable   # Rollouts가 실제 해시값으로 자동 패치
    - name: canary
      labels:
        rollouts-pod-template-hash: canary   # Rollouts가 실제 해시값으로 자동 패치
yaml
# VirtualService — Argo Rollouts가 배포 단계마다 weight 값을 자동 수정
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-service-vs
spec:
  hosts:
    - my-service                  # spec.hosts는 필수 필드
  http:
    - name: primary
      route:
        - destination:
            host: my-service
            subset: stable
          weight: 100
        - destination:
            host: my-service
            subset: canary
          weight: 0

초기에는 weight: stable 100, canary 0으로 두어도 됩니다. Argo Rollouts가 setWeight 스텝에 따라 알아서 수정해줘서, 실제로 VirtualService를 직접 건드릴 일이 거의 없습니다. 솔직히 처음에는 이걸 직접 관리해야 하나 걱정했는데, 컨트롤러가 전부 처리해줘서 오히려 편했습니다.

예시 2: Rollout + AnalysisTemplate으로 자동 프로모션/롤백

Rollout 리소스에서 카나리 단계와 분석을 정의합니다. 아래는 핵심 전략 부분만 발췌한 예시입니다(전체 스펙에는 selector와 template 필드도 포함되어야 합니다).

yaml
# Rollout — 카나리 단계, 트래픽 라우팅, 분석 연결 (전략 부분 발췌)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-service
spec:
  # selector, replicas, template 등 기본 필드는 Deployment와 동일한 형태로 작성
  strategy:
    canary:
      stableService: my-service-stable    # 앞서 생성한 Service 참조
      canaryService: my-service-canary    # 앞서 생성한 Service 참조
      trafficRouting:
        istio:
          virtualService:
            name: my-service-vs
            routes:
              - primary
      steps:
        - setWeight: 10
        - pause: {duration: 5m}
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: canary-workload
                value: my-service-canary
        - setWeight: 50
        - pause: {duration: 10m}
        - setWeight: 100

카나리 파드만의 성공률을 측정하는 AnalysisTemplate은 다음과 같이 작성합니다.

yaml
# AnalysisTemplate — 카나리 파드에 도달한 요청의 성공률만 측정
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: canary-workload
  metrics:
    - name: success-rate
      interval: 1m
      successCondition: result[0] >= 0.95
      failureLimit: 3    # 누적 3회 실패 시 롤백 (연속 실패 기준은 consecutiveErrorLimit 사용)
      provider:
        prometheus:
          address: http://prometheus:9090
          query: |
            (
              sum(rate(istio_requests_total{
                destination_workload="{{args.canary-workload}}",
                reporter="destination",
                response_code!~"5.*"
              }[2m]))
              /
              sum(rate(istio_requests_total{
                destination_workload="{{args.canary-workload}}",
                reporter="destination"
              }[2m]))
            ) or on() vector(1)

reporter="destination" 조건을 빼면 source 쪽에서 보고하는 메트릭과 중복 집계될 수 있습니다. 처음에 이 조건 없이 쿼리를 썼다가 성공률이 이상하게 나왔던 경험이 있어서, 꼭 명시하는 것을 권장합니다.

PromQL 핵심 함수 간단 정리: rate(metric[2m])는 지난 2분간의 초당 평균 증가율을 계산합니다. sum()은 레이블 조합별로 분리된 시계열을 합칩니다. or on() vector(1)은 트래픽이 없어 결과가 NaN이 될 때 기본값 1(100% 성공)을 반환해 초기 트래픽 없는 단계에서 불필요한 롤백이 트리거되는 것을 막아줍니다.

쿼리 요소 설명
destination_workload="{{args.canary-workload}}" 카나리 파드에 도달한 요청만 필터링
reporter="destination" 수신 측 집계로 고정해 중복 방지
response_code!~"5.*" 5xx 제외해 성공 요청 비율 계산
or on() vector(1) 트래픽 없을 때 NaN 대신 기본값 반환
failureLimit: 3 누적 3회 실패 시 자동 롤백 트리거

예시 3: setHeaderRoute로 QA 팀만 카나리 테스트

이 패턴이 개인적으로 가장 실용적이라고 생각합니다. 운영 중인 서비스에 영향을 주지 않고 QA 팀이 카나리 파드를 먼저 검증할 수 있거든요.

yaml
# Rollout steps — 헤더 라우트 먼저 설정하고, 검증 후 가중치 트래픽 시작
steps:
  - setHeaderRoute:
      name: canary-header-route
      match:
        - headerName: X-Canary
          headerValue:
            exact: "true"
  - pause: {}              # QA가 헤더로 카나리 테스트, 수동 승인 대기
  - setWeight: 10          # 헤더 라우트 유지한 채 일반 트래픽 10%도 카나리로
  - pause: {duration: 10m}
  - analysis:
      templates:
        - templateName: success-rate
      args:
        - name: canary-workload
          value: my-service-canary
  - setWeight: 50
  - pause: {duration: 10m}
  - setHeaderRoute:
      name: canary-header-route    # match 없이 같은 이름 → 해당 헤더 라우트 삭제
  - setWeight: 100

마지막에서 두 번째 스텝에서 match 없이 동일한 name을 사용하는 게 처음에는 직관적이지 않게 느껴질 수 있습니다. Argo Rollouts는 이를 "해당 이름의 라우트를 managedRoutes 목록에서 제거하라"는 명령으로 해석합니다. 결과적으로 VirtualService에서 헤더 조건 라우트가 사라지는 방식입니다.

bash
# QA 팀 — X-Canary 헤더를 붙여 카나리 파드로 직접 요청
curl -H "X-Canary: true" https://my-service.example.com/api/health
 
# 일반 사용자 — 헤더 없이 → stable 파드로 라우팅
curl https://my-service.example.com/api/health

pause: {} 스텝에서 멈춰 있을 때 QA 팀이 E2E 테스트를 마치면, kubectl argo rollouts promote my-service 명령으로 다음 단계로 넘어갈 수 있습니다. ArgoCD를 사용 중이라면 UI의 프로모션 버튼을 누르면 됩니다.

예시 4: 카나리 파드 P99 레이턴시와 업스트림 에러율 쿼리

성공률 외에도 레이턴시와 카나리가 의존하는 서비스에 미치는 영향을 함께 모니터링하면 훨씬 안전합니다. 운영을 이어가다 보니, 이 쿼리들을 추가하고 나서야 성공률만으로는 잡히지 않던 문제들이 보이기 시작했습니다.

promql
# 카나리 파드의 P99 응답 시간 (히스토그램 버킷 기반)
histogram_quantile(0.99,
  sum(rate(istio_request_duration_milliseconds_bucket{
    destination_workload="my-service-canary",
    reporter="destination"
  }[5m])) by (le)
)
promql
# 카나리 파드가 보낸 요청 중 5xx 발생율 (카나리→의존 서비스 영향 측정)
(
  sum(rate(istio_requests_total{
    source_workload="my-service-canary",
    response_code=~"5.*"
  }[2m]))
  /
  sum(rate(istio_requests_total{
    source_workload="my-service-canary"
  }[2m]))
) or on() vector(0)

두 번째 쿼리는 source_workload를 기준으로 합니다. 카나리 파드 자체가 받는 오류가 아니라, 카나리 파드가 다른 서비스를 호출할 때 발생하는 오류를 잡아냅니다. 새 버전이 DB나 외부 API를 다르게 호출하는 경우, 이 쿼리가 없으면 문제를 놓칠 수 있습니다.


장단점 분석

장점

항목 내용
레플리카 수 독립 트래픽 제어 카나리 파드 1개로도 정확히 5%, 10% 트래픽 분배 가능
파드 레벨 메트릭 정밀도 destination_workload 레이블로 카나리 파드에만 도달한 요청의 에러율·레이턴시 독립 측정
무중단 QA 테스트 setHeaderRoute로 실 서비스 영향 없이 카나리 검증 후 점진적 전환
자동 롤백 AnalysisTemplate 실패 조건 충족 시 Argo Rollouts가 자동으로 stable 복귀
GitOps 친화 모든 설정이 Kubernetes manifest로 선언되어 ArgoCD와 자연스럽게 통합

단점 및 주의사항

항목 내용 대응 방안
리소스 복잡도 VirtualService, DestinationRule, Rollout, AnalysisTemplate 등 다수 리소스 동시 관리 Helm chart 또는 Kustomize로 템플릿화해 일관성 유지
메트릭 카디널리티 Istio 레이블 조합 증가로 Prometheus 스토리지·쿼리 비용 증가 Sidecar 리소스로 메트릭 스코프 제한, 불필요한 레이블 exclude 설정
ArgoCD diff 충돌 Argo Rollouts가 VirtualService를 동적 수정하므로 ArgoCD가 drift로 감지 ignoreDifferences에 VirtualService의 spec.http 경로 추가 필수
서브셋 해시 의존성 DestinationRule의 rollouts-pod-template-hash는 롤아웃마다 변경 Argo Rollouts가 자동 관리하므로 수동 수정 금지 — 컨트롤러에 위임
DB 마이그레이션 결합 스키마 변경 수반 시 카나리/stable 파드가 동시에 동일 DB 공유 스키마 변경과 코드 배포를 별도 단계로 분리 (expand/contract 패턴)
mTLS 스크래핑 이슈 PeerAuthentication STRICT 모드에서 Prometheus 스크래핑이 차단될 수 있음 Prometheus에 Istio 인증서 마운트하거나 포트 15090(Envoy stats)을 직접 스크래핑

DB 마이그레이션 이슈는 처음 맞닥뜨렸을 때 꽤 당황스러웠습니다. 카나리 파드가 새 컬럼을 쓰는 순간 stable 파드가 알 수 없는 필드라며 오류를 내기 시작한다는 걸, 직접 겪고 나서야 expand/contract 패턴의 필요성을 실감했습니다. mTLS 스크래핑 이슈도 비슷한 맥락입니다 — PeerAuthentication을 STRICT로 바꿨더니 Prometheus 수집이 조용히 끊겨 버린 경험이 있었습니다.

ignoreDifferences: ArgoCD에서 특정 필드의 변경을 drift로 감지하지 않도록 설정하는 옵션입니다. Argo Rollouts가 VirtualService의 weight 값을 자동 수정하기 때문에, ArgoCD가 이를 "원하지 않는 변경"으로 감지해 계속 sync를 시도하는 현상을 방지합니다.

실무에서 가장 흔한 실수

  1. reporter 레이블 없이 PromQL 작성: reporter="destination" 없이 쿼리하면 source와 destination 쪽 메트릭이 중복 집계되어 성공률이 실제보다 낮게 나옵니다. AnalysisTemplate 쿼리에는 항상 이 조건을 포함하는 것을 권장합니다.

  2. canaryService와 stableService Service 오브젝트를 생성하지 않은 채 Rollout 배포: Rollout manifest에서 이 두 필드를 선언하면 동일한 이름의 Kubernetes Service가 실제로 존재해야 합니다. 없으면 Rollout 컨트롤러가 오류를 내면서 배포가 진행되지 않습니다. 예시 1에서 소개한 Service를 미리 적용해두는 것이 필요합니다.

  3. setHeaderRoute 제거 스텝 누락: 롤아웃 마지막 단계에서 헤더 라우트를 제거하지 않으면 이후에도 X-Canary: true 헤더가 있는 요청이 (이미 stable이 된) 서브셋으로만 계속 라우팅됩니다. 스텝 마지막에 match 없는 setHeaderRoute를 넣어 명시적으로 제거하는 것이 필요합니다.


마치며

여기까지 따라오셨다면 이제 파드 수에 종속되지 않는 정밀한 카나리 배포를 구성할 기반이 생겼습니다. VirtualService가 트래픽 비율을 결정하고, AnalysisTemplate이 카나리 파드 전용 메트릭으로 자동 판단을 내리며, setHeaderRoute가 그 사이에 QA 팀의 안전한 검증 창구를 열어줍니다. 구성 요소가 많아 처음엔 복잡해 보이지만, 각 역할이 명확히 분리되어 있어서 익숙해지면 배포 과정 전체가 훨씬 투명하게 보이기 시작합니다.

지금 바로 시작해볼 수 있는 3단계를 소개합니다.

  1. 로컬에서 전체 흐름 확인해보기 (Kubernetes 기본이 익숙하고 로컬 클러스터를 쉽게 띄울 수 있는 분): kind 또는 minikube에 Istio와 Argo Rollouts를 설치하고 예시 manifest를 순서대로 적용해보면, 컨트롤러가 VirtualService를 자동으로 수정하는 과정을 직접 확인할 수 있습니다. kubectl get vs my-service-vs -o yaml -w로 변화를 실시간으로 볼 수 있습니다.

  2. 기존 서비스에 AnalysisTemplate 먼저 연결해보기 (이미 Istio와 Prometheus를 운영 중인 분): 카나리 전략을 전환하기 전에, 현재 서비스에 대한 istio_requests_total 쿼리를 Prometheus에서 먼저 확인해보면 좋습니다. destination_workload 레이블이 어떻게 나오는지 확인한 뒤, AnalysisTemplate을 dryRun: true 모드로 연결하면 실제 롤백 없이 분석 로직을 검증할 수 있습니다.

  3. ArgoCD ignoreDifferences 설정 미리 추가하기 (ArgoCD로 GitOps를 운영 중인 분): 프로덕션 적용 전에 ArgoCD Application의 ignoreDifferences에 VirtualService spec.http 경로를 추가해두면, 첫 배포 때 ArgoCD가 sync를 반복하는 혼란을 미리 막을 수 있습니다.


참고 자료

  • Argo Rollouts — Istio 트래픽 관리 | 공식 문서
  • Argo Rollouts — Analysis 개요 | 공식 문서
  • Demo: An Automated Canary Deployment on Kubernetes with Argo Rollouts, Istio and Prometheus | CNCF Blog
  • Progressive Delivery with Service Mesh: Argo Rollouts + Istio | InfraCloud
  • Progressive Delivery with Argo Rollouts: Canary with Analysis | InfraCloud
  • Canary Deployment in Kubernetes using Argo Rollouts and Istio | Deckhouse Blog
  • Argo Rollouts를 이용한 카나리 Progressive Delivery | Tetrate 공식 문서
  • Prometheus 메트릭 쿼리 | Istio 공식 문서
  • Under the Hood: Argo Rollouts 1.8 with Kubernetes 1.33 and Prometheus 3.1 | earezki.com
  • How to Perform Canary with Argo Rollouts and Istio Service Mesh | OpsMx
#Istio#ArgoRollouts#카나리배포#Kubernetes#Prometheus#VirtualService#PromQL#GitOps#서비스메시#AnalysisTemplate
공유하기

목차

핵심 개념왜 레플리카 비율이 아닌 VirtualService 가중치인가전체 아키텍처 흐름파드 레벨 메트릭 격리의 원리실전 적용예시 1: stable/canary Service와 DestinationRule 준비예시 2: Rollout + AnalysisTemplate으로 자동 프로모션/롤백예시 3: setHeaderRoute로 QA 팀만 카나리 테스트예시 4: 카나리 파드 P99 레이턴시와 업스트림 에러율 쿼리장단점 분석장점단점 및 주의사항실무에서 가장 흔한 실수마치며참고 자료

추천 포스트

Vercel CDN 비용 폭탄 없애기: Flat Rate CDN과 FinOps로 예측 가능한 인프라 비용 만들기 (2026)
DevOps

Vercel CDN 비용 폭탄 없애기: Flat Rate CDN과 FinOps로 예측 가능한 인프라 비용 만들기 (2026)

Vercel을 쓰다 보면 한 번쯤 이런 경험을 하게 됩니다. 월말에 청구서를 열었는데, 예상보다 훨씬 큰 숫자가 적혀 있는 거죠. 심하면 DDoS 공격 한 방에 $23,000짜리 청구서를 받은 케이스도 실제로 있었고, HowdyGo 같은 팀은 이미지 최적화 항목 하나에서 매달 수백 달러...

2026년 05월 25일읽는 데 24분
Rancher Fleet으로 Kubernetes 멀티클러스터 운영하기 — 드리프트 없이 수십 개 클러스터를 Git 하나로 관리하는 패턴
DevOps

Rancher Fleet으로 Kubernetes 멀티클러스터 운영하기 — 드리프트 없이 수십 개 클러스터를 Git 하나로 관리하는 패턴

이 글은 Kubernetes를 실제로 운영해본 경험이 있는 DevOps/인프라 엔지니어를 대상으로 합니다. Helm, Kustomize, kubectl 정도는 익숙하다고 가정하고 씁니다. 클러스터가 처음 한두 개일 때는 로도 충분했습니다. 그러다 리전별로, 환경별로 나뉘기 시작하면...

2026년 05월 25일읽는 데 23분
Rancher Fleet과 Argo Rollouts를 조합해 500개 Kubernetes 클러스터에 카나리 배포하기 — Blast Radius를 파티션 단위로 제한하는 Progressive Delivery
DevOps

Rancher Fleet과 Argo Rollouts를 조합해 500개 Kubernetes 클러스터에 카나리 배포하기 — Blast Radius를 파티션 단위로 제한하는 Progressive Delivery

솔직히 말하면, 저도 처음 수십 개 클러스터를 동시에 관리해야 할 때 꽤 막막했습니다. 단일 클러스터에서 카나리 배포 하나 굴리는 건 어렵지 않은데, 클러스터가 수백 개로 늘어나는 순간 얘기가 달라집니다. "이 변경이 전체 프로덕션에 터지면 어떡하지?"라는 두려움이 배포를 망설이게 만들...

2026년 05월 26일읽는 데 24분
Kubernetes Argo Rollouts AnalysisTemplate과 Datadog으로 구현하는 번 레이트 SLO 기반 카나리 자동 롤백
DevOps

Kubernetes Argo Rollouts AnalysisTemplate과 Datadog으로 구현하는 번 레이트 SLO 기반 카나리 자동 롤백

새벽 3시에 PagerDuty 알림으로 눈을 뜬 적이 있나요? 저는 있습니다. 그것도 여러 번. 그때마다 로그를 뒤지다 보면 결국 같은 생각이 들더라고요. "카나리 배포를 하고 있었는데 왜 배포 시점에 이걸 못 잡았지?" 에러율이 1% 미만이었으니 시스템 입장에선 아무 문제가 없었던 거...

2026년 05월 25일읽는 데 24분
ArgoCD ApplicationSet rollingSync + Argo Rollouts로 멀티 클러스터 카나리 배포 구현하기
DevOps

ArgoCD ApplicationSet rollingSync + Argo Rollouts로 멀티 클러스터 카나리 배포 구현하기

수십 개 클러스터에 안전하게 점진적 롤아웃을 적용하는 2중 게이팅 전략 대상 독자: ArgoCD를 어느 정도 써본 분들. Kubernetes 기본 개념(Deployment, Service, Ingress)은 안다고 가정합니다. 솔직히 말하면, 처음 멀티 클러스터 배포를 맡았을...

2026년 05월 25일읽는 데 20분
2026년 GitOps 도구 비교: ArgoCD 3.3 vs FluxCD 2.8 + MCP Server, 어떤 팀에 무엇이 맞을까
DevOps

2026년 GitOps 도구 비교: ArgoCD 3.3 vs FluxCD 2.8 + MCP Server, 어떤 팀에 무엇이 맞을까

처음 ArgoCD를 도입했을 때 저도 솔직히 "일단 UI가 예쁘고 커뮤니티가 크니까"라는 이유로 선택했습니다. 6개월쯤 지나 멀티클러스터 환경이 복잡해지면서 그 선택을 되짚어보게 됐는데, 2026년 지금은 다시 꺼내볼 시점이 됐습니다. FluxCD가 드디어 공식 Web UI를 내놨고, ...

2026년 05월 24일읽는 데 21분