Post

VirtualService & DestinationRule — 트래픽 관리의 최소 단위

VS와 DR의 책임 분리로 카나리·정책 안정성을 높이는 Istio 트래픽 관리 원칙

VirtualService & DestinationRule — 트래픽 관리의 최소 단위

결론 요약

Istio 트래픽 관리의 핵심은 VirtualService와 DestinationRule을 분리해서 사고하는 것이다.
VirtualService는 “요청을 어디로 보낼지”만 결정한다.
DestinationRule은 “그곳에 도착한 이후 어떤 정책으로 처리할지”를 담당한다.
이 분리가 깨지면 카나리 배포는 즉시 불안정해진다.
버전 관리·정책 관리·트래픽 비율이 섞이는 순간 운영자는 통제력을 잃는다.
VS/DR은 문법이 아니라 역할 분업 계약이다.


한 문장 정의: VS / DR 역할 분리

  • VirtualService: 요청을 어떻게 라우팅할지 (match / route / weights)
  • DestinationRule: 라우팅된 이후 어떤 정책으로 보낼지 (subsets / trafficPolicy)

👉 VS는 ‘결정’, DR은 ‘처리’다.


VirtualService 핵심 패턴 3개

1) 조건 기반 라우팅 (match)

  • 헤더, URI, 메서드 기준 분기
  • “누가 보냈는가”를 기준으로 나눈다

2) 비율 기반 분산 (weights)

  • 카나리/점진 배포의 핵심
  • 10 → 30 → 50 → 100 같은 단계적 증가

3) 경로 중심 설계

  • VirtualService는 요청 진입점 기준으로 설계
  • 버전 개념을 여기서 섞지 않는다

DestinationRule 핵심 패턴 3개

1) 버전 그룹화 (subsets)

  • labels 기반으로 논리적 버전 그룹 정의
  • v1, v2는 이미지 태그가 아니라 운영 단위

2) 정책 캡슐화 (trafficPolicy)

  • loadBalancer
  • connectionPool
  • outlierDetection

3) 재사용 가능 설계

  • 하나의 DR은 여러 VS에서 재사용 가능
  • 정책은 중앙화, 라우팅은 분산화

예시 1: 나쁜 예 → 왜 위험한가

❌ 나쁜 예 (운영에서 자주 깨짐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
  hosts:
  - api
  http:
  - route:
    - destination:
        host: api
        subset: v1
      weight: 50
    - destination:
        host: api
        subset: v2
      weight: 50
1
2
3
4
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
spec:
  host: api

왜 위험한가

  • subset은 있는데 정의가 없다
  • DestinationRule에 subsets 누락
  • 배포 순서에 따라 트래픽 블랙홀 발생
  • “YAML은 적용됐는데 트래픽이 안 간다” 상황 발생

👉 VS는 DR의 존재를 전제로 한다.


예시 2: 개선 예 → 운영에서 왜 안정적인가

✅ 개선 예 (의도/버전/정책 분리)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
spec:
  host: api
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
  hosts:
  - api
  http:
  - route:
    - destination:
        host: api
        subset: v1
      weight: 90
    - destination:
        host: api
        subset: v2
      weight: 10

왜 안정적인가

  • 버전 그룹(subset)이 명확하다
  • 정책은 DR에 고정
  • VS는 비율만 조정
  • 배포/롤백 시 수정 범위 최소화

👉 운영 변경의 반경이 작다.


단계별 배포 사고 방식 (비율 설계)

  • 1단계: 90 / 10 — 기능 검증
  • 2단계: 70 / 30 — 성능/에러율 확인
  • 3단계: 50 / 50 — 실제 트래픽 반응
  • 4단계: 0 / 100 — 전환

중요한 점:

  • 비율은 의사결정 단계를 의미한다
  • 숫자는 작아도 되고 느려도 된다
  • “빨리 100”이 가장 위험하다

실무에서 자주 생기는 실수 5개

  1. subset 정의 없이 VirtualService부터 작성
  2. 여러 VirtualService 간 룰 충돌
  3. 우선순위(match 조건) 의도 미정의
  4. DR에 너무 많은 정책을 한 번에 추가
  5. 카나리 실패 시 롤백 경로 미정의

운영 전 검증 체크리스트 (10개)

  • DestinationRule이 먼저 존재하는가?
  • subset label이 실제 Pod와 일치하는가?
  • VirtualService의 match 조건이 명확한가?
  • weight 합이 100인가?
  • 하나의 VS가 하나의 진입 책임만 가지는가?
  • DR 정책이 과도하지 않은가?
  • 재시도/타임아웃과 비율이 함께 고려됐는가?
  • 롤백 시 수정 파일이 최소화되는가?
  • 배포 순서가 문서화되어 있는가?
  • 관측(Kiali/Jaeger)에서 의도가 보이는가?

흔한 오해 3개 + 교정

  1. 오해: VS와 DR은 항상 1:1이다

    교정: DR은 여러 VS에서 재사용된다.

  2. 오해: subset은 단순 버전 태그다

    교정: 운영 단위이자 정책 단위다.

  3. 오해: 카나리는 비율만 바꾸면 된다

    교정: 관측·롤백 경로가 먼저다.


재학습 체크리스트

  • VS와 DR의 책임 경계를 설명할 수 있는가?
  • subset을 “버전”이 아니라 “그룹”으로 인식하는가?
  • 정책 변경과 라우팅 변경을 분리하는가?
  • YAML 수정 시 영향 반경을 예측하는가?
  • 카나리 실패 시 즉시 되돌릴 수 있는가?
  • VS 충돌 가능성을 사전에 점검하는가?
  • 배포 단계가 숫자가 아닌 판단으로 정의되는가?
  • 트래픽 변경이 로그/트레이스로 확인되는가?

This post is licensed under CC BY 4.0 by the author.