This is a sample to show how to deploy with the canary strategy by ingress in kubernetes.
Ingress support two strategies, canary by weight
and canary by header
.
- test for canary by weight
- test for canary by header
Here will use env to flag the different app version. As the definition in app-1.0.0.yaml
:
env:
- name: app.version
value: 1.0.0
Please execute mvn clean install
to build the image at first.
The yaml files are in the canary-weight
directory.
First write a script as follow for test:
#! /bin/bash
v1=0;
v2=0;
count=100;
while [ $count -gt 0 ];
do
result=$(curl -s "http://shf.boot.com/app-service/get/app/version")
flag=$(echo $result | grep "1.0.0")
if [ "$flag" != "" ]
then
v1=$(expr $v1 + 1)
else
v2=$(expr $v2 + 1)
fi
count=$(expr $count - 1)
done;
echo $v1;
echo $v2;
- Deploy the app-1.0.0, now 100% traffic to version 1.0.0:
$ kubectl apply -f ./kubernetes/0namespace.yaml -f ./kubernetes/app-1.0.0.yaml -f ./kubernetes/ingress-1.0.0.yaml
- Execute the script, the result as follow:
100
0
We will always get 1.0.0.
- Deploy the version 2.0.0 by app-2.0.0
$ kubectl apply -f ./kubernetes/app-2.0.0.yaml
- Next deploy the ingress-canary-2.0.0 to proxy the app-2.0.0, set 20% traffic to version 2.0.0:
$ kubectl apply -f ./kubernetes/canary-weight/ingress-canary-2.0.0.yaml
- Execute the script, the result as follow:
81
19
The output results are basically consistent with the expected preset ratio(20%).
- Until everything goes well, delete
ingress-canary
and deploy ingress-2.0.0 to set 100% traffic to version 2.0.0
$ kubectl delete -f ./kubernetes/canary-weight/ingress-canary-2.0.0.yaml
$ kubectl apply -f ./kubernetes/canary-weight/ingress-2.0.0.yaml
- Execute the script, the result as follow:
0
100
We will always get 2.0.0.
- Cleanup
$ kubectl delete ns canary-deploy
The yaml files are in the canary-header
directory.
Write the test script as follow:
#! /bin/bash
echo $(curl -s -H "TAG: a" "http://shf.boot.com/app-service/get/app/version")
echo $(curl -s -H "TAG: b" "http://shf.boot.com/app-service/get/app/version")
echo $(curl -s -H "TAG: c" "http://shf.boot.com/app-service/get/app/version")
echo $(curl -s "http://shf.boot.com/app-service/get/app/version")
echo $(curl -s -H "TAG: d" "http://shf.boot.com/app-service/get/app/version")
echo $(curl -s -H "TAG: b" "http://shf.boot.com/app-service/get/app/version")
- Deploy the app-1.0.0, now 100% traffic to version 1.0.0:
$ kubectl apply -f ./kubernetes/0namespace.yaml -f ./kubernetes/app-1.0.0.yaml -f ./kubernetes/ingress-1.0.0.yaml
- Execute the script, the result as follow:
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 1.0.0
We will always get 1.0.0.
- Deploy the version 2.0.0 by app-2.0.0
$ kubectl apply -f ./kubernetes/app-2.0.0.yaml
- Next deploy the ingress-header-b to proxy the app-2.0.0. Then when the request include a header which is [TAG: b] will be oriented to version 2.0.0:
$ kubectl apply -f ./kubernetes/canary-header/ingress-header-b.yaml
- Re-run the script, the result as follow:
Current version is : 1.0.0
Current version is : 2.0.0
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 1.0.0
Current version is : 2.0.0
As expected, the output of the second and sixth contain 2.0.0
. Others contain 1.0.0
.
- Until everything goes well, delete
ingress-header-b
and deploy ingress-2.0.0 to set 100% traffic to version 2.0.0
$ kubectl apply -f ./kubernetes/canary-header/ingress-2.0.0.yaml
$ kubectl delete -f ./kubernetes/canary-header/ingress-header-b.yaml
- Re-run the script, the result as follow:
Current version is : 2.0.0
Current version is : 2.0.0
Current version is : 2.0.0
Current version is : 2.0.0
Current version is : 2.0.0
Current version is : 2.0.0
We will always get 2.0.0.
- Cleanup
$ kubectl delete ns canary-deploy