Argo rollouts结合Ingress Nginx进行Canary流量迁移
Istio环境中支持两种流量分割模式
◼ 更新期间,使用不同的Service分别承载新旧版本的流量
◆Canary和Stable版本分别对应一个独立的Service
⚫ canaryService:待发布的新版本
⚫ stableService:待更新的旧版本
◆分别为Canary和Stable的Pod添加rollouts-pod-template-hash标签,其值为相应的RS模板的hash值
◼ 通过Ingress完成流量分割和迁移
◆更新期间,默认创建的Ingress用于承载旧版本的请求流量
◆另外生成一个专用的Ingress用于承载Canary流量,并将这些流量转发到canaryServer相关的EndPoint之上
◆动态调整canaryIngress和stableIngress的weight进行流量迁移
◼ 更新完后,所有流量回转至stableIngress和stableService,此时相关的后端EndPoint已经切换为发布的新版本
提示:这种Canary期间VS的动态调整可能会导致通过GitOps自动化部署时的问题:权重的瞬时摆动
测试此示例前,先把之前启动的service删除掉
kubectl delete -f 01-basic-rollotes-demo.yaml
查看是否运行rollouts资源
kubectl get rollouts
运行文件
[root@ubuntu2004 rollout-demos]#pwd
/root/learning-jenkins-cicd/09-argocd-and-rollout/rollout-demos
[root@ubuntu2004 rollout-demos]#cat 02-rollouts-with-ingress-nginx-traffic-shifting.yaml
# CopyRight: MageEdu <mage@magedu.com>
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-helloworld-with-traffic-shifting
spec:
replicas: 10
strategy:
canary:
canaryService: spring-boot-helloworld-canary
stableService: spring-boot-helloworld
trafficRouting:
nginx:
stableIngress: spring-boot-helloworld
steps:
- setCanaryScale:
matchTrafficWeight: true
- setWeight: 5
- pause: {duration: 1m}
- setWeight: 10
- pause: {duration: 1m}
- pause: {duration: 20}
- setWeight: 20
- pause: {duration: 40}
- setWeight: 40
- pause: {duration: 20}
- setWeight: 60
- pause: {duration: 20}
- setWeight: 80
- pause: {duration: 20}
revisionHistoryLimit: 5
selector:
matchLabels:
app: spring-boot-helloworld
template:
metadata:
labels:
app: spring-boot-helloworld
spec:
containers:
- name: spring-boot-helloworld
image: ikubernetes/spring-boot-helloworld:v0.9.2
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 50m
livenessProbe:
httpGet:
path: '/'
port: 80
scheme: HTTP
initialDelaySeconds: 3
readinessProbe:
httpGet:
path: '/'
port: 80
scheme: HTTP
initialDelaySeconds: 5
---
apiVersion: v1 #需要两个service
kind: Service
metadata:
name: spring-boot-helloworld #稳定版service
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: spring-boot-helloworld
---
apiVersion: v1
kind: Service
metadata:
name: spring-boot-helloworld-canary #给canary使用的service
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: spring-boot-helloworld #使用相同的标签选择器,但rollouts会自动添加另外的标签选择器
--- 各自只能承载到不同的版本pod上去
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-boot-helloworld
spec:
ingressClassName: "nginx"
rules:
- host: hello.magedu.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: spring-boot-helloworld
port:
number: 80
---
执行运行命令:kubectl apply -f 02-rollouts-with-ingress-nginx-traffic-shifting.yaml
查看运行的service,有两个
kubectl get svc
spring-boot-helloworld
spring-boot-helloworld-canary
查看spring-boot-helloworld,会发现自动增添标签选择器的条件,pod的配置改变,其hash值也会改变
kubectl get svc spring-boot-helloworld -o yaml
此时,访问哪一个service都是一样的,一旦启动更新,这两个service就不一样了
查看ingress
kubectl get ingress
查看相关的ingress的详情,活得host信息,并进行解析
在集群外部的客户端上建立持续访问请求
while true; do curl hello.magedu.com/version; sleep 0.$[$RANDOM%10]; done
此时一直是0.9.2的版本

启动更新操作
kubectl get rollouts
NAME
rollouts-helloworld-with-traffic-shifting
把rollouts-helloworld-with-traffic-shifting pod中的容器的镜像进行修改
kubectl rollouts set image rollouts-helloworld-with-traffic-shifting spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.9.3
查看图形页面更行情况

命令行进行持续访问查看流量调度情况