Istio의 트래픽 관리(Traffic Management) API는 서비스 간 트래픽 흐름을 세밀하게 제어할 수 있도록 설계되었다. 이 API를 활용하면 트래픽 라우팅, 로드 밸런싱, 재시도, 페일오버, 트래픽 미러링 등 다양한 정책을 설정할 수 있다.
Istio에서 트래픽을 제어하는 주요 API 리소스는 다음과 같다.
| 리소스 | 주요 기능 |
|---|---|
| VirtualService | 트래픽 라우팅 (A/B 테스트, Canary 배포, 재시도, 페일오버 등) |
| DestinationRule | 서비스 대상 설정 (로드 밸런싱, 서킷 브레이커, mTLS 등) |
| ServiceEntry | 외부 서비스(API, DB 등)를 Istio 네트워크에 포함 |
| Gateway | 외부 트래픽 관리 (Ingress, Egress) |
| Sidecar | 특정 서비스의 트래픽 필터링 및 네트워크 최적화 |
이 후부터 트래픽 관리(Traffic Management) API에 대한 상세 설명이다.
VirtualService는 Istio에서 트래픽을 제어하는 리소스로, 서비스 메시 내에서 트래픽 라우팅 규칙을 정의하는 역할을 한다. 이를 통해 요청을 특정 버전의 서비스로 라우팅하거나, A/B 테스트, Canary 배포 등을 손쉽게 구현할 수 있다.
| 필드 | 설명 |
|---|---|
| hosts | 트래픽을 수신할 서비스의 호스트 (예: reviews.default.svc.cluster.local) |
| gateways | 외부 트래픽을 허용할 Istio Gateway (예: my-gateway) |
| http / tcp / tls | HTTP, TCP, TLS 기반 트래픽을 라우팅하는 규칙 |
| match | 특정 요청 조건 (예: headers, URI, method) |
| route | 트래픽을 전달할 대상 서비스와 비율 설정 |
| timeout | 요청의 최대 응답 대기 시간 |
| retries | 실패한 요청의 재시도 정책 |
| fault | 장애 주입 (latency 추가, 오류 반환) |
| mirror | 요청을 복사하여 다른 서비스로 전달 (미러링) |
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews.default.svc.cluster.local
http:
- route:
- destination:
host: reviews.default.svc.cluster.local
subset: v1
weight: 70
- destination:
host: reviews.default.svc.cluster.local
subset: v2
weight: 30
이 설정은 reviews 서비스의 v1 버전에 80%의 트래픽을, v2 버전에 20%의 트래픽을 보내도록 한다.
아래 예제는 새로운 v2 버전을 Canary 방식으로 배포하는 설정이다.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: canary-deployment
spec:
hosts:
- my-service.default.svc.cluster.local
http:
- route:
- destination:
host: my-service.default.svc.cluster.local
subset: v1
weight: 90
- destination:
host: my-service.default.svc.cluster.local
subset: v2
weight: 10
이 설정에서는 v1 버전에 90%, v2 버전에 10%의 트래픽을 보냄으로써 Canary 배포를 수행한다.
아래 예제는 user-group이라는 요청 헤더 값을 기반으로 트래픽을 v2 버전으로 라우팅하는 설정이다.
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: header-routing
spec:
hosts:
- my-app.default.svc.cluster.local
http:
- match:
- headers:
user-group:
exact: "test-users"
route:
- destination:
host: my-app.default.svc.cluster.local
subset: v2
- route:
- destination:
host: my-app.default.svc.cluster.local
subset: v1
이 설정에서는 user-group: test-users 헤더를 포함한 요청은 v2로 보내고, 나머지는 v1으로 보낸다.
Kiali에서는 VirtualService 설정을 기반으로 서비스 간 트래픽 흐름을 그래프로 시각화할 수 있다.
특정 VirtualService가 적용된 트래픽 패턴을 확인하고, A/B 테스트, Canary 배포 등 라우팅 전략을 쉽게 분석할 수 있다.
Kiali UI를 통해 VirtualService의 트래픽 비율, 재시도 설정, 장애 주입 상태 등을 직관적으로 확인 가능하다.
DestinationRule은 Istio에서 서비스 간 트래픽을 세분화하고, 부하 분산, 연결 정책, 보안 설정을 관리하는 리소스다. VirtualService와 함께 사용되며, 트래픽이 특정 서비스로 도착한 후 어떤 방식으로 처리될지 결정하는 역할을 한다.
| 필드 | 설명 |
|---|---|
| host | 트래픽을 적용할 대상 서비스 (예: reviews.default.svc.cluster.local) |
| subsets | 특정 버전(예: v1, v2) 또는 특정 레이블을 가진 서비스 그룹 |
| trafficPolicy | 부하 분산, 연결 풀, TLS, 장애 감지 등의 정책 설정 |
| loadBalancer | 부하 분산 방식 (Round Robin, Least Request, Random 등) |
| connectionPool | 최대 연결 수, 동시 요청 수 등의 연결 제한 설정 |
| outlierDetection | 장애 발생 시 문제가 있는 인스턴스를 자동으로 제외하는 기능 |
| tls | 서비스 간 TLS 통신 설정 (DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL) |
아래 예제는 reviews 서비스에 대해 v1과 v2 버전을 정의하는 설정이다.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
이 설정을 사용하면 VirtualService에서 v1, v2 서브셋을 기준으로 트래픽을 분배할 수 있다.
아래 예제는 reviews 서비스에 대해 Least Request 방식의 부하 분산 정책을 적용하는 설정이다.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-loadbalancer
spec:
host: reviews.default.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_REQUEST
Least Request: 가장 적은 요청을 처리 중인 인스턴스에 트래픽을 분배하는 방식.
아래 예제는 오류가 많은 인스턴스를 자동으로 제거하는 Outlier Detection을 설정하는 방법이다.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-outlier
spec:
host: reviews.default.svc.cluster.local
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 3
interval: 10s
baseEjectionTime: 30s
위 설정은 10초 동안 3번 이상의 5xx 오류가 발생하는 인스턴스를 30초 동안 제외한다.
아래 예제는 reviews 서비스 간 mTLS (Mutual TLS) 암호화를 활성화하는 설정이다.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-tls
spec:
host: reviews.default.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
ISTIO_MUTUAL은 Istio에서 자동으로 TLS 인증서를 관리하도록 설정하는 방식이다.
VirtualService는 트래픽이 어떤 서비스로 전송될지 결정
DestinationRule은 트래픽이 서비스에 도착한 후 어떻게 처리될지 결정
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews.default.svc.cluster.local
http:
- route:
- destination:
host: reviews.default.svc.cluster.local
subset: v1
weight: 80
- destination:
host: reviews.default.svc.cluster.local
subset: v2
weight: 20
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
VirtualService는 80% 트래픽을 v1, 20% 트래픽을 v2로 보낸다. DestinationRule은 v1, v2 서브셋을 정의하여 VirtualService에서 이를 참조 가능하도록 한다.
Gateways API는 Kubernetes 환경에서 네트워크 트래픽을 제어하고 관리하는 새로운 표준 API이다. 기존 Istio Gateway 또는 Ingress 리소스를 대체하거나 확장하는 역할을 하며, 더 유연한 트래픽 라우팅과 멀티 클러스터 지원을 제공한다.
Gateways API는 여러 개의 CRD (Custom Resource Definition) 로 구성되어 있다.
| 리소스 | 역할 |
|---|---|
| GatewayClass | Gateway의 동작 방식 및 컨트롤러를 정의 |
| Gateway | 클러스터 외부에서 내부 서비스로 트래픽을 유입시키는 역할 |
| HTTPRoute | HTTP 요청을 특정 서비스로 라우팅 (호스트 기반, 경로 기반 등) |
| TCPRoute | TCP 트래픽을 특정 백엔드 서비스로 라우팅 |
| TLSRoute | TLS 트래픽을 특정 백엔드 서비스로 전달 |
| GRPCRoute | gRPC 요청을 특정 백엔드 서비스로 라우팅 |
| ReferenceGrant | 다른 네임스페이스의 리소스를 참조할 수 있도록 허용 |
기존 Ingress API는 HTTP 기반 요청만 처리할 수 있지만, Gateways API는 TCP, UDP, gRPC까지 지원하여 더욱 유연한 트래픽 제어가 가능하다.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio-gateway
spec:
controllerName: istio.io/gateway-controller
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: istio-gateway
listeners:
- protocol: HTTP
port: 80
name: http
allowedRoutes:
namespaces:
from: All
gatewayClassName: 사용할 GatewayClass 지정 (예: istio-gateway)
listeners: 특정 프로토콜(HTTP, TCP, TLS 등)에 대한 설정
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- "example.com"
rules:
- matches:
- path:
type: PathPrefix
value: "/api"
backendRefs:
- name: my-service
port: 8080
parentRefs: 어느 Gateway와 연결할지 지정
hostnames: 특정 도메인(예: example.com)에서만 요청을 허용
rules: /api 경로로 들어오는 요청을 my-service:8080으로 전달
apiVersion: gateway.networking.k8s.io/v1
kind: TCPRoute
metadata:
name: my-tcp-route
spec:
parentRefs:
- name: my-gateway
rules:
- backendRefs:
- name: my-tcp-service
port: 3306
apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: my-tls-route
spec:
parentRefs:
- name: my-gateway
rules:
- backendRefs:
- name: my-tls-service
port: 443
| 기능 | Kubernetes Ingress | Istio Gateway | Gateway API |
|---|---|---|---|
| L4 (TCP) 트래픽 제어 | ❌ 불가능 | ✅ 가능 | ✅ 가능 |
| L7 (HTTP) 트래픽 제어 | ✅ 가능 | ✅ 가능 | ✅ 가능 |
| mTLS 지원 | ❌ 불가능 | ✅ 가능 | ✅ 가능 |
| 다양한 리스너 지원 | ❌ 제한적 (HTTP/HTTPS) | ✅ 가능 (TCP, HTTP, HTTPS, gRPC) | ✅ 가능 (더 유연함) |
| VirtualService 연동 가능 | ❌ 불가능 | ✅ 가능 | ✅ 가능 |
| 멀티클러스터 지원 | ❌ 불가능 | ✅ 가능 | ✅ 가능 |
| 표준화된 API | ❌ Kubernetes 전용 | ❌ Istio 전용 | ✅ Kubernetes 공식 API |
Sidecars API는 Istio에서 특정 네임스페이스 또는 서비스의 프록시(Sidecar Envoy)를 커스터마이징하는 리소스다.
기본적으로 Istio는 모든 Pod에 동일한 Sidecar 프록시 설정을 적용하지만, Sidecar 리소스를 사용하면 특정 서비스에 맞는 네트워크 정책을 개별적으로 설정할 수 있다.
| 필드 | 설명 |
|---|---|
| workloadSelector | 특정 Pod(워크로드)에만 Sidecar 설정을 적용 (예: app: my-app) |
| ingress | 다른 서비스가 이 Sidecar를 통해 접근할 수 있는 트래픽 규칙 설정 |
| egress | 이 Sidecar에서 외부로 나가는 트래픽을 제한 또는 허용 |
| outboundTrafficPolicy | 외부 트래픽(클러스터 외부 접속) 정책 (ALLOW_ANY, REGISTRY_ONLY) |
| listeners | Envoy Proxy가 트래픽을 수신하는 리스너 설정 |
기본적으로 Istio는 모든 네임스페이스에서 트래픽을 감시하지만, 아래 설정을 적용하면 특정 네임스페이스(my-namespace)에만 Sidecar를 삽입할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: custom-sidecar
namespace: my-namespace
spec:
egress:
- hosts:
- "./*" # 같은 네임스페이스의 서비스만 허용
- "istio-system/*" # Istio 컨트롤 플레인과의 통신 허용
아래 설정을 적용하면 특정 라벨이 있는 Pod (app: my-app)에만 Sidecar 설정을 적용할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: app-specific-sidecar
namespace: my-namespace
spec:
workloadSelector:
labels:
app: my-app # 이 라벨이 붙은 Pod에만 Sidecar 적용
egress:
- hosts:
- "./*" # 같은 네임스페이스 내 트래픽 허용
- "external-namespace/*" # 특정 네임스페이스의 서비스만 허용
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: restricted-egress
namespace: my-namespace
spec:
outboundTrafficPolicy:
mode: REGISTRY_ONLY # 외부 트래픽 차단 (클러스터 내부 서비스만 허용)
| 기능 | 기본 Istio Sidecar | Sidecar API 사용 시 |
|---|---|---|
| 모든 네임스페이스 감시 | ✅ 예 | ❌ 아니요 (제한 가능) |
| 특정 네임스페이스만 감시 | ❌ 불가능 | ✅ 가능 |
| 특정 서비스 트래픽만 허용 | ❌ 불가능 | ✅ 가능 |
| 외부 트래픽 제한 | ❌ 기본적으로 허용됨 | ✅ 차단 가능 (REGISTRY_ONLY) |
| 리소스 절감 | ❌ 불필요한 트래픽 감시 | ✅ 최소한의 트래픽 감시 가능 |
💡 핵심 차이점:
기본 Istio는 모든 Pod의 네트워크 트래픽을 감시하지만, Sidecar API를 사용하면 필요한 서비스만 감시하여 리소스 절감 가능
외부 트래픽을 자동으로 차단할 수도 있고, 특정 서비스에 대해서만 허용 가능
ServiceEntry API는 Istio에서 클러스터 외부의 서비스(외부 API, DB, SaaS 등)를 서비스 메시에 등록하는 역할을 한다.
기본적으로 Kubernetes 내부 서비스만 Istio의 트래픽 관리 대상이지만, ServiceEntry 리소스를 사용하면 외부 서비스를 마치 클러스터 내부 서비스처럼 통합 관리할 수 있다.
| 필드 | 설명 |
|---|---|
| hosts | 외부 서비스의 호스트 이름 (예: api.example.com) |
| addresses | IP 기반으로 서비스 접근을 제어할 경우 사용 |
| ports | 통신할 프로토콜과 포트 정의 (예: HTTP 80, HTTPS 443) |
| location | MESH_EXTERNAL (외부 서비스), MESH_INTERNAL (내부 서비스) |
| resolution | DNS를 통한 서비스 검색 여부 (DNS, STATIC, NONE) |
| workloadSelector | 특정 워크로드에만 적용할 경우 사용 |
아래 설정을 적용하면 api.example.com을 클러스터 내부 서비스처럼 등록할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-api
spec:
hosts:
- api.example.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
hosts: api.example.com을 외부 서비스로 등록
location: MESH_EXTERNAL: 클러스터 외부 서비스임을 명시
ports: HTTP(80) 포트 사용
resolution: DNS: DNS를 통해 서비스 검색
아래 설정을 적용하면 MySQL 데이터베이스(mysql.external.com:3306)를 서비스 메시에 등록할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-db
spec:
hosts:
- mysql.external.com # 외부 DB 호스트
location: MESH_EXTERNAL
ports:
- number: 3306
name: mysql
protocol: TCP
resolution: DNS
아래 설정을 적용하면 라벨이 app: web인 Pod만 외부 API(api.external.com)에 접근 가능하도록 제한할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: restricted-api
spec:
hosts:
- api.external.com
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
workloadSelector:
labels:
app: web # 웹 애플리케이션만 접근 가능
ServiceEntry를 VirtualService와 결합하면 트래픽 라우팅, 재시도, 타임아웃 등 고급 정책 적용 가능
아래 예제는 api.example.com의 트래픽을 우선적으로 내부 캐시 서버로 보내고, 실패하면 외부 API 호출하도록 설정한다.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: api-routing
spec:
hosts:
- api.example.com
gateways:
- mesh
http:
- route:
- destination:
host: cache-service # 내부 캐시 서버
port:
number: 8080
- destination:
host: api.example.com # 외부 API
port:
number: 80
retries:
attempts: 3 # 3번 재시도
perTryTimeout: 2s # 재시도 간격 2초
| 기능 | Kubernetes Service | Istio ServiceEntry |
|---|---|---|
| 외부 서비스 등록 가능 여부 | ❌ 불가능 | ✅ 가능 |
| mTLS 적용 가능 여부 | ❌ 불가능 | ✅ 가능 |
| 트래픽 제어 (VirtualService 연동) | ❌ 불가능 | ✅ 가능 |
| 로드 밸런싱 적용 가능 여부 | ❌ 불가능 | ✅ 가능 (DestinationRule 필요) |
Kubernetes의 Service는 클러스터 내부 서비스만 관리 가능, 하지만 ServiceEntry는 외부 서비스도 Istio 네트워크에 추가 가능
외부 서비스에 mTLS, 트래픽 제한, 로드 밸런싱 등을 적용할 수 있음