Istio의 트래픽 라우팅 규칙을 사용하면 서비스 간 트래픽 흐름과 API 호출을 쉽게 제어할 수 있다.
Traffic Management를 통해 제공하는 기능은 다음과 같다.
- Circuit breaker
- Timeout & Retry
- A/B 테스트
- Canary 테스트
- 백분율 기반 트래픽 분할
Istio의 트래픽 관리는 사용자가 서비스를 배포 하면서 함께 배포되는 Envoy 프록시에 의해 가능해진다. 모든 트래픽은 envoy 프록시를 거쳐 들어오고 나가게 되어 별도로 서비스의 변경 없이 트래픽 관리를 쉽게 할 수 있다.
더 많은 내용은 다음 페이지에서 참고 가능
architecture overview
개요
Istio는 트래픽 관리를 위해 각 서비스가 어떤 endpoint를 가지고 있는지 알아야 한다.
이 정보를 서비스 레지스트리에 등록하기 위해 Istio는 service discovery 시스템을 연결한다. 예를 들어 kubernetes 클러스터에 istio를 설치하면 자동으로 그 클러스터의 endpoint와 서비스를 탐색한다.
envoy 프록시는 이 서비스 레지스트리에 있는 정보를 활용해 적절한 서비스로 트래픽을 전달할 수 있다. 기본적으로 loadbalancing pool 에 최소 요청 모델을 사용해 각 요청이 pool에서 무작위로 선택된 두 개의 호스트 중 더 적은 수의 요청을 가진 호스트로 라우팅한다. 때문에 가장 많은 요청을 받은 호스트는 다른 호스트 중 자신보다 요청을 많이 받은 호스트가 생기기 전까지 더이상 요청을 받지 않는다.
Istio에서 기본으로 제공하는 service discovery 및 로드 밸런싱은 Istio가 할 수 있는 모든 기능을 제공하지는 않기 때문에 사용자는 트래픽을 더욱 세밀하게 제어하고 싶을 때는 트래픽 관리 API를 사용하여 구현이 가능하다 (예를 들어 특정 비율의 트래픽을 새 버전의 서비스로 라우팅하거나, 서비스의 특정 서브셋에 다른 라우팅 규칙을 적용하거나, 들어오고 나가는 트래픽에 특별한 규칙을 적용하거나, 클러스터 외부의 자원을 서비스 레지스트리에 추가하는 등). 트래픽 관리 API는 yaml로 구성할 수 있는 쿠버네티스 CRDs로 적용할 수 있다.
이 문서에서 소개하는 트래픽 관리 API 리소스의 종류는 다음과 같다.
Virtual service
Virtual services는 Destination rules와 함께 트래픽 라우팅 기능의 핵심 구성 요소이다.
Virtual services는 Istio가 제공하는 기본 연결과 discovery를 기반으로 요청을 어떻게 어떤 서비스에 라우팅 할 지 설정하는 리소스이다. 각 Virtual service는 순서대로 평가되는 일련의 라우팅 규칙으로 구성되어 Virtual service에 대한 각 요청을 mesh 내의 특정 서비스와 일치시킬 수 있도록 한다.
상황에 따라 여러 개의 virtual service가 필요할 수도 있고, 전혀 필요하지 않을 수도 있다.
사용 목적
만약 virtual service 없이 istio를 구성한다면 개요에서 설명한대로 envoy 프록시는 최소 요청 모델 기반으로 트래픽을 균등하게 분배할 것이다. A/B 테스트, canary 테스트가 필요할 때 라우팅 규칙을 정하기 위해 이 리소스를 사용한다. 지정한 규칙을 이용해 내부 사용자의 트래픽(또는 특정 백분율 기반)을 특정 인스턴스 집합으로 전달하는 A/B 테스트를 구현할 수 있다.(이때 대상이 되는 호스트는 하나일 수도 있고 여러 개일 수도 있다.) 예를 들어 “트래픽의 20%는 새로운 배포 버전” 또는 “특정 클라이언트는 새로운 배포 버전”으로 보내는 기능을 활용해 canary 배포를 구현할 수 있다. 이 과정에서 envoy가 virtual service의 규칙에 따라 다른 버전으로 트래픽을 보내기 때문에 클라이언트는 마치 하나의 서비스에 요청을 보낸다 여긴다.
기존 쿠버네티스만 활용하는 경우, 인스턴스 수에 따라 트래픽을 분배하기 때문에 위와 같은 구성을 하기 위해서 직접 인스턴스 수를 조절해야 하는 단점이 있었다. virtual service는 높은 scalability를 가지기 때문에 이런 단점을 극복할 수 있다.
Virtual service를 이용해 canary 배포 예제는 아래를 참고.
항목 | 설명 |
Routing Independence | - “20%의 요청을 새로운 버전(v2)으로 보내기”같은 규칙이 있을 때, 이 라우팅 결정과 현재 실행 중인 v2 애플리케이션 인스턴스 수는 독립적이다. - 즉, 애플리케이션의 인스턴스 수를 고민하지 않고 트래픽을 어떻게 분배할 지 정할 수 있다. |
Scalability | - v2 애플리케이션의 성능을 모니터링하면서 트래픽의 일부 비율을 늘리거나 줄일 수 있다. 이때 v2 애플리케이션의 인스턴스 수를 조정하지 않아도 된다. - 트래픽이 얼마나 필요한지 자동으로 감지하고, 그에 따라 인스턴스를 자동으로 늘리거나 줄이기 때문 |
단일 Virtual service에 여러 서비스를 매핑 할 수도 있다. 이는 monolithic 애플리케이션이 MSA 구조로 전환될 때, 클라이언트가 전환 내용에 적응할 필요 없이 기존처럼 “monolithic.com”이라는 host의 특정 url을 입력하면, 그에 따라 적절한 애플리케이션 모듈로 라우팅 시킬 수 있다.
사용 예제
apiVersion: networking.istio.io/v1alpha3
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
hosts
hosts
필드는 클라이언트가 주소를 지정할 수 있는 대상 host 또는 이런 라우팅 규칙이 적용되는 대상 host 목록을 나열한다.이 주소는 사용자가 요청을 보낼 때 사용하는 주소이다.
여기서 말하는 host가 될 수 있는 대상은 다음과 같다.
- IP주소
- DNS 이름
- FQDN(정규화 도메인 이름; 예를 들어 서비스 이름)
"*"
와일드 카드(”*”)는 일치하는 모든 서비스에 단일 라우팅 규칙을 적용한다.
이 host는 꼭 istio 내부에 있는 리소스 뿐만 아니라 외부에 있는 host에 대해서도 가능하다.
routing 규칙
http
필드는 라우팅 규칙을 정하는 필드이며 다음을 포함한다.
- HTTP/1.1
- HTTP2
- gRPC
http
외에도 tcp
, tls
로 TCP 또는 TLS 트래픽에 대한 라우팅 규칙을 지정할 수도 있다.
routing 규칙을 0개 혹은 여러개 정하여 조건에 따라 원하는 목적지로 트래픽을 보낼 수 있다.
규칙을 포함하는 필드는 match
와 destination
이 있다.
match
- 특정 트래픽을 선별하는 필드.
- 하나의
match
블록에 여러 조건을 추가해 AND 조건 구현 가능 - 여러
match
블록을 추가해 OR 조건 구현 가능 port
,header
필드,URIs
등 많은 규칙이 제공됨 (HTTPMatchRequest reference)
destination
- 실제로 트래픽을 보낼 대상
- envoy가 요청을 보낼 때 도착지 정보를 알아야 하기 때문에 virtual service의 hosts와 달리 istio service registry에 실제 존재하는 대상이어야 한다.
- 이는 proxy가 포함된 mesh service이거나, service entry로 registry에 추가된 non-nesh service일 수 있다.
- 서비스의 하위 집합으로도 지정이 가능하다.
짧은 이름(e.g., service 이름)은 destionation.host와 virtual service가 같은 namespace에 있을 때에만 사용해야 한다.
실제 상용 환경에서는 이 과정에서 잘못된 구성이 적용될 수 있으므로 FQDN 사용을 권장한다.
라우팅 규칙은 위에서 아래로 순차적으로 평가된다. 즉, 상위 규칙일수록 높은 priority가 부여된다. 하나의 트래픽이 적어도 하나의 destination에는 라우팅 될 수 있도록 규칙의 마지막에는 조건이 없는(또는 가중치 기반 규칙; 아래에서 설명) 기본 규칙을 정해주는 것을 권장한다.
weight
필드를 이용해 트래픽을 분배할 수도 있다.
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75
- destination:
host: reviews
subset: v2
weight: 25
라우팅 규칙을 통해 다음 작업들도 가능하다.
- 헤더를 추가하거나 제거
- URL 재작성
- 이 destination에 대해 retry 정책 설정
더 많은 작업들에 대한 내용은 아래 페이지 참고
HTTP Route reference
Destination rule
Virtual service와 함께 Istio의 라우팅 기능의 핵심 요소 중 하나이다.
virtual service가 어떻게(HOW) 트래픽을 라우팅 할 것인지 정한다면, Destination rules는 destination에 대한 트래픽에 어떤(WHAT) 일이 발생하는지 구성한다. 트래픽이 virtual service의 라우팅 규칙에 의해 평가된 후에 적용되므로 실제 대상에 대해 적용된다.
특히 특정 서비스의 모든 인스턴스를 버전별로 그룹화하는 등 명명된 서비스 서브셋을 지정한다. 이 서브셋은 virtual service의 라우팅 규칙에서 사용된다.
또한 envoy 프록시의 트래픽 정책(e.g., 선호하는 로드밸런싱 모델 지정, TLS 모드, circuit breaker 등)을 커스터마이징 할 수 있도록 해준다.
커스터마이징 할 수 있는 더 많은 트래픽 정책은 다음 페이지에서 확인 가능하다.
Destination rules reference
istio는 기본적으로 가장 적은 요청을 가진 인스턴스에 트래픽을 분배하는 최소 요청 로드 밸런싱 정책을 사용하는데 이 외에도 random, weighted, round robin, ring hash, panic threshold 등 많은 옵션을 제공한다. 그 외에 옵션들은 다음 페이지에서 확인 가능하다.
Envoy load balancing documentation
사용 예제
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-svc
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
위 코드에서 각 서브셋은 한 개 이상의 라벨로 정의 되어있다.
서브셋을 지정하는 것 외에도 전역적으로 트래픽 정책을 선언할 수 있는데 v1, v3에는 random load balancer가 설정되고, v2에는 round-robin load balancer가 설정된다.
Gateway
Gateway는 mesh의 inbound, outbound 트래픽을 관리하여 mesh에 들어오거나 나갈 트래픽을 지정할 수 있다.
gateway 설정은 workload에 sidecar로 배포되는 envoy 프록시가 아닌 mesh의 끝 단에 있는 envoy proxy에 적용된다. istio gateway는 시스템으로 들어오는 트래픽을 관리하는 다른 매커니즘(e.g., kubernetes’s ingress APIs)보다 더 높은 성능을 보이는데 TLS 설정, 노출 port 설정 등을 L4~L6에 구성할 수 있기 때문이다.
주로 수신하는 트래픽 관리에 사용 되지만, 외부 네트워크에 엑세스할 수 있는 또는 엑세스할 서비스를 제한하기 위해 전용 노드를 구성할 때 gress gateway로도 사용 가능하다. 또는 secure control을 활성화하여 보안을 추가할 수도 있다.
사용 예제
apiVersion: networking.istio.io/v1alpha3
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
위 코드는 HTTPS 요청에 대한 설정을 담당한다. “ext-host.example.com”의 443 포트로 들어오는 트래픽을 허용하지만 라우팅 하지는 않고 있다. 만약 트래픽을 라우팅 하려면 원하는 virtual service의 gateways
필드에 해당 gateway를 추가해야 한다.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
더 많은 내용은 아래 페이지에서 확인 가능하다.
Gateway reference
Service entry
Service entries는 엔트리를 istio의 service registry에 등록하기 위해 사용된다.
아래 과정을 통해 envoy 프록시는 mesh 내부에 있는 서비스처럼 mesh 외부 서비스에 트래픽을 전송할 수 있다.
- 웹 API 같은 외부 대상 또는 레거시 인프라 서비스에 대한 트래픽을 redirect 하고 전달한다.
- retry, timeout, fault injection 등의 정책을 외부 대상에 정의한다.
- mesh에 VM을 추가해 그 위에서 해당 mesh 서비스를 실행한다.
(https://istio.io/latest/docs/examples/virtual-machines/)
기본적으로 istio는 알 수 없는 서비스에 대한 요청을 통과 시키도록 구성되어 있어 mesh에서 사용하려는 모든 외부 서비스를 등록할 필요는 없다.
즉, 트래픽 제어가 필요한 외부 서비스만 등록하면 된다.
사용 예제
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: svc-entry
spec:
hosts:
- ext-svc.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ext-res-dr
spec:
host: ext-svc.example.com
trafficPolicy:
connectionPool:
tcp:
connectTimeout: 1s
위 예제는 “ext-svc.example.com”이라는 외부 종속성을 service registry에 추가해 timeout을 설정하는 코드이다. 이렇게 등록한 엔트리는 mesh 내부 서비스처럼 destination rule이나 virtual service에서 사용 가능하다.
hosts
필드에 원하는 외부 리소스를 추가하거나 와일드 카드 접두사가 붙은 도메인 이름을 사용할 수 있다.
더 많은 내용은 아래 페이지에서 확인 가능하다.
Service Entry reference
Reference
'Istio' 카테고리의 다른 글
istio deep dive: Sidecar Traffic Intercepting & Routing Process (0) | 2024.01.04 |
---|---|
Istio ingress gateway VS API Gateway (istio ver. 1.19) (0) | 2024.01.03 |
Canary deployment using Istio (1) | 2024.01.03 |
Istio addons on Minikube (0) | 2023.12.27 |
Envoy 기초 (0) | 2023.12.27 |