상황 1. 트래픽의 일정 비율을 새로운 버전으로 라우팅
같은 서비스에 대해 2개의 버전 (v1, v2)를 배포해서 v2에 10%의 유저 트래픽을 보내 canary 테스트를 하는 상황이라 가정해보자.
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
selector:
app: helloworld
...
v1과 v2는 라벨로 버전을 구분짓는다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
spec:
replicas: 1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
containers:
- image: helloworld-v1
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
spec:
replicas: 1
template:
metadata:
labels:
app: helloworld
version: v2
spec:
containers:
- image: helloworld-v2
...
쿠버네티스만 사용했다면 90%, 10%의 트래픽 분배를 위해 각각 replicas: 9
, replicas: 1
로 설정해야 한다. 하지만 istio를 사용할 경우에는 단순히 Virtual service에 라우팅 규칙을 정해주기만 하면 된다. (실제 배포를 담당하는 deployment 및 service와 같은 리소스들이 아닌 virtual service가 담당하므로 정책에 종속받지 않고 위와 같이 작성될 수 있다.)
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld
http:
- route:
- destination:
host: helloworld
subset: v1
weight: 90
- destination:
host: helloworld
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
spec:
host: helloworld
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
EOF
위의 규칙은 replicas에 관계없이 1/10의 트래픽만 v2로 배포되도록 한다.
$ kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10
deployment "helloworld-v1" autoscaled
$ kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10
deployment "helloworld-v2" autoscaled
$ kubectl get hpa
NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE
Helloworld-v1 Deployment/helloworld-v1 50% 47% 1 10 17s
Helloworld-v2 Deployment/helloworld-v2 50% 40% 1 10 15s
replicas 비율을 관리할 필요가 없으므로 HPA를 추가하여 두 버전의 replicas를 관리한다.
$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-3q5wh 0/2 Pending 0 15m
helloworld-v1-3523621687-73642 2/2 Running 0 11m
helloworld-v1-3523621687-7hs31 2/2 Running 0 19m
helloworld-v1-3523621687-dt7n7 2/2 Running 0 50m
helloworld-v1-3523621687-gdhq9 2/2 Running 0 11m
helloworld-v1-3523621687-jxs4t 0/2 Pending 0 15m
helloworld-v1-3523621687-l8rjn 2/2 Running 0 19m
helloworld-v1-3523621687-wwddw 2/2 Running 0 15m
helloworld-v1-3523621687-xlt26 0/2 Pending 0 19m
helloworld-v2-4095161145-963wt 2/2 Running 0 50m
이제 요청을 반복하여 보낸 후 pod의 개수를 살펴보면 90%의 트래픽을 받도록 한 v1의 pod 개수가 더 많이 로드된 것을 볼 수 있다.
$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-73642 2/2 Running 0 35m
helloworld-v1-3523621687-7hs31 2/2 Running 0 43m
helloworld-v1-3523621687-dt7n7 2/2 Running 0 1h
helloworld-v1-3523621687-gdhq9 2/2 Running 0 35m
helloworld-v1-3523621687-l8rjn 2/2 Running 0 43m
helloworld-v2-4095161145-57537 0/2 Pending 0 21m
helloworld-v2-4095161145-9322m 2/2 Running 0 21m
helloworld-v2-4095161145-963wt 2/2 Running 0 1h
helloworld-v2-4095161145-c3dpj 0/2 Pending 0 21m
helloworld-v2-4095161145-t2ccm 0/2 Pending 0 17m
helloworld-v2-4095161145-v3v9n 0/2 Pending 0 13m
만약 라우팅 규칙을 각 애플리케이션이 50%로 동일하게 받도록 설정한다면 v1과 v2 pod이 같은 비율로 로드 되는 것을 확인할 수 있다.
$ kubectl get pods | grep helloworld
helloworld-v1-3523621687-dt7n7 2/2 Running 0 1h
helloworld-v2-4095161145-963wt 2/2 Running 0 1h
이 상황에서 요청을 줄인다면 두 버전의 pod 개수가 최소값(1)로 축소된다.
상황 2. 특정 사용자의 요청을 새로운 버전으로 라우팅
이번에는 특정 사용자(내부 사용자 등)를 대상으로 새로운 버전의 애플리케이션을 테스트해 보고 싶은 상황이라 가정하자.
“some-company-name.com” 사용자의 트래픽 중 50%를 새로운 버전으로 라우팅 하는 시나리오이다.
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld
http:
- match:
- headers:
cookie:
regex: "^(.*?;)?(email=[^;]*@some-company-name.com)(;.*)?$"
route:
- destination:
host: helloworld
subset: v1
weight: 50
- destination:
host: helloworld
subset: v2
weight: 50
- route:
- destination:
host: helloworld
subset: v1
EOF
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 |
Traffic Management (1) | 2024.01.03 |
Istio addons on Minikube (0) | 2023.12.27 |
Envoy 기초 (0) | 2023.12.27 |