Phased Release of Application Services through Kubernetes Ingress Controller

Release Scenarios

Scenario 1

Scenario 2

  1. Traffic splitting based on the request header, which is applicable to phased release and A/B testing scenarios.
  2. Traffic splitting based on the cookie, which is applicable to phased release and A/B testing scenarios.
  3. Traffic splitting based on the query parameter, which is applicable to phased release and A/B testing scenarios.
  4. Traffic splitting based on the service weight, which is applicable to blue-green release scenarios.

Annotation Description

1. nginx.ingress.kubernetes.io/service-match

nginx.ingress.kubernetes.io/service-match: | 
<service-name>: <match-rule>
# Parameter description:
# service-name: indicates the service name. Requests that conform to the rule specified by match-rule are routed to this service.
# match-rule: indicates the routing matching rule.
#
# Routing matching rule:
# 1. Supported matching types:
# - header: indicates matching based on the request header, which can be regular expression matching or exact expression matching.
# - cookie: indicates matching based on the cookie, which can be regular expression matching or exact expression matching.
# - query: indicates matching based on the query parameter, which can be regular expression matching or exact expression matching.
#
# 2. Matching modes:
# - Regular expression matching format: /{regular expression}/. // indicates matching based on a regular expression.
# - Exact expression matching format: "{exact expression}". "" indicates matching based on an exact expression.
# Requests whose foo in the request header contains ^bar$ (regular expression matching) are forwarded to the new-nginx service.
new-nginx: header("foo", /^bar$/)
# Requests whose foo in the request header equals bar (exact expression matching) are forwarded to the new-nginx service.
new-nginx: header("foo", "bar")
# Requests whose foo in the cookie contains ^sticky-.+$ (regular expression matching) are forwarded to the new-nginx service.
new-nginx: cookie("foo", /^sticky-.+$/)
# Requests whose foo in the query parameter equals bar (exact expression matching) are forwarded to the new-nginx service.
new-nginx: query("foo", "bar")

2. nginx.ingress.kubernetes.io/service-weight

nginx.ingress.kubernetes.io/service-weight: | 
<new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>
Parameter description:
new-svc-name: indicates the name of the new-version service.
new-svc-weight: indicates the weight of the new-version service.
old-svc-name: indicates the name of the old-version service.
old-svc-weight: indicates the weight of the old-version service.
nginx.ingress.kubernetes.io/service-weight: | 
new-nginx: 20, old-nginx: 60
  1. A service weight is calculated based on the relative value. In the preceding example, the weight percentage of the new-nginx service is 25%, whereas that of the old-nginx service is 75%.
  2. In a service group (in which services have the same host and path in the Ingress YAML file), the default weight value of services without a specified weight is 100.

Version Updates

  1. Deployed using Deployment
  • kubectl -n kube-system get deploy nginx-ingress-controller -o yaml | grep -v 'apiVersion' | grep 'aliyun-ingress-controller'
  • kubectl -n kube-system get ds nginx-ingress-controller -o yaml | grep -v 'apiVersion' | grep 'aliyun-ingress-controller'
kubectl -n kube-system set image deploy/nginx-ingress-controller nginx-ingress-controller=registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:0.12.0-5
kubectl -n kube-system set image ds/nginx-ingress-controller nginx-ingress-controller=registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:0.12.0-5

Service Deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: old-nginx
spec:
replicas: 2
selector:
matchLabels:
run: old-nginx
template:
metadata:
labels:
run: old-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx
imagePullPolicy: Always
name: old-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: old-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: old-nginx
sessionAffinity: None
type: NodePort
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gray-release
spec:
rules:
- host: www.example.com
http:
paths:
# Old-version service
- path: /
backend:
serviceName: old-nginx
servicePort: 80
kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
gray-release www.example.com 47.107.20.35 80 1m
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old

Phased Release of the new-version Service

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: new-nginx
spec:
replicas: 1
selector:
matchLabels:
run: new-nginx
template:
metadata:
labels:
run: new-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx
imagePullPolicy: Always
name: new-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: new-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: new-nginx
sessionAffinity: None
type: NodePort

Scenario 1: Set a specific rule to allow clients that conform to this rule to access the new-nginx service.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# Requests whose foo in the request header contains bar (regular expression matching) are routed to the new-nginx service.
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
spec:
rules:
- host: www.example.com
http:
paths:
# Old-version service
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# New-version service
- path: /
backend:
serviceName: new-nginx
servicePort: 80
curl -H "Host: www.example.com"  http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new

Scenario 2: Set a specific rule to route a specified proportion of requests that conform to this rule to the new-nginx service.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# Requests whose foo in the request header contains bar (regular expression matching) are routed to the new-nginx service.
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
# Only 50% of the requests that conform to the preceding matching rule are routed to the new-nginx service.
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
rules:
- host: www.example.com
http:
paths:
# Old-version service
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# New-version service
- path: /
backend:
serviceName: new-nginx
servicePort: 80
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
old
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
old
curl -H "Host: www.example.com" -H "foo: bar" http://47.107.20.35
new

Scenario 3: Route a specified proportion of requests to the new-nginx service.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# Only 50% of traffic is routed to the new-nginx service.
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
rules:
- host: www.example.com
http:
paths:
# Old-version service
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# New-version service
- path: /
backend:
serviceName: new-nginx
servicePort: 80
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
old
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
old

Completion of the Phased Release

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gray-release
spec:
rules:
- host: www.example.com
http:
paths:
# New-version service
- path: /
backend:
serviceName: new-nginx
servicePort: 80
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
new
curl -H "Host: www.example.com" http://47.107.20.35
new

--

--

--

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

JENKINSFILE VALIDATION

How to write self-documented code with low cognitive complexity

ANACITY, a cost-saving software for Owner Association Management Companies

Simplify Android Kotlin Code with Ktlint

Setting goals

Access Modifiers in C#

Have a Whole Product Team without Having a $1m Payroll

How to Deploy and Host a Joomla Website on Alibaba Cloud ECS

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

More from Medium

The SRE series: add a worker node to Kubernetes

A step-by-step guide to implement metrics for your ad-hoc Operator in Golang by Prometheus on…

Taints And Toleration Basics In Kubernetes

Zero-Downtime Deployment in Kubernetes

Deployment illustration with rocket launch.