https://dev-ryuon.tistory.com/122
Istio 톺아보기 #1 - 개요
서비스 메쉬란?서비스 메쉬는 MSA(마이크로 서비스 아키텍처)환경에서 서비스 간의 통신을 제어하고 관리할 수 있는 인프라 계층을 의미한다. 즉, 서비스 내의 애플리케이션 혹은 비즈니스 로직
dev-ryuon.tistory.com
- Istio나 서비스 메쉬가 처음이신 분은 이전 게시글을 읽고오시면 이해하기 쉬울거에요!
개요

- Istio는 트래픽 라우팅 규칙을 통해 서비스 간의 트래픽 흐름을 쉽게 제어할 수 있다. 제어할 수 있는 기능으로는 아래와 같은 것들이 있다.
- Circuit Breaker : 서킷브레이커(회로 차단기)는 서비스 장애 전파와 과부하를 방지하기 위한 패턴이다. DestinationRule CRD에서 설정할 수 있으며, 특정 서비스의 오류율이 임계치를 초과하면 해당 서비스로 흐르는 트래픽을 일시적으로 차단할 수 있다.
- Timeout : 서비스간 요청이 일정 시간 내에 응답하지 않으면 실패로 간주하고 중단하는 기능이다. VirtualService CRD에서 설정할 수 있다.
- Retries : 재시도 요청을 통해 실패한 요청에 대해 다시 시도할 수 있는 기능을 제공한다. VirtualService, DestinationRule CRD를 통해 제공하며, 서비스에 대한 신뢰성을 높힐 수 있다.
- A/B testing : 단일 애플리케이션에 대해 두 개 이상의 버전을 동시에 배포하여 트래픽을 분산시키고 사용자의 반응을 비교하는 실험적 배포 방식이다. VirtualService에 대해 서비스의 버전별로 트래픽 비율을 분배하여 테스트할 수 있다.
- Canary : 새로운 버전을 소수의 사용자에게 실험적으로 배포하고, 점진적으로 문제가 없을 경우 트래픽의 비중을 높히는 방식의 배포방식이다.
- 메쉬 내의 트래픽의 목적지를 판단하려면, Istio는 엔드포인트를 알아야하고, 어떤 서비스로 트래픽이 전달되는지 규칙을 알아야 하기 때문에 Service Registry에 등록하게 된다. (메쉬 네트워크의 관리 대상이 되려면 Service Registry에 등록되어야 한다.)
- istioctl install --set meshConfig.outboundTrafficPolicy.mode=[ALLOW_ANY,REGISTRY_ONLY] 옵션을 통해 Service Registry에 등록된 서비스만 메쉬 내트워크 내의 통신을 제한할지 아니면 모든 외부 트래픽을 허용할지 정할 수 있다.
Istio에서 제공되는 네트워크 관련 CRD
DestinationRule & VirtualService
- DestinationRule과 VirtualService는 Istio에서 트래픽 라우팅을 하는데 있어서 핵심 기능이다.
- VirtualService에서 라우팅 규칙이 평가된 뒤에, DestinationRule에서 트래픽을 실제 목적지까지 전달하는 역할을 수행한다.
- 우선 DestinationRule에서 Pod의 레이블을 기반으로 subnet을 정의한다.
- VirtualService에서 주어진 호스트(Kubernetes Service의 FQDN)와 DestinationRule을 통해 생성한 subnet을 통해 라우팅을 수행한다. (물론 VirtualService에서 subnet을 활용하지 않을 수도 있다.)

