
对生产环境进行应用升级的时候,需要稳妥小心,尽可能避免对业务连续性造成影响。
如果应用代码做了比较大的修改,对新版本心里不太有底,那么渐进式部署就是一种更好的选择。
保留原来的稳定版本,把新版本一起部署上去,一开始先分配少数的用户流量到新版本上面,大部分用户还在使用原来的稳定版本。观察一下,看看有没有问题,有问题就赶紧全部切回去。没问题的话,就把更多的用户流量切到新版本上面,一步步增大新版本的流量,直到把所有的流量都切到新版本上面,最后所有的用户都开始使用新版本。这种部署方式叫金丝雀部署。
金丝雀部署是一种非常小心谨慎的应用升级方式,能够尽量减少对业务的影响。
操作系统 Debian 12,Kubernetes 1.28.4,argo rollouts 1.6.6。
一、安装软件
在Kubernetes集群的master主机上,运行下列命令,安装argo rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
运行下列命令,安装kubectl插件
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
kubectl argo rollouts version
二、使用案例
用nginx升级作为案例,把nginx从1.24升级到1.25.2。
1.部署原有的稳定版本
新建文件rollouts.yaml,内容如下
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-test
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {}
- setWeight: 40
- pause: {duration: 10}
- setWeight: 60
- pause: {duration: 10}
- setWeight: 80
- pause: {duration: 10}
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollouts-test
template:
metadata:
labels:
app: rollouts-test
spec:
containers:
- name: rollouts-test
image: atomhub.openatom.cn/library/nginx:1.24
ports:
- name: http
containerPort: 80
protocol: TCP
新建文件service.yaml,内容如下
apiVersion: v1
kind: Service
metadata:
name: rollouts-test
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollouts-test
运行
kubectl apply -f rollouts.yaml -f service.yaml
把nginx1.24和service部署上去。
运行
kubectl argo rollouts get rollout rollouts-test
输出类似下面
Name: rollouts-test
Namespace: default
Status: ✔ Healthy
Strategy: Canary
Step: 8/8
SetWeight: 100
ActualWeight: 100
Images: atomhub.openatom.cn/library/nginx:1.24 (stable)
Replicas:
Desired: 5
Current: 5
Updated: 5
Ready: 5
Available: 5
NAME KIND STATUS AGE INFO
⟳ rollouts-test Rollout ✔ Healthy 4m2s
└──# revision:1
└──⧉ rollouts-test-65bffdb987 ReplicaSet ✔ Healthy 4m2s stable
├──□ rollouts-test-65bffdb987-26sdl Pod ✔ Running 4m1s ready:1/1
├──□ rollouts-test-65bffdb987-kqhg6 Pod ✔ Running 4m1s ready:1/1
├──□ rollouts-test-65bffdb987-qnt2b Pod ✔ Running 4m1s ready:1/1
├──□ rollouts-test-65bffdb987-tbwtg Pod ✔ Running 4m1s ready:1/1
└──□ rollouts-test-65bffdb987-vn5d2 Pod ✔ Running 4m1s ready:1/1
可以看到nginx1.24,有5个pod正常运行。
2. 部署新版本
运行
kubectl argo rollouts set image rollouts-test rollouts-test=atomhub.openatom.cn/library/nginx:1.25.2
把nginx1.25.2同时部署上去。
运行
kubectl argo rollouts get rollout rollouts-test
可以看到当前应用的容器部署情况。输出类似下面
Name: rollouts-test
Namespace: default
Status: ॥ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 1/8
SetWeight: 20
ActualWeight: 20
Images: atomhub.openatom.cn/library/nginx:1.24 (stable)
atomhub.openatom.cn/library/nginx:1.25.2 (canary)
Replicas:
Desired: 5
Current: 5
Updated: 1
Ready: 5
Available: 5
NAME KIND STATUS AGE INFO
⟳ rollouts-test Rollout ॥ Paused 5m7s
├──# revision:2
│ └──⧉ rollouts-test-568854f959 ReplicaSet ✔ Healthy 27s canary
│ └──□ rollouts-test-568854f959-r4ncj Pod ✔ Running 27s ready:1/1
└──# revision:1
└──⧉ rollouts-test-65bffdb987 ReplicaSet ✔ Healthy 5m7s stable
├──□ rollouts-test-65bffdb987-26sdl Pod ✔ Running 5m6s ready:1/1
├──□ rollouts-test-65bffdb987-kqhg6 Pod ✔ Running 5m6s ready:1/1
├──□ rollouts-test-65bffdb987-qnt2b Pod ✔ Running 5m6s ready:1/1
└──□ rollouts-test-65bffdb987-tbwtg Pod ✔ Running 5m6s ready:1/1
现在nginx1.24有4个pod,nginx1.25.2有1个pod,用户流量从service rollouts-test进来以后,平均分配到各个pod上面,所以nginx1.25.2得到了20%的用户流量。
现在可以对应用进行测试,看看是否运行正常。
3. 增加新版本的流量比例
如果测试没有问题,运行
kubectl argo rollouts promote rollouts-test
继续部署过程。
运行
kubectl argo rollouts get rollout rollouts-test --watch
进行观察。
根据rollouts.yaml的定义,每隔10秒钟,nginx1.24的pod数量就会减少1个,nginx1.25.2的pod数量会增加一个,nginx1.25.2上面的用户流量从20%增加到40%,再变成60%,80%,最后变成100%。
如果接下来运行正常,这个过程就结束了,金丝雀部署就此完成,nginx从1.24顺利升级到了1.25.2。
4. 中断升级,回退到老版本
在部署过程中,如果发现新版本运行出现问题,可以运行
kubectl argo rollouts abort rollouts-test
中断部署。
nginx1.24的pod又会变成5个,nginx1.25.2的pod消失,所有的用户流量会回到nginx1.24上面。
如果应用升级已经完成,所有的用户流量都已经到了nginx1.25.2上面,这个时候才发现新版本出现问题。可以运行
kubectl argo rollouts undo rollouts-test
进行回滚,所有的用户流量又会回到nginx1.24上面。
参考:
https://argo-rollouts.readthedocs.io/en/stable/installation
https://argo-rollouts.readthedocs.io/en/stable/getting-started