金丝雀发布(Canary releas)是一种降低在生产中引入新软件版本的风险的技术,方法是在将更改推广到整个基础架构并使其可供所有人使用之前,缓慢地将更改推广到一小部分用户。
基于header灰度
通过Annotaion扩展创建灰度ingress
灰度头部key以及value灰度流量验证完毕后
切换正式ingress到新版本
如双十一开始前,先对服务器进行cdn流量导向,就可设定一定的用户数量访问测试
首先删除所有之前创建的ingress规则,避免冲突
[root@k8s2 ingress]# kubectl delete ingress --all
创建两个应用版本
[root@k8s2 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d19h
myapp-v1 ClusterIP 10.102.0.141 <none> 80/TCP 34m
myapp-v2 ClusterIP 10.108.173.0 <none> 80/TCP 29m
[root@k8s2 ingress]# vim ingress-v1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-v1-ingress
spec:
ingressClassName: nginx
rules:
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myapp-v1
port:
number: 80
[root@k8s2 ingress]# kubectl apply -f ingress-v1.yaml
[root@k8s2 ingress]# vim ingress-v2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: stage
nginx.ingress.kubernetes.io/canary-by-header-value: gray
name: myapp-v2-ingress
spec:
ingressClassName: nginx
rules:
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myapp-v2
port:
number: 80
[root@k8s2 ingress]# kubectl apply -f ingress-v2.yaml
正常访问到v1
[root@k8s1 harbor]# curl myapp.westos.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
加了key - v键值的header后,访问到了v2,将新版本局限到一定范围内。
[root@k8s1 harbor]# curl -H "stage: gray" myapp.westos.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
基于权重灰度
按照权重灰度
通过Annotaion拓展
创建灰度ingress,配置灰度权重以及总权重灰度流量验证完毕后,切换正式ingress到新版本
修改配置
[root@k8s2 ingress]# vim ingress-v2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
#nginx.ingress.kubernetes.io/canary-by-header: stage
#nginx.ingress.kubernetes.io/canary-by-header-value: gray
nginx.ingress.kubernetes.io/canary-weight: "10" #转发到v2版本的流量百分比
nginx.ingress.kubernetes.io/canary-weight-total: "100" #总共100
name: myapp-v2-ingress
spec:
ingressClassName: nginx
rules:
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: myapp-v2
port:
number: 80
运行
[root@k8s2 ingress]# kubectl apply -f ingress-v2.yaml
测试脚本,统计100此,输出v1和v2的比例
[root@k8s1 ~]# vim test.sh
#!/bin/bash
v1=0
v2=0
for (( i=0; i<100; i++))
do
response=`curl -s myapp.westos.org |grep -c v1`
v1=`expr $v1 + $response`
v2=`expr $v2 + 1 - $response`
done
echo "v1:$v1, v2:$v2"
修改canary-weight,30%,50%,100%,一点一点把流量到v2,直到把流量全部切换到v2版本
[root@k8s1 ~]# sh test.sh
v1:88, v2:12
[root@k8s1 ~]# sh test.sh
v1:74, v2:26
[root@k8s1 ~]# sh test.sh
v1:48, v2:52
[root@k8s1 ~]# sh test.sh
v1:0, v2:100
业务域拆分
以微服务各个业务域含义作为API路径前缀ingress provider负责去掉业务域前缀易于管理维护、认证鉴权、观测统计,类似于重定向,不过是定到微服务
好处在能够对架构内每个服务进行拆分管理,如lnmp架构内,将php,ngnix拆出来,分别根据实际情况进行扩缩容,进行流量拆分管理
[root@k8s2 ingress]# vim ingress-v3.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
name: ingress-v3
spec:
ingressClassName: nginx
rules:
- host: myapp.westos.org
http:
paths:
- path: /user/(.*) #如出现user,定向到v1
pathType: Prefix
backend:
service:
name: myapp-v1
port:
number: 80
- path: /order/(.*)#如果出现order,定向到v2
pathType: Prefix
backend:
service:
name: myapp-v2
port:
number: 80
运行
[root@k8s2 ingress]# kubectl apply -f ingress-v3.yaml
不同域名定向到不同服务
[root@k8s1 ~]# curl myapp.westos.org/user/hostname.html
myapp-deployment-67984c8646-vppq7
[root@k8s1 ~]# curl myapp.westos.org/order/hostname.html
myapp-deployment-v2-74b4cdbf78-fjgn5