https://itnp.kr/post/canary-deployments-using-istio
에서 올려주신 블로그를 참조하여 카나리아를 테스트해보자
카나리아를 디폴드 네임스페이스에 테스트해보자
kubectl label ns default istio-injection=enabled #디폴트 네임스페이스에 istio추적 하게 라벨링설정
> namespace/default labeled
hello서버 v1 버전을 업로드후 접속테스트를 진행한다.
#httbin 통신용 파드 하나 추가
kubectl apply -f httbin.yml
> pod/httpbin created
#통신할 v1버전의 hello서버 디폴로이먼트와 서비스 추가
kubectl apply -f hello-deployment.yml
> deployment.apps/hello-server-v1 created
> service/svc-hello created
반복돌려
for i in {1..5}; do kubectl exec -it httpbin -c httpbin -- curl http://svc-hello.default.svc.cluster.local:8080; sleep 0.1; done
> Hello server - v1
> Hello server - v1
> Hello server - v1
> Hello server - v1
> Hello server - v1
카나리아 테스트를 위해 hello서버와 서비스에 셀렉터를 추가한다(추가하는 셀렉터는 버전이다)
kubectl apply -f hello-deployment_v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-server-v1
labels:
app: hello
version: v1
spec:
replicas: 2
selector:
matchLabels:
app: hello
version: v1
template:
metadata:
labels:
app: hello
version: v1
spec:
containers:
- image: honester/hello-server:v1
imagePullPolicy: IfNotPresent
name: hello-server-v1
---
apiVersion: v1
kind: Service
metadata:
name: svc-hello
labels:
app: hello
spec:
selector:
app: hello
version: v1
ports:
- name: http
protocol: TCP
port: 8080
kubectl apply -f hello-deployment_v2.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-server-v2
labels:
app: hello
version: v2
spec:
replicas: 2
selector:
matchLabels:
app: hello
version: v2
template:
metadata:
labels:
app: hello
version: v2
spec:
containers:
- image: honester/hello-server:v2
imagePullPolicy: IfNotPresent
name: hello-server-v2
kubectl get all --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/hello-server-v1-dccb576fc-q2q4s 2/2 Running 0 4m36s app=hello,pod-template-hash=dccb576fc,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=hello,service.istio.io/canonical-revision=v1,version=v1
pod/hello-server-v1-dccb576fc-v5nb2 2/2 Running 0 4m36s app=hello,pod-template-hash=dccb576fc,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=hello,service.istio.io/canonical-revision=v1,version=v1
pod/hello-server-v2-f7bf65bf8-97hdp 2/2 Running 0 4m app=hello,pod-template-hash=f7bf65bf8,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=hello,service.istio.io/canonical-revision=v2,version=v2
pod/hello-server-v2-f7bf65bf8-fcmrm 2/2 Running 0 4m app=hello,pod-template-hash=f7bf65bf8,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=hello,service.istio.io/canonical-revision=v2,version=v2
pod/httpbin 2/2 Running 0 12m app=httpbin,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=httpbin,service.istio.io/canonical-revision=latest
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d component=apiserver,provider=kubernetes
service/svc-hello ClusterIP 10.102.124.176 <none> 8080/TCP 12m app=hello
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/hello-server-v1 2/2 2 2 4m36s app=hello,version=v1
deployment.apps/hello-server-v2 2/2 2 2 4m app=hello,version=v2
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/hello-server-v1-dccb576fc 2 2 2 4m36s app=hello,pod-template-hash=dccb576fc,version=v1
replicaset.apps/hello-server-v2-f7bf65bf8 2 2 2 4m app=hello,pod-template-hash=f7bf65bf8,version=v2
dr-hello.yml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr-hello
spec:
host: svc-hello
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
virtualservice 를 생성합니다.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-hello
spec:
hosts:
- svc-hello.default.svc.cluster.local
http:
- match:
- headers:
end-user:
exact: "testers"
route:
- destination:
host: svc-hello
subset: v1
weight: 50
- destination:
host: svc-hello
subset: v2
weight: 50
- route:
- destination:
host: svc-hello
subset: v1
셋팅하면 v2가 인식이안되서 에러가 난다
서비스에서 셀럭터 부분에 버전을 제거하여준다
apiVersion: v1
kind: Service
metadata:
name: svc-hello
labels:
app: hello
spec:
selector:
app: hello
ports:
- name: http
protocol: TCP
port: 8080
그리고 VirtualService 셋팅해서 end-user:testers 일경우 50:50부분으로 트래픽을 분할한다.
for i in {1..10}; do kubectl exec -it httpbin -c httpbin -- curl -H "end-user:testers" http://svc-hello:8080; sleep 0.1; done
Hello server - v2
Hello server - v1
Hello server - v1
Hello server - v1
Hello server - v2
Hello server - v2
Hello server - v2
Hello server - v1
Hello server - v2
Hello server - v2
테스트하고 v2가 정상작동 하면 v1을 제거 v2가 비정상작동이면 v2를 제거한다.