
새로운 기능이 추가된 v2 버전을 사용자에게 배포해야 하는 상황을 상상해 보세요. 🧐 만약 모든 트래픽을 한 번에 v2로 보낸다면? 생각지도 못한 버그가 발생했을 때 모든 사용자가 영향을 받는 끔찍한 상황이 발생할 수 있습니다. 😱
이런 문제를 해결하기 위해 우리는 카나리 배포(Canary Deployment), 블루/그린 배포(Blue/Green Deployment) 같은 전략을 사용합니다. 특정 사용자 그룹이나 일부 트래픽만 신규 버전으로 보내서 안정성을 검증하는 것이죠.
Kubernetes 환경에서 서비스 메시(Service Mesh)의 대표 주자인 Istio를 사용하면 이 과정을 아주 우아하고 강력하게 제어할 수 있습니다. 오늘은 Istio가 어떻게 특정 버전의 서비스로 트래픽을 보내는지, 그 핵심 개념을 파헤쳐 보겠습니다!
🤔 문제의 시작: Kubernetes Service의 한계
먼저 Kubernetes의 기본 동작을 이해해야 합니다. 아래와 같이 my-service라는 이름의 Service가 있다고 가정해 봅시다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app # 'app: my-app' 레이블을 가진 모든 파드를 찾습니다.
ports:
- protocol: TCP
port: 80
targetPort: 8080
이 Service는 app: my-app 레이블을 가진 모든 파드(Pod)를 자신의 엔드포인트로 삼습니다. 만약 v1 버전의 파드 3개와 v2 버전의 파드 1개가 모두 app: my-app 레이블을 가지고 있다면, my-service로 들어온 요청은 이 4개의 파드에 기본적으로 라운드 로빈(Round Robin) 방식으로 분산됩니다.
- my-app Pods
- pod-v1-a (labels: app: my-app, version: v1)
- pod-v1-b (labels: app: my-app, version: v1)
- pod-v1-c (labels: app: my-app, version: v1)
- pod-v2-a (labels: app: my-app, version: v2) 🆕
이 상황에서는 "나는 v1으로만 요청을 보내고 싶어" 또는 "전체 트래픽의 10%만 v2로 보내고 싶어"와 같은 세밀한 제어가 불가능합니다. 😥
✨ Istio의 해결사 듀오: VirtualService와 DestinationRule
이러한 한계를 극복하기 위해 Istio는 VirtualService와 DestinationRule이라는 두 가지 강력한 CRD(Custom Resource Definition)를 제공합니다.
- VirtualService (가상 서비스) 👮
- 역할: "어디로 갈까?" 트래픽 라우팅 규칙을 정의합니다.
- 설명: my-service로 들어온 트래픽을 어떤 조건(헤더, URI, 소스 등)에 따라 어디로 보낼지 결정하는 교통 경찰과 같습니다. 예를 들어, "URI가 /api/v2로 시작하면 v2 서비스로 보내" 또는 "90%의 트래픽은 v1으로, 10%는 v2로 보내" 같은 규칙을 정의합니다.
- DestinationRule (목적지 규칙) 📖
- 역할: "도착할 수 있는 곳은 어디인가?" 실제 목적지(엔드포인트 그룹)를 정의합니다.
- 설명: VirtualService가 길을 알려주기 전에, 목적지들이 어떤 특성을 가지고 있는지 정의해놓은 주소록과 같습니다. 여기서 바로 오늘의 주인공인 서브셋(Subsets) 이 등장합니다.
이 둘은 항상 함께 움직여야 합니다. VirtualService가 아무리 "v2로 가!"라고 외쳐도, DestinationRule에 v2라는 목적지 그룹이 정의되어 있지 않으면 소용이 없습니다.
🎯 핵심 개념: DestinationRule의 서브셋(Subsets)
DestinationRule의 핵심 기능은 바로 서브셋(Subsets) 을 정의하는 것입니다. 서브셋은 특정 레이블(label)을 기준으로 서비스의 파드들을 논리적인 그룹으로 나누는 것을 의미합니다.
말보다 코드로 보는 것이 훨씬 이해하기 쉽습니다. my-service에 대한 DestinationRule을 정의해 봅시다.
DestinationRule Raw Data (YAML)
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-service-dr
spec:
# 이 규칙이 적용될 서비스의 호스트 이름
host: my-service.default.svc.cluster.local
# 파드들을 논리적인 그룹으로 나눕니다.
subsets:
- name: v1 # 이 그룹의 이름은 'v1' 입니다.
labels:
version: v1 # 'version: v1' 레이블을 가진 파드들만 이 그룹에 속합니다.
- name: v2 # 이 그룹의 이름은 'v2' 입니다.
labels:
version: v2 # 'version: v2' 레이블을 가진 파드들만 이 그룹에 속합니다.
위 YAML 파일이 하는 일은 간단합니다.
- host 필드를 통해 my-service에 이 규칙을 적용하겠다고 선언합니다.
- subsets 필드 안에 두 개의 그룹을 정의합니다.
- v1 서브셋: version: v1 레이블을 가진 파드들의 모임 🏠
- v2 서브셋: version: v2 레이블을 가진 파드들의 모임 🏡
이제 Istio는 my-service가 단순히 파드 4개의 묶음이 아니라, v1과 v2라는 이름표를 가진 두 개의 뚜렷한 그룹으로 구성되어 있음을 인지합니다.
🚀 서브셋 활용하기: VirtualService와의 연계
이제 DestinationRule로 주소록을 만들었으니, VirtualService라는 교통 경찰이 이 주소록을 보고 길을 안내할 차례입니다.
90% 트래픽은 v1으로, 10%는 v2로 보내는 카나리 배포 예제
VirtualService Raw Data (YAML)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-service-vs
spec:
hosts:
- my-service.default.svc.cluster.local # my-service로 들어오는 모든 트래픽에 대해
http:
- route:
- destination:
host: my-service.default.svc.cluster.local
subset: v1 # 'DestinationRule'에 정의된 'v1' 서브셋으로 보내라
weight: 90 # 가중치는 90%
- destination:
host: my-service.default.svc.cluster.local
subset: v2 # 'DestinationRule'에 정의된 'v2' 서브셋으로 보내라
weight: 10 # 가중치는 10%
VirtualService의 http.route 부분을 보세요. destination에 subset이라는 필드가 있습니다. 여기에 DestinationRule에서 정의했던 서브셋의 name(v1, v2)을 정확히 기재하면, Istio는 해당 레이블을 가진 파드 그룹으로만 트래픽을 전달합니다.
이렇게 두 리소스를 조합하면, 코드 한 줄 바꾸지 않고 YAML 파일 수정만으로 서비스의 트래픽 흐름을 완벽하게 제어할 수 있게 됩니다. ✨
❌ 이건 왜 정답이 아닐까?
Istio에는 다양한 리소스가 있어서 헷갈릴 수 있습니다. 다른 개념들과 Subsets의 차이를 명확히 알아봅시다.
- ServiceEntry: 서비스 메시에 포함되지 않은 외부 서비스를 Istio가 인식할 수 있도록 등록하는 데 사용됩니다. 예를 들어, 외부 클라우드 데이터베이스 API를 메시 내부 서비스처럼 호출하고 싶을 때 사용합니다. 메시 내부 서비스의 버전을 나누는 것과는 전혀 다른 목적을 가집니다.
- Gateway: 메시의 가장자리(edge)에서 들어오고 나가는 트래픽(Ingress/Egress)을 관리합니다. 즉, 클러스터 외부의 요청이 어떻게 내부로 들어올지를 정의하는 관문 역할을 합니다. 일단 들어온 트래픽을 내부 서비스 버전별로 라우팅하는 Subsets과는 역할의 위치가 다릅니다.
- PodSelector: Kubernetes의 기본 개념으로, 특정 레이블을 가진 파드들을 선택하는 데 사용됩니다. DestinationRule의 subsets가 내부적으로 레이블 셀렉터를 사용하긴 하지만, Istio DestinationRule 내에서 특정 버전의 파드 그룹을 논리적으로 명명하고 정의하는 Istio의 공식적인 개념은 서브셋(Subsets)입니다.
💡 정리하며
서비스 장애 없이 안전하게 신규 버전을 배포하고 싶다면, Istio의 DestinationRule과 VirtualService를 이해하는 것은 필수입니다.
- DestinationRule은 subsets를 통해 서비스의 파드들을 version: v1, version: v2와 같이 의미 있는 그룹으로 정의합니다. (주소록 만들기 📖)
- VirtualService는 이렇게 정의된 subsets을 목적지로 사용하여, 트래픽을 가중치에 따라 분배하거나 특정 조건에 따라 라우팅하는 규칙을 설정합니다. (교통정리하기 👮)
이 두 가지의 완벽한 조합을 통해, 여러분은 이제 어떤 복잡한 배포 시나리오도 자신 있게 처리할 수 있는 강력한 무기를 얻게 되었습니다!
'클라우드 > Istio' 카테고리의 다른 글
| 내 Istio가 점점 느려지는 충격적인 이유 (feat. Sidecar 리소스) (0) | 2025.11.28 |
|---|---|
| 내 서비스만 암호화? 🔒 Istio mTLS, 무작정 STRICT 모드 쓰면 큰일나는 이유 (0) | 2025.11.28 |
| 내 서비스는 누가 지킬까? Istio의 깐깐한 신원 조회 방법 2가지 🕵️♂️ (0) | 2025.11.28 |
| Istio 프로덕션 환경, '이것'만은 꼭 확인하세요: 설치 프로필의 비밀 🤫 (0) | 2025.11.28 |
| Istio, 너 혹시 텔레파시 쓰니? Envoy와 Istiod의 비밀 통신 방법 🤫 (0) | 2025.11.28 |