对生产环境进行应用升级的时候,需要稳妥小心,尽可能避免对业务连续性造成影响。

如果应用代码做了比较大的修改,对新版本心里不太有底,那么渐进式部署就是一种更好的选择。

保留原来的稳定版本,把新版本一起部署上去,一开始先分配少数的用户流量到新版本上面,大部分用户还在使用原来的稳定版本。观察一下,看看有没有问题,有问题就赶紧全部切回去。没问题的话,就把更多的用户流量切到新版本上面,一步步增大新版本的流量,直到把所有的流量都切到新版本上面,最后所有的用户都开始使用新版本。这种部署方式叫金丝雀部署。

金丝雀部署是一种非常小心谨慎的应用升级方式,能够尽量减少对业务的影响。

操作系统 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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注