- 먼저 위 예시를 보면 아래와 같이 이해할 수 있다.
- DestinationRule CRD에서 version: v1 레이블을 가진 Pod들을 v1 subnet으로 정의한다.
- 이어서 version: v2 레이블을 가진 Pod들도 v2 subnet으로 정의한다.
- VirtualService에서 reviews 라는 도메인(hosts)으로 인그레스 트래픽이 들어왔을 때, 아래와 같은 목적지(destination)으로 트래픽을 전달한다.
- reviews 라는 FQDN을 가진 Kubernetes Service로 트래픽을 전달한다.
- 그 중에서, DestinationRule에서 정의한 v1 subnet들에만 부분적으로 전달한다. 즉, reviews Service의 Endpoint 대상인 Pod들 중에서 version: v1 레이블을 가진 Pod들만 필터링한다.
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destination-rule
spec:
host: reviews # reviews.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
- DestinationRule에 대해 조금 더 연습해보자. 위 DestinationRule에서는 reviews (reviews.<namespace>.svc.cluster.local) 라는 FQDN을 가지는 Service 객체에 대하여 총 3개의 subnet을 정의했다. (label을 통해 버전별로(v1 ~ v3) subnet을 분리했다.)
- 하지만, v2 subent은 RR 방식의 로드밸런싱 알고리즘을 적용했다. 즉, VirtualService를 통해 v2 subnet으로 트래픽이 전달될 경우, 해당 트래픽이 version: v2 레이블을 가진 Pod들에 대해서 라운드 로빈방식으로 전달할 수 있다.
- 여기서 문서를 보지 않아도 알 수 있는 점은, RR 방식 이외에 로드밸런싱 알고리즘을 지원할 것이고, L7 기능을 제공한다는 점이다. (https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings-SimpleLB)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v3
- 위 VirtualService는 외부로부터 reviews 라는 도메인으로 요청이 들어올 때, 라우팅 규칙을 정의했다.
- hosts : VirtualService에서 트래픽을 받을 수 있는 호스트들의 나열이다. IP 주소, DNS 이름이 될 수 있으며 와일드카드(*) 접두어를 통해 매칭되는 다수의 서비스들도 정의할 수 있다.
- http : HTTP/1.1, HTTP2, gRPC 프로토콜의 트래픽을 전달하기 위한 액션들을 정의한다. (http 이외에도 tcp, tls 필드를 통해 정의할 수 있다.)
- match : VirtualService의 라우팅 규칙을 적용하기 위한 조건들을 의미한다.
- route : match의 조건에 부합하는 트래픽들을 전달해야 하는 대상을 나타낸다. 위에 정의된 hosts 필드와는 다르게 실제로 Service Registry에 등록된 (메쉬 네트워크의 관리 대상으로 지정된 Service) 호스트여야 한다.
- 위 YAML을 설명하면, HTTP 헤더에 end-user: jason 사용자에 대해서 version: v2 레이블을 가지는 reviews Service의 대상 Pod들로 트래픽을 전달하고, 그 외는 version: v3로 전달한다.
Gateway
- Gateway는 서비스 메쉬의 인바운드, 아웃바운드 트래픽을 관리하는 역할을 가지고 있다.
- VirtualService를 Gateway에 바인딩하여 메쉬 내 다른 데이터 플레인처럼 관리할 수 있다.
- istioctl의 default profile을 통해 세팅하면 istio-ingressgateway를 기본으로 생성할 수 있다. (Istio Profile 관련 내용은 여기 참조)
- Gateway CRD를 프로비저닝하기 이전에 istio-ingressgateway를 먼저 생성해야 한다. (이때, Envoy 프록시 Pod와 LoadBalancer 타입의 Service 객체가 생성된다.)
- AWS 환경에서 세팅하는 경우, CLB가 생성되므로, 별도의 애노테이션을 설정하여 ALB / NLB로 프로비저닝할 수 있다. (Nginx Ingress Controller에서도 동일하다.)
- Gateway CRD는 어떤 Ingress Gateway Pod가 어떻게 트래픽을 수신하고 처리할지 명시하는 역할을 한다. (즉, 실제로 외부 트래픽을 처리하는 주체는 istio-ingressgateway, Gateway CRD의 Controller 역할을 수행한다.)
- Gateway CRD를 프로비저닝하기 이전에 istio-ingressgateway를 먼저 생성해야 한다. (이때, Envoy 프록시 Pod와 LoadBalancer 타입의 Service 객체가 생성된다.)
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
credentialName: ext-host-cert
- selector : 어떤 레이블을 가진 Istio Ingress 혹은 Egress Gateway Pod를 디스커버리 하는 역할을 수행한다. 즉, app: my-gateway-controller 레이블이 있는 Pod를 Gateway CRD의 컨트롤러로 대상을 지정한다.
- servers : 어떤 도메인(hosts)에 대하여 어떤 포트(port)를 리스닝 할 것인지를 명시한다.
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
# 라우팅 규칙 매칭 예시
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
- Gateway만 딸랑 정의한다고 서비스 메쉬 내로 트래픽을 전달할 수 없기 때문에 VirtualService도 정의해야 한다. ("VirtualService를 Gateway에 바인딩하여 메쉬 내 다른 데이터 플레인처럼 관리할 수 있다.")
- gateways 필드를 통해 어떤 Gateway CRD로부터 트래픽을 인입할지 명시하고, 해당 게이트웨어로부터 일치하는 도메인(hosts)에 대해 메쉬 내부 서비스로 트래픽을 라우팅하게 된다.
ServiceEntry
- ServiceEntry는 메쉬 내부에 등록되지 않은 (Service Registry에 등록되지 않은) 외부 서비스를 수동으로 메쉬 내부의 관리 대상으로 등록하는 CRD이다.
- 물론 Service Registry에 등록하지 않아도 메쉬 내부에서 외부로 트래픽을 전달하지 못하는 것은 아니지만, 서비스 메쉬의 기능을 온전히 활용할 수 없다.
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: svc-entry
spec:
hosts:
- ext-svc.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
- hosts : Service Registry에 등록할 외부 도메인
- location : 등록할 서비스에 대한 메쉬 내외부 구분 용도
- MESH_EXTERNAL : 메쉬 외부로 인식하여 mTLS 비활성화 및 해당 서비스로 향하는 트래픽을 이그레스 트래픽으로 인식한다.
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: ext-res-dr
spec:
host: ext-svc.example.com
trafficPolicy:
connectionPool:
tcp:
connectTimeout: 1s
- 이렇게 외부 서비스도 Service Registry에 등록해두면 DestinationRule이나 VirtualService로 제어가 가능해진다.
Sidecar
- 기본적으로 Istio는 서비스 메쉬 내의 모든 Envoy 프록시에 대해 모든 트래픽을 수용하게끔 설정되어 있다.
- Sidecar CRD를 통해 수용가능한 포트와 프로토콜 집합을 정의하거나 트래픽이 도달할 수 있는 서비스 집합을 제한할 수 있다.
# 예시 1)
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
name: default
namespace: bookinfo
spec:
egress:
- hosts:
- "./*"
- "istio-system/*"
---
# 예시 2)
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: example-sidecar
namespace: my-namespace
spec:
workloadSelector:
labels:
app: my-app
egress:
- hosts:
- "./b-service.my-namespace.svc.cluster.local"
- "./c-service.my-namespace.svc.cluster.local"
- 첫 번째 예시는 bookinfo 네임스페이스 내의 모든 서비스들은 동일한 네임스페이스 내의 Service들과 Istio Contol Plane (istio-system 네임스페이스의 모든 Service)에 대해서만 트래픽을 도달할 수 있도록 강제한다.
- 두 번째 예시는 my-namespace 네임스페이스 내에서 app: my-app 레이블을 가진 Pod에만 적용된다. 해당 서비스(Pod)들은 my-namespace 내의 b-service, c-service Service 객체로만 트래픽을 허용하고 나머지 이그레스 트래픽은 차단된다.
다음 글에서는 트래픽을 제어하는 옵션(Timeout, Retries, Fault Injection, Circuit Breaker)들에 대해서 알아볼게요~!
'[DevOps] - Kubernetes' 카테고리의 다른 글
| Harbor 레지스트리 구성하기 (feat. Helm Chart 연동) (0) | 2025.05.26 |
|---|---|
| Istio 톺아보기 #1 - 개요 (0) | 2025.05.17 |
| 라즈베리 파이로 홈 쿠버네티스 클러스터 구축 매뉴얼 (1) | 2025.04.20 |
| 쿠버네티스 환경의 서비스 디스커버리 (0) | 2024.05.26 |