Before you update a Service, you can use canary releases to test the stability of the new Service version. The Application Load Balancer (ALB) Ingress controller allows you to use annotations to specify the percentage of traffic routed to a canary Service. This topic describes how to use an ALB Ingress to perform canary releases.
Usage notes for canary annotations
ALB Ingresses allow you to use canary annotations to perform canary releases based on headers, cookies, and weights. Canary releases that use different rules take effect in the following order: header-based > cookie-based > weight-based. If you configure the header-based, cookie-based, and weight-based rules at the same time, the rules with the highest priority shall prevail. For more information about canary annotations, see Use annotations to perform canary releases. Step 1: Create an application
- Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
- Deploy a Service named tea.
- Create a file named tea-deploy.yaml and copy the following content to the file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 1
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx:latest
ports:
- containerPort: 80
- Run the following command to deploy the tea Service:
kubectl apply -f tea-deploy.yaml
- Deploy a Service named tea-svc.
- Create a file named tea-svc.yaml and copy the following content to the file:
apiVersion: v1
kind: Service
metadata:
name: tea-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: tea
type: NodePort
- Run the following command to deploy the tea-svc Service:
kubectl apply -f tea-svc.yaml
- Deploy an Ingress named tea-ingress.
- Create a file named test-ingress.yaml and copy the following content to the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tea-ingress
spec:
ingressClassName: alb
rules:
- host: demo.domain.ingress.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- Run the following command to deploy the Ingress:
kubectl apply -f tea-ingress.yaml
Step 2: Perform a canary release for a new Service version
Deploy a new Service version and a new Ingress version to route all requests that carry the location: hz
header to the new Service version named canary and route 50% of the other requests to the new Service version. Other requests include requests that carry other headers and requests that do not carry headers.
- Deploy the new Service version named canary.
- Create a file named canary-deploy.yaml and copy the following content to the file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: canary
spec:
replicas: 1
selector:
matchLabels:
app: canary
template:
metadata:
labels:
app: canary
spec:
containers:
- name: canary
image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx:latest
ports:
- containerPort: 80
- Run the following command to deploy the canary Service:
kubectl apply -f canary-deploy.yaml
- Deploy a Service named canary-svc.
- Create a file named canary-svc.yaml and copy the following content to the file:
apiVersion: v1
kind: Service
metadata:
name: canary-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: canary
type: NodePort
- Run the following command to deploy the canary-svc Service:
kubectl apply -f canary-svc.yaml
- Deploy an Ingress to route requests based on headers.
- Create a file named canary-header-ingress.yaml and copy the following content to the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/canary: "true"
alb.ingress.kubernetes.io/canary-by-header: "location"
alb.ingress.kubernetes.io/canary-by-header-value: "hz"
name: canary-header-ingress
namespace: default
spec:
ingressClassName: alb
rules:
- host: demo.domain.ingress.top
http:
paths:
- backend:
service:
name: canary-svc
port:
number: 80
path: /
pathType: Prefix
- Set alb.ingress.kubernetes.io/canary to true to enable canary annotations.
- Set alb.ingress.kubernetes.io/canary-by-header and alb.ingress.kubernetes.io/canary-by-header-value to the key and value of the header that you want to match. In this example, the KV pair of the header is set to
location: hz
. All requests that carry the location: hz
header are routed to the new Service version. Requests that carry other headers are matched against other canary release rules based on the priorities of the rules and then routed to the Service versions associated with the matching rules.
- Run the following command to deploy an Ingress to route requests based on headers:
kubectl apply -f canary-header-ingress.yaml
- Deploy an Ingress to route requests based on weights.
- Create a file named canary-weight-ingress.yaml and copy the following content to the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/canary: "true"
alb.ingress.kubernetes.io/canary-weight: "50"
name: canary-weight-ingress
namespace: default
spec:
ingressClassName: alb
rules:
- host: demo.domain.ingress.top
http:
paths:
- backend:
service:
name: canary-svc
port:
number: 80
path: /
pathType: Prefix
alb.ingress.kubernetes.io/canary-weight: specifies the percentage of traffic routed to the new Service version. In this example, the value is set to 50, which indicates that 50% of the traffic is routed to the new Service version.
- Run the following command to deploy an Ingress to route requests based on weights:
kubectl apply -f canary-weight-ingress.yaml
- Check whether the canary release is successful.
- Run the following command to query the IP address of the ALB instance:
kubectl get ing
Expected output:
NAME CLASS HOSTS ADDRESS PORTS AGE
canary-header-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 8m23s
canary-weight-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 8m16s
tea-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 7m5s
- Run the following command multiple times to send requests that carry the
location: hz
header to the Service: curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
Expected output:
new
new
is returned for the requests that carry the location: hz
header. The requests that carry the location: hz
header are routed to the new Service version.
- Run the following command multiple times to send requests that do not carry headers to the Service:
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
new
is returned for 50% of the requests that do not carry headers and old
is returned for the remaining 50% of the requests. 50% of the requests that do not carry headers are routed to the new Service version.
- Run the following command multiple times to send requests that carry the
location: bj
header to the Service: curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
new
is returned for 50% of the requests that carry the location: bj
header and old
is returned for the remaining 50% of the requests. 50% of the requests that carry the location: bj
header are routed to the new Service version.
All requests that carry the location: hz
header are routed to the new Service version named canary. Only 50% of the requests that carry other headers and do not carry headers are routed to the new Service version. The canary release is successful.
Step 3: Deprecate the old Service version
After the new Service version runs as expected for a period of time, you need to deprecate the old Service version and keep only the new Service version. To do this, you need to change the Service in the Ingress of the old Service version to the new Service version so that the Ingress can route traffic to the new Service version. Then, delete the canary Ingresses.
- Run the following command to change the Service in the tea-ingress.yaml file from tea-svc to canary-svc:
vim tea-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tea-ingress
spec:
ingressClassName: alb
rules:
- host: demo.domain.ingress.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-svc
port:
number: 80
- Run the following command for the modified Ingress to take effect:
Kubectl apply -f tea-ingress.yaml
- Check whether the old Service version is deprecated.
- Run the following command multiple times to send requests that carry the
location: hz
header to the Service: curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
Expected output:
new
new
is returned for the requests that carry the location: hz
header. Requests that carry the location: hz
header are routed to the new Service version.
- Run the following command multiple times to send requests that do not carry headers to the Service:
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
Expected output:
new
new
is returned for the requests that do not carry headers to the Service. Requests that do not carry headers to the Service are routed to the new Service version.
- Run the following command multiple times to send requests that carry the
location: bj
header to the Service: curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
Expected output:
new
new
is returned for the requests that carry the location: bj
header. Requests that carry the location: bj
header are routed to the new Service version.
Requests that carry the location: hz
header, requests that carry other headers, and requests that do not carry headers are all routed to the new Service version. The old Service version is deprecated.
- Run the following command to delete the canary Ingresses named canary-weight-ingress and canary-header-ingress:
kubectl delete ing canary-weight-ingress canary-header-ingress