VirtualService & DestinationRule — 트래픽 관리의 최소 단위
VS와 DR의 책임 분리로 카나리·정책 안정성을 높이는 Istio 트래픽 관리 원칙
Posted Updated
By okorion
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개
- subset 정의 없이 VirtualService부터 작성
- 여러 VirtualService 간 룰 충돌
- 우선순위(match 조건) 의도 미정의
- DR에 너무 많은 정책을 한 번에 추가
- 카나리 실패 시 롤백 경로 미정의
운영 전 검증 체크리스트 (10개)
- DestinationRule이 먼저 존재하는가?
- subset label이 실제 Pod와 일치하는가?
- VirtualService의 match 조건이 명확한가?
- weight 합이 100인가?
- 하나의 VS가 하나의 진입 책임만 가지는가?
- DR 정책이 과도하지 않은가?
- 재시도/타임아웃과 비율이 함께 고려됐는가?
- 롤백 시 수정 파일이 최소화되는가?
- 배포 순서가 문서화되어 있는가?
- 관측(Kiali/Jaeger)에서 의도가 보이는가?
흔한 오해 3개 + 교정
오해: VS와 DR은 항상 1:1이다
교정: DR은 여러 VS에서 재사용된다.
오해: subset은 단순 버전 태그다
교정: 운영 단위이자 정책 단위다.
오해: 카나리는 비율만 바꾸면 된다
교정: 관측·롤백 경로가 먼저다.
재학습 체크리스트
- VS와 DR의 책임 경계를 설명할 수 있는가?
- subset을 “버전”이 아니라 “그룹”으로 인식하는가?
- 정책 변경과 라우팅 변경을 분리하는가?
- YAML 수정 시 영향 반경을 예측하는가?
- 카나리 실패 시 즉시 되돌릴 수 있는가?
- VS 충돌 가능성을 사전에 점검하는가?
- 배포 단계가 숫자가 아닌 판단으로 정의되는가?
- 트래픽 변경이 로그/트레이스로 확인되는가?
This post is licensed under CC BY 4.0 by the author.
