Day17-ArgoCD-图34

三、实战练习

登录http://gitlab.example.com/,账号为

root,密码为<gitlab-password>。登录成功后,参考前面内容创建名为Argocd Example Apps的项目,标识字符串为argocd-example-apps

image-20250424175412664

创建一个 Rollout 资源和一个针对该资源的 Kubernetes Service 对象,这里的 Rollout 采用了蓝绿部署:

[root@master01 ~]# cd /root/17/argo-rollouts

[root@master01 argo-rollouts]# mkdir -p argorollout-examples/bluegreen

[root@master01 argo-rollouts]# cd argorollout-examples/bluegreen

[root@master01 bluegreen]# vim rollout.yaml

apiVersion: argoproj.io/v1alpha1

kind: Rollout

metadata:

  name: newapp-rollout-0902

  namespace: demo

spec:

  replicas: 3

  strategy:

    blueGreen:     

      activeService: bluegreen-appv1

      previewService: bluegreen-appv2  

      autoPromotionEnabled: false

  revisionHistoryLimit: 2

  selector:

    matchLabels:

      app: web-app

  template:

    metadata:

      labels:

        app: web-app

    spec:

      containers:

      - name: web

        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/kubernetes-bootcamp:v1

        ports:

        - name: http

          containerPort: 8080

          protocol: TCP

web-app 应用的 appv1-svc:

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples/bluegreen

[root@master01 bluegreen]# vim web-app-appv1.yaml

apiVersion: v1

kind: Service

metadata:

  name: bluegreen-appv1

  namespace: demo

spec:

  selector:

    app: web-app

  ports:

  - port: 8080

    protocol: TCP

    targetPort: 8080

web-app 应用的 appv2-svc:

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples/bluegreen

[root@master01 bluegreen]# vim web-app-appv2.yaml

apiVersion: v1

kind: Service

metadata:

  name: bluegreen-appv2

  namespace: demo

spec:

  selector:

    app: web-app

  ports:

  - port: 8080

    protocol: TCP

    targetPort: 8080

把上述3个文件放入代码仓库 http://gitlab.example.com/demoteam/argocd-example-apps.git的argorollout-examples/bluegreen 目录下

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# git init

# 添加远端仓库

[root@master01 argorollout-examples]# git remote add origin http://gitlab.example.com/demoteam/argocd-example-apps.git

# 验证查看

[root@master01 argorollout-examples]# git remote -v

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (fetch)

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (push)

# 添加到暂存区

[root@master01 argorollout-examples]# git add .

# 提交到本地仓库

[root@master01 argorollout-examples]# git commit -m "first for argocd-example-apps"

# 切换到main分支

[root@master01 argorollout-examples]# git branch -M main

# 上传到main分支

[root@master01 argorollout-examples]# git push -uf origin main

Username for 'http://gitlab.example.com': root

Password for 'http://root@gitlab.example.com': <gitlab-password>

image-20250422130724122

添加gitlab仓库

# 先使用初始密码登录

[root@master01 17]# argocd login argocd.example.com

Username: admin

Password: <new-admin-password>

# 添加前需要保证私有gitlab仓库不为空

[root@master01 argo-rollouts]# argocd repo add http://gitlab.example.com/demoteam/argocd-example-apps.git  --username root --password <gitlab-password> --insecure-skip-server-verification 

# 验证查看

[root@master01 argorollout-examples]# argocd repo list | grep argocd-example-apps

git         http://gitlab.example.com/demoteam/argocd-example-apps.git  true      false  false  true   Successful 

后续在 Argo CD 上使用 YAML 资源清单创建服务:

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# vim argorollout-blue-green.yaml

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

  name: argorollout-blue-green

  namespace: argocd

spec:

  destination:

    name: ''

    namespace: demo

    server: 'https://kubernetes.default.svc'

  source:

    path: bluegreen

    repoURL: 'http://gitlab.example.com/demoteam/argocd-example-apps.git'

    targetRevision: main

  sources: []

  project: default

# 应用  

[root@master01 argorollout-examples]# kubectl apply -f argorollout-blue-green.yaml

最终目录文件结构:

[root@master01 argorollout-examples]# tree ../argorollout-examples/

../argorollout-examples/

├── argorollout-blue-green.yaml

└── bluegreen

    ├── rollout.yaml

    ├── web-app-appv1.yaml

    └── web-app-appv2.yaml

1 directory, 4 files

web页面手动实现同步

依次点击【SYNC】-【SYNCHEONIZE】

image-20250424184532326

image-20250424184557256

web 页面查看状态:

Day17-ArgoCD-图35

查看网络流向:

Day17-ArgoCD-图36

Argo Rollouts 查看服务:

# 查看服务

[root@master01 argorollout-examples]# kubectl argo rollouts list rollouts -ndemo

NAME                 STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE

newapp-rollout-0902  BlueGreen  Healthy       -     -           3/3    3        3           3        

# 查看节点状态

[root@master01 argorollout-examples]# kubectl argo rollouts status newapp-rollout-0902 -ndemo

Healthy

获取滚动更新的信息:

[root@master01 argorollout-examples]# kubectl argo rollouts get rollout newapp-rollout-0902 -ndemo

Name:            newapp-rollout-0902

Namespace:       demo

Status:           Healthy

Strategy:        BlueGreen

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable, active)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                            KIND        STATUS     AGE    INFO

⟳ newapp-rollout-0902                           Rollout      Healthy  2m33s  

└──# revision:1                                                               

   └──⧉ newapp-rollout-0902-746fbdc85           ReplicaSet   Healthy  2m33s  stable,active

      ├──□ newapp-rollout-0902-746fbdc85-h77np  Pod          Running  2m33s  ready:1/1

      ├──□ newapp-rollout-0902-746fbdc85-kvn98  Pod          Running  2m33s  ready:1/1

      └──□ newapp-rollout-0902-746fbdc85-md5j7  Pod          Running  2m33s  ready:1/1

测试验证:均为 v1 版本

# 查看服务

[root@master01 argorollout-examples]# kgs -ndemo | grep bluegreen

bluegreen-appv1   ClusterIP   <cluster-ip>    <none>        8080/TCP   10m

bluegreen-appv2   ClusterIP   <cluster-ip>     <none>        8080/TCP   10m

# 查看bluegreen-appv1对应的版本为v1

[root@master01 argorollout-examples]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: newapp-rollout-0902-746fbdc85-kvn98 | v=1

# 查看bluegreen-appv2对应的版本为v1

[root@master01 argorollout-examples]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: newapp-rollout-0902-746fbdc85-kvn98 | v=1

更新镜像:

1)更新 git 仓库配置文件,修改镜像版本从 v1 --> v2

2)通过命令行的方式更新:

  • 更新镜像
#语法格式

kubectl argo rollouts set image ROLLOUT_NAME CONTAINER=IMAGE [flags]

# 实际替换镜像为v2

[root@master01 argorollout-examples]# kubectl argo rollouts set image newapp-rollout-0902 web=registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 -ndemo
  • 动态观察服务切换信息
[root@master01 argorollout-examples]# kubectl argo rollouts get rollout newapp-rollout-0902 -ndemo --watch

Name:            newapp-rollout-0902

Namespace:       demo

Status:           Paused

Message:         BlueGreenPause

Strategy:        BlueGreen

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable, active)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (preview)

Replicas:

  Desired:       3

  Current:       6

  Updated:       3

  Ready:         3

  Available:     3

NAME                                             KIND        STATUS     AGE  INFO

⟳ newapp-rollout-0902                            Rollout      Paused   12m  

├──# revision:2                                                                └──⧉ newapp-rollout-0902-7466b89448           ReplicaSet   Healthy  41s  preview

│     ├──□ newapp-rollout-0902-7466b89448-75x4s  Pod          Running  41s  ready:1/1

│     ├──□ newapp-rollout-0902-7466b89448-8wh8l  Pod          Running  41s  ready:1/1

│     └──□ newapp-rollout-0902-7466b89448-nn84z  Pod          Running  41s  ready:1/1

└──# revision:1                                                              

   └──⧉ newapp-rollout-0902-746fbdc85            ReplicaSet   Healthy  12m  stable,active

      ├──□ newapp-rollout-0902-746fbdc85-h77np   Pod          Running  12m  ready:1/1

      ├──□ newapp-rollout-0902-746fbdc85-kvn98   Pod          Running  12m  ready:1/1

      └──□ newapp-rollout-0902-746fbdc85-md5j7   Pod          Running  12m  ready:1/1
  • 手动执行版本切换
# 手动进行切换,等待大概10s后,v1版本的pod会被删除

[root@master01 argorollout-examples]# kubectl argo rollouts promote newapp-rollout-0902 -ndemo

# 实时查看,观察到目前只剩下v2版本的pod

[root@master01 argorollout-examples]# kubectl argo rollouts get rollout newapp-rollout-0902 -ndemo --watch

Name:            newapp-rollout-0902

Namespace:       demo

Status:           Healthy

Strategy:        BlueGreen

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (stable, active)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                             KIND        STATUS        AGE    INFO

⟳ newapp-rollout-0902                            Rollout      Healthy     18m    

├──# revision:2                                                                     └──⧉ newapp-rollout-0902-7466b89448           ReplicaSet   Healthy     6m55s  stable,active

│     ├──□ newapp-rollout-0902-7466b89448-75x4s  Pod          Running     6m55s  ready:1/1

│     ├──□ newapp-rollout-0902-7466b89448-8wh8l  Pod          Running     6m55s  ready:1/1

│     └──□ newapp-rollout-0902-7466b89448-nn84z  Pod          Running     6m55s  ready:1/1

└──# revision:1                                                                   

   └──⧉ newapp-rollout-0902-746fbdc85            ReplicaSet   ScaledDown  18m    

Day17-ArgoCD-图37

测试验证:均为 v2 版本

# 查看服务

[root@master01 argorollout-examples]# kgs -ndemo | grep blue

bluegreen-appv1   ClusterIP   <cluster-ip>    <none>        8080/TCP   19m

bluegreen-appv2   ClusterIP   <cluster-ip>     <none>        8080/TCP   19m

# 测试访问v1

[root@master01 argorollout-examples]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: newapp-rollout-0902-7466b89448-nn84z | v=2

# 测试访问v2

[root@master01 argorollout-examples]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: newapp-rollout-0902-7466b89448-nn84z | v=2

浏览器中输入http://argorollouts.example.com/,打开argorollouts Dashboard 界面

Day17-ArgoCD-图38

如何中断 Rollout ?

在生产过程中,如果新版本部署后测试有问题,如何在更新过程中手动中止 Rollout ?

首先,使用 set image 命令部署一个新的 V1 版本的容器,并等待 rollout 再次达到暂停的步骤。

[root@master01 ~]# kubectl argo rollouts set image newapp-rollout-0902 web=registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 -ndemo

查看验证:

[root@master01 ~]# kubectl argo rollouts get rollout newapp-rollout-0902 -ndemo --watch

中止更新,而不是将滚动切换到下一步,这样它就回到了 V2 版本,该插件同样提供了一个 abort 命令,可以在更新过程中的任何时候手动中止 Rollout 。

[root@master01 ~]# kubectl argo rollouts abort newapp-rollout-0902 -ndemo

当中止滚动时,它将扩大 ReplicaSet 的 stable 版本(在本例中是 V2 版本),并缩小任何其他版本。

尽管 ReplicaSet 的稳定版本可能正在运行,并且是健康的,但整个 Rollout 仍然被认为是退化的,因为期望的版本( V1 版本)不是实际运行的版本。

[root@master01 ~]# kubectl argo rollouts get rollout newapp-rollout-0902 -ndemo

Name:            newapp-rollout-0902

Namespace:       demo

Status:           Degraded

Message:         RolloutAborted: Rollout aborted update to revision 3

Strategy:        BlueGreen

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (preview)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (stable, active)

Replicas:

  Desired:       3

  Current:       6

  Updated:       3

  Ready:         3

  Available:     3

NAME                                             KIND        STATUS      AGE    INFO

⟳ newapp-rollout-0902                            Rollout      Degraded  32m    

├──# revision:3                                                                   └──⧉ newapp-rollout-0902-746fbdc85            ReplicaSet   Healthy   32m    preview,delay:1s

│     ├──□ newapp-rollout-0902-746fbdc85-44hq9   Pod          Running   3m47s  ready:1/1

│     ├──□ newapp-rollout-0902-746fbdc85-sz5rv   Pod          Running   3m47s  ready:1/1

│     └──□ newapp-rollout-0902-746fbdc85-z7cj4   Pod          Running   3m47s  ready:1/1

└──# revision:2                                                                 

   └──⧉ newapp-rollout-0902-7466b89448           ReplicaSet   Healthy   21m    stable,active

      ├──□ newapp-rollout-0902-7466b89448-75x4s  Pod          Running   21m    ready:1/1

      ├──□ newapp-rollout-0902-7466b89448-8wh8l  Pod          Running   21m    ready:1/1

      └──□ newapp-rollout-0902-7466b89448-nn84z  Pod          Running   21m    ready:1/1

模拟测试访问,发现实际访问的版本为v2,但是用户实际想访问的是v1

[root@master01 ~]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: newapp-rollout-0902-7466b89448-8wh8l | v=2

[root@master01 ~]# curl <cluster-ip>:8080

curl: (7) Failed connect to <cluster-ip>:8080; Connection refused

四、基于ArgoCD的金丝雀部署

4.1 传统金丝雀(灰度)流程

Day17-ArgoCD-图39

4.2 ArgoRollout 金丝雀(灰度)流程

实现原理:

金丝雀发布是一种部署新版本应用的方法,其中 新版本 先部署给一小部分用户,如果一切正常,则逐渐增加新版本的流量,直到完全替换旧版本。

Day17-ArgoCD-图40

4.3 基于 Replica Shifting(版本替换) 金丝雀发布

4.3.1 部署 Rollout

创建数据目录

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# mkdir canary-replica

在数据目录中创建文件

[root@master01 argorollout-examples]# cd canary-replica/

[root@master01 canary-replica]# vim canary-rollout.yaml

apiVersion: argoproj.io/v1alpha1

kind: Rollout

metadata:

  name: canary-rollouts-demo

  namespace: demo

spec:

  replicas: 3 # 定义3个副本

  strategy: # 定义升级策略

    canary: # 金丝雀发布

      steps: # 发布的节奏

        - setWeight: 20

        - pause: {} # 会一直暂停,需要手动 promote

        - setWeight: 40

        - pause: { duration: 10 } # 暂停10s

        - setWeight: 60

        - pause: { duration: 10 }

        - setWeight: 80

        - pause: { duration: 10 }

  revisionHistoryLimit: 2 # 下面部分其实是和 Deployment 兼容的

  selector:

    matchLabels:

      app: rollouts-demo

  template:

    metadata:

      labels:

        app: rollouts-demo

    spec:

      containers:

        - name: rollouts-demo

          image: registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1

          ports:

            - name: http

              containerPort: 8080

              protocol: TCP

可以看到除了 apiVersion,kind 以及 strategy 之外,其他和 Deployment 无异。

strategy 字段定义的是发布策略,其中:

  • setWeight:设置流量的权重

  • pause:暂停,如果里面没有跟duration: 10则表示需要手动更新,如果跟了表示等待多长时间会自动更新。

4.3.2 定义 service

[root@master01 argorollout-examples]# cd canary-replica/

[root@master01 canary-replica]# vim canary-rollout-svc.yaml

apiVersion: v1

kind: Service

metadata:

  name: rollouts-demo

  namespace: demo

spec:

  ports:

  - port: 8080

    targetPort: http

    protocol: TCP

    name: http

  selector:

    app: rollouts-demo

4.3.3 创建 argorollout-canary-replica

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# vim argorollout-canary-replica.yaml

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

  name: argorollout-canary-replica

  namespace: argocd

spec:

  destination:

    name: ''

    namespace: demo

    server: 'https://kubernetes.default.svc'

  source:

    path: canary-replica

    repoURL: 'http://gitlab.example.com/demoteam/argocd-example-apps.git'

    targetRevision: main

  sources: []

  project: default

把上述2个文件放入代码仓库 http://gitlab.example.com/demoteam/argocd-example-apps.git canary-replica 目录下,后续在 Argo CD 上使用 YAML 资源清单创建服务。

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# git init

# 添加远端仓库

[root@master01 argorollout-examples]# git remote add origin http://gitlab.example.com/demoteam/argocd-example-apps.git

# 验证查看

[root@master01 argorollout-examples]# git remote -v

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (fetch)

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (push)

# 添加到暂存区

[root@master01 argorollout-examples]# git add .

# 提交到本地仓库

[root@master01 argorollout-examples]# git commit -m "first for argocd-example-apps"

# 切换到main分支

[root@master01 argorollout-examples]# git branch -M main

# 上传到main分支

[root@master01 argorollout-examples]# git push -uf origin main

Username for 'http://gitlab.example.com': root

Password for 'http://root@gitlab.example.com': <gitlab-password>

创建相关资源

[root@master01 argorollout-examples]# kubectl apply -f argorollout-canary-replica.yaml

4.3.4 手动 sync

点击【SYNC】-【SYNCHRONIZE】进行手动同步

image-20250424192949584

底层命令观察:

# 查看回滚列表

[root@master01 ~]# kubectl argo rollouts list rollouts -ndemo

NAME                  STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE

canary-rollouts-demo  Canary     Healthy       8/8   100         3/3    3        3           3        

newapp-rollout-0902   BlueGreen  Healthy       -     -           3/3    3        3           3       

# 获取滚动更新的信息

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-demo -ndemo

Name:            canary-rollouts-demo

Namespace:       demo

Status:           Healthy

Strategy:        Canary

  Step:          8/8

  SetWeight:     100

  ActualWeight:  100

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                             KIND        STATUS     AGE  INFO

⟳ canary-rollouts-demo                           Rollout      Healthy  63s  

└──# revision:1                                                              

   └──⧉ canary-rollouts-demo-d7975f98c           ReplicaSet   Healthy  63s  stable

      ├──□ canary-rollouts-demo-d7975f98c-sdsb8  Pod          Running  62s  ready:1/1

      ├──□ canary-rollouts-demo-d7975f98c-vlxr5  Pod          Running  62s  ready:1/1

      └──□ canary-rollouts-demo-d7975f98c-wkwlg  Pod          Running  62s  ready:1/1

打开浏览器输入http://argorollouts.example.com/打开argorollout dashboard,命名空间选择demo

Day17-ArgoCD-图42

4.3.5 更新 Rollout

先打开一个新的 xshell 窗口,便于动态观察:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-demo -ndemo --watch

# 初始页面

Name:            canary-rollouts-demo

Namespace:       demo

Status:           Healthy

Strategy:        Canary

  Step:          8/8

  SetWeight:     100

  ActualWeight:  100

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                             KIND        STATUS     AGE   INFO

⟳ canary-rollouts-demo                           Rollout      Healthy  5m3s  

└──# revision:1                                                               

   └──⧉ canary-rollouts-demo-d7975f98c           ReplicaSet   Healthy  5m3s  stable

      ├──□ canary-rollouts-demo-d7975f98c-sdsb8  Pod          Running  5m2s  ready:1/1

      ├──□ canary-rollouts-demo-d7975f98c-vlxr5  Pod          Running  5m2s  ready:1/1

      └──□ canary-rollouts-demo-d7975f98c-wkwlg  Pod          Running  5m2s  ready:1/1

使用 set image 的命令更新:

[root@master01 ~]# kubectl argo rollouts set image canary-rollouts-demo rollouts-demo=registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 -ndemo

动态观察数据:

Name:            canary-rollouts-demo

Namespace:       demo

Status:          ॥ Paused #暂停,等待进一步promote

Message:         CanaryPauseStep

Strategy:        Canary

  Step:          1/8

  SetWeight:     20

  ActualWeight:  25

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (canary)

Replicas:

  Desired:       3

  Current:       4

  Updated:       1

  Ready:         4

  Available:     4

NAME                                              KIND        STATUS     AGE    INFO

⟳ canary-rollouts-demo                            Rollout     ॥ Paused   5m50s  

├──# revision:2                                                                 

│  └──⧉ canary-rollouts-demo-68bfb5ccbb           ReplicaSet  ✔ Healthy  15s    canary # 版本被标记为canary

│     └──□ canary-rollouts-demo-68bfb5ccbb-zhh74  Pod         ✔ Running  15s    ready:1/1

└──# revision:1                                                                 

   └──⧉ canary-rollouts-demo-d7975f98c            ReplicaSet  ✔ Healthy  5m50s  stable

      ├──□ canary-rollouts-demo-d7975f98c-sdsb8   Pod         ✔ Running  5m49s  ready:1/1

      ├──□ canary-rollouts-demo-d7975f98c-vlxr5   Pod         ✔ Running  5m49s  ready:1/1

      └──□ canary-rollouts-demo-d7975f98c-wkwlg   Pod         ✔ Running  5m49s  ready:1/1

当 demo rollout 到达第二步时,我们可以从插件中看到,Rollout 处于暂停状态,现在有 4 个副本中的1 个运行新版本的 pod,其余 3 个仍然运行旧版本,这相当于 setWeight: 20 步骤所定义的 20% 的金丝雀权重。

4.3.6 Promote Rollout

Rollout 现在处于暂停状态,要手动将 Rollout 切换到下一个步骤,运行插件的 promote 命令。

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-demo -ndemo

然后,每隔 10s 进行 v2 版本的逐步替换,最后全部替换为 v2 版本:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-demo -ndemo

Name:            canary-rollouts-demo

Namespace:       demo

Status:           Healthy

Strategy:        Canary

  Step:          8/8

  SetWeight:     100

  ActualWeight:  100

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (stable)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                              KIND        STATUS         AGE    INFO

⟳ canary-rollouts-demo                            Rollout      Healthy      9m21s  

├──# revision:2                                                                       └──⧉ canary-rollouts-demo-68bfb5ccbb           ReplicaSet   Healthy      3m46s  stable

│     ├──□ canary-rollouts-demo-68bfb5ccbb-zhh74  Pod          Running      3m46s  ready:1/1

│     ├──□ canary-rollouts-demo-68bfb5ccbb-n956r  Pod          Running      33s    ready:1/1

│     └──□ canary-rollouts-demo-68bfb5ccbb-mb4fc  Pod          Running      22s    ready:1/1

└──# revision:1                                                                     

   └──⧉ canary-rollouts-demo-d7975f98c            ReplicaSet   ScaledDown   9m21s  

      └──□ canary-rollouts-demo-d7975f98c-wkwlg   Pod          Terminating  9m20s  ready:1/1

也可以底层 svc 访问验证:

# 查看svc地址为<cluster-ip>

[root@master01 argorollout-examples]# kgs -ndemo | grep rollouts-demo

rollouts-demo     ClusterIP   <cluster-ip>   <none>        8080/TCP   2d4h

# 测试访问服务,目前版本变为v2

[root@master01 ~]# curl <cluster-ip>:8080

Hello Kubernetes bootcamp! | Running on: canary-rollouts-demo-68bfb5ccbb-mb4fc | v=2

4.4 基于 Traffic Shifting(流量接入) 金丝雀发布

官方数据:https://argoproj.github.io/argo-rollouts/features/traffic-management/nginx/

上面我们并没有接入外部流量,仅仅是在内部使用展示了金丝雀部署过程,下面我们接入外部流量进行测试。

Argo-Rollout 主要集成了 IngressServiceMesh 两种流量控制方法。

主要 Ingress 支持:(主要使用 Nginx-Ingress)

4.4.1 创建 Rollout

Rollout 里用 canaryService 和 stableService 分别定义了该应用:

  • 灰度的 Service Name (rollouts-traffic-canary)

  • 当前版本的 Service Name (rollouts-traffic-stable)

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# mkdir canary-traffic

[root@master01 argorollout-examples]# cd canary-traffic

[root@master01 canary-traffic]# vim canary-rollout.yaml

apiVersion: argoproj.io/v1alpha1

kind: Rollout

metadata:

  name: canary-rollouts-traffic-demo

  namespace: demo

spec:

  replicas: 3

  strategy:

    canary:

      canaryService: rollouts-traffic-canary

      stableService: rollouts-traffic-stable

      trafficRouting:

        nginx:

          stableIngress: rollouts-traffic-stable

      # 发布的节奏

      steps:

      - setWeight: 30

      # 会一直暂停

      - pause: {}

      - setWeight: 60

      - pause: {}

      - setWeight: 100

      - pause: {}

  revisionHistoryLimit: 2

  selector:

    matchLabels:

      app: rollouts-traffic-demo

  template:

    metadata:

      labels:

        app: rollouts-traffic-demo

    spec:

      containers:

      - name: rollouts-traffic-demo

        image: registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1

        ports:

        - name: http

          containerPort: 8080

          protocol: TCP

        resources:

          requests:

            memory: 512Mi

            cpu: 512m

4.4.2 创建应用的 stable/canary SVC

Service rollouts-traffic-canary 和 rollouts-traffic-stable,二者内容一样。selector 中暂时没有填上pod-template-hash。

Argo-Rollout Controller 会根据实际的 ReplicaSet hash 来修改该值:

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples/canary-traffic

[root@master01 canary-traffic]# vim rollouts-traffic-stable-canary.yaml

apiVersion: v1

kind: Service

metadata:

  name: rollouts-traffic-canary

  namespace: demo

spec:

  ports:

  - port: 8080

    targetPort: http

    protocol: TCP

    name: http

  selector:

    app: rollouts-traffic-demo

    # This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:

    # rollouts-pod-template-hash: 7bf84f9696

---

apiVersion: v1

kind: Service

metadata:

  name: rollouts-traffic-stable

  namespace: demo

spec:

  ports:

  - port: 8080

    targetPort: http

    protocol: TCP

    name: http

  selector:

    app: rollouts-traffic-demo

4.4.3 创建应用的 ingress 路由

Ingress 则定义了规则,nginx 将 canary.example.com 域名的请求转发到当前版本的 Service(rollouts-traffic-stable)

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples/canary-traffic

[root@master01 canary-traffic]# vim canary-traffic-ing.yaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  name: rollouts-traffic-stable

  namespace: demo

spec:

  ingressClassName: nginx

  rules:

  - host: canary.example.com

    http:

      paths:

      - backend:

          service:

            name: rollouts-traffic-stable

            port:

              number: 8080

        path: /

        pathType: Prefix

4.4.4 创建 APP

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# vim argorollout-canary-traffic.yaml

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

  name: argorollout-canary-traffic

  namespace: argocd

spec:

  destination:

    name: ''

    namespace: default

    server: 'https://kubernetes.default.svc'

  source:

    path: canary-traffic

    repoURL: 'http://gitlab.example.com/demoteam/argocd-example-apps.git'

    targetRevision: main

  sources: []

  project: default

把上述 3 个文件放入代码仓库 http://gitlab.example.com/demoteam/argocd-example-apps.git canary-traffic 目录下,后续在 Argo CD 上使用 YAML 资源清单创建服务。

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

# 初始化

[root@master01 argorollout-examples]# git init

# 添加远端仓库

[root@master01 argocd]# git remote add origin http://gitlab.example.com/demoteam/argocd-example-apps.git

# 验证查看

[root@master01 argorollout-examples]# git remote -v

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (fetch)

origin  http://gitlab.example.com/demoteam/argocd-example-apps.git (push)

# 添加到暂存区

[root@master01 argorollout-examples]# git add .

# 提交到本地仓库

[root@master01 argorollout-examples]# git commit -m "second for argorollout-examples"

# 切换到main分支

[root@master01 argorollout-examples]# git branch -M main

# 上传到main分支

[root@master01 argorollout-examples]# git push -uf origin main

Username for 'http://gitlab.example.com': root

Password for 'http://root@gitlab.example.com': <gitlab-password>

...

...

gitlab页面查看

image-20250424200006890

应用创建

[root@master01 ~]# cd /root/17/argo-rollouts/argorollout-examples

[root@master01 argorollout-examples]# kubectl apply -f argorollout-canary-traffic.yaml

WEB UI 手动同步:

点击【SYNC】-【SYNCHRONIZE】

Day17-ArgoCD-图43

traffic 流向:

Day17-ArgoCD-图44

4.4.5 Canary Ingress

Rollout Controller 会根据 ingress rollouts-traffic-stable 内容,自动创建一个 ingress 用于灰度的流量,名字为 --canary,

所以这里多了一个 ingress canary-rollouts-traffic-demo-rollouts-traffic-stable-canary,将流量导向Canary Service (rollouts-traffic-canary):

[root@master01 ~]# kubectl get ing -ndemo | grep canary

canary-rollouts-traffic-demo-rollouts-traffic-stable-canary   nginx   canary.example.com   <node-ip>   80      8m36s

rollouts-traffic-stable                                       nginx   canary.example.com   <node-ip>   80      8m39s

4.4.6 触发更新

[root@master01 ~]# kubectl argo rollouts set image canary-rollouts-traffic-demo rollouts-traffic-demo=registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 -ndemo

动态观察,第一步:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-traffic-demo -ndemo --watch

# 回显内容

Name:            canary-rollouts-traffic-demo

Namespace:       demo

Status:           Paused

Message:         CanaryPauseStep

Strategy:        Canary

  Step:          1/6

  SetWeight:     30  #权重比例

  ActualWeight:  30  #权重比例

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (canary)

Replicas:

  Desired:       3

  Current:       4

  Updated:       1

  Ready:         4

  Available:     4

NAME                                                      KIND        STATUS     AGE    INFO

⟳ canary-rollouts-traffic-demo                            Rollout      Paused   12m    

├──# revision:2                                                                           └──⧉ canary-rollouts-traffic-demo-69f4dd6c8            ReplicaSet   Healthy  2m27s  canary

│     └──□ canary-rollouts-traffic-demo-69f4dd6c8-f5bqd   Pod          Running  2m27s  ready:1/1

└──# revision:1                                                                         

   └──⧉ canary-rollouts-traffic-demo-5c8c98d57f           ReplicaSet   Healthy  12m    stable

      ├──□ canary-rollouts-traffic-demo-5c8c98d57f-6fwcj  Pod          Running  12m    ready:1/1

      ├──□ canary-rollouts-traffic-demo-5c8c98d57f-jbqcv  Pod          Running  12m    ready:1/1

      └──□ canary-rollouts-traffic-demo-5c8c98d57f-mrqmx  Pod          Running  12m    ready:1/1

Day17-ArgoCD-图45

curl 命令测试:

# 目前v2的权重占30%

[root@master01 ~]# for i in {1..10}; do curl canary.example.com; done

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-6fwcj | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-jbqcv | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-mrqmx | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-6fwcj | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-6fwcj | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-f5bqd | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-jbqcv | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-mrqmx | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-jbqcv | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-jbqcv | v=1

因为配置文件中 pause: {} ,需要在命令行手动执行灰度发布,命令执行完成后就能达到 60% 灰度

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

再次查看 滚动更新状态:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-traffic-demo -ndemo --watch

# 回显

Name:            canary-rollouts-traffic-demo

Namespace:       demo

Status:          ॥ Paused

Message:         CanaryPauseStep

Strategy:        Canary

  Step:          3/6

  SetWeight:     60 #权重比例

  ActualWeight:  60 #权重比例

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (canary)

Replicas:

  Desired:       3

  Current:       5

  Updated:       2

  Ready:         5

  Available:     5

查看 canary ingress 资源:

[root@master01 ~]# kgi -ndemo canary-rollouts-traffic-demo-rollouts-traffic-stable-canary -oyaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  annotations:

    nginx.ingress.kubernetes.io/canary: "true"

    nginx.ingress.kubernetes.io/canary-weight: "60"

  creationTimestamp: "2025-04-24T12:01:59Z"

  generation: 1

  name: canary-rollouts-traffic-demo-rollouts-traffic-stable-canary

  namespace: demo

  ownerReferences:

  - apiVersion: argoproj.io/v1alpha1

    blockOwnerDeletion: true

    controller: true

    kind: Rollout

    name: canary-rollouts-traffic-demo

    uid: a40a95e0-617a-4f40-b7ed-79f07e17cefa

  resourceVersion: "2571984"

  uid: 465ee9e2-71d1-45cb-92ad-ad1f5e7ffc27

spec:

  ingressClassName: nginx

  rules:

  - host: canary.example.com

    http:

      paths:

      - backend:

          service:

            name: rollouts-traffic-canary

            port:

              number: 8080

        path: /

        pathType: Prefix

status:

  loadBalancer:

    ingress:

    - ip: <node-ip>

继续执行命令完成 100% 的灰度流程:

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

再次查看滚动更新状态:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-traffic-demo -ndemo --watch

# 回显

Name:            canary-rollouts-traffic-demo

Namespace:       demo

Status:          ॥ Paused

Message:         CanaryPauseStep

Strategy:        Canary

  Step:          5/6

  SetWeight:     100

  ActualWeight:  100

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

                 registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (canary)

Replicas:

  Desired:       3

  Current:       6

  Updated:       3

  Ready:         6

  Available:     6

NAME                                                      KIND        STATUS     AGE    INFO

⟳ canary-rollouts-traffic-demo                            Rollout     ॥ Paused   16m    

├──# revision:2                                                                         

│  └──⧉ canary-rollouts-traffic-demo-69f4dd6c8            ReplicaSet  ✔ Healthy  6m29s  canary

│     ├──□ canary-rollouts-traffic-demo-69f4dd6c8-f5bqd   Pod         ✔ Running  6m29s  ready:1/1

│     ├──□ canary-rollouts-traffic-demo-69f4dd6c8-cw95h   Pod         ✔ Running  3m11s  ready:1/1

│     └──□ canary-rollouts-traffic-demo-69f4dd6c8-npwvj   Pod         ✔ Running  62s    ready:1/1

└──# revision:1                                                                         

   └──⧉ canary-rollouts-traffic-demo-5c8c98d57f           ReplicaSet  ✔ Healthy  16m    stable

      ├──□ canary-rollouts-traffic-demo-5c8c98d57f-6fwcj  Pod         ✔ Running  16m    ready:1/1

      ├──□ canary-rollouts-traffic-demo-5c8c98d57f-jbqcv  Pod         ✔ Running  16m    ready:1/1

      └──□ canary-rollouts-traffic-demo-5c8c98d57f-mrqmx  Pod         ✔ Running  16m    ready:1/1

打开浏览器输入http://argorollouts.example.com/查看 argorollouts dashboard:

Day17-ArgoCD-图46

浏览器输入https://argocd.example.com/打开argocd dashboard

Day17-ArgoCD-图47

完成金丝雀发布及销毁 v1 版本:

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

等待一小段时间,再次查看底层数据,观察到v1版本的pod删除,目前只剩下v2版本的pod

Name:            canary-rollouts-traffic-demo

Namespace:       demo

Status:           Healthy

Strategy:        Canary

  Step:          6/6

  SetWeight:     100

  ActualWeight:  100

Images:          registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (stable)

Replicas:

  Desired:       3

  Current:       3

  Updated:       3

  Ready:         3

  Available:     3

NAME                                                     KIND        STATUS        AGE    INFO

⟳ canary-rollouts-traffic-demo                           Rollout      Healthy     19m    

├──# revision:2                                                                             └──⧉ canary-rollouts-traffic-demo-69f4dd6c8           ReplicaSet   Healthy     9m44s  stable

│     ├──□ canary-rollouts-traffic-demo-69f4dd6c8-f5bqd  Pod          Running     9m44s  ready:1/1

│     ├──□ canary-rollouts-traffic-demo-69f4dd6c8-cw95h  Pod          Running     6m26s  ready:1/1

│     └──□ canary-rollouts-traffic-demo-69f4dd6c8-npwvj  Pod          Running     4m17s  ready:1/1

└──# revision:1                                                                           

   └──⧉ canary-rollouts-traffic-demo-5c8c98d57f          ReplicaSet   ScaledDown  19m    

Day17-ArgoCD-图48

curl 数据验证:

# 因为版本切换为v2,所以版本全为v2

[root@master01 ~]# for i in {1..10}; do curl canary.example.com; done

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-npwvj | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-f5bqd | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-cw95h | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-npwvj | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-f5bqd | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-f5bqd | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-cw95h | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-cw95h | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-cw95h | v=2

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-69f4dd6c8-npwvj | v=2

五、回退应用

5.1 命令行回退

有时候在应用上线过后,有些BUG并没有发现,这时候要回退怎么办呢?argo rollouts 有一个 undo 命令,可以进行回退。

比如我们要将版本回退到第一个版本,则执行一下命令:

[root@master01 ~]# kubectl argo rollouts undo canary-rollouts-demo -ndemo --to-revision=1

通过 watch 界面可以看到如下信息:

[root@master01 ~]# kubectl argo rollouts get rollout canary-rollouts-demo -ndemo

再次 promote 执行更多的 canary 过程:

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-demo -ndemo

最终数据:

Name: canary-rollouts-traffic-demo

Namespace: demo

Status: ॥ Paused

Message: CanaryPauseStep

Strategy: Canary

Step: 5/6

SetWeight: 100

ActualWeight: 100

Images:

  registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v1 (stable)

  registry.cn-hangzhou.aliyuncs.com/zhdya/kubernetes-bootcamp:v2 (canary)

Replicas:

  Desired: 3

  Current: 6

  Updated: 3

  Ready: 6

  Available: 6

5.2 argorollouts界面回退

浏览器中输入http://argorollouts.example.com/打开argorollouts界面后,点击【Rollback】

image-20250424202503016

依次执行promote直至完全回退到上个版本

# 第一次回退,此时权重比例变为60%

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

# 第二次回退,此时权重比例变为100%

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

# 第三次回退,删除现有版本的pod,完全回滚到上一个版本

[root@master01 ~]# kubectl argo rollouts promote canary-rollouts-traffic-demo -ndemo

# 等待一小段时间进行测试访问,目前全部为v1,回退成功

[root@master01 ~]# for i in {1..10}; do curl canary.example.com; done

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-bxz2c | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-95snl | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-bxz2c | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-95snl | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-8f9q2 | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-95snl | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-8f9q2 | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-8f9q2 | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-8f9q2 | v=1

Hello Kubernetes bootcamp! | Running on: canary-rollouts-traffic-demo-5c8c98d57f-8f9q2 | v=1

六、总结

Argo Rollout 可以认为是 Deployment 的扩展,增加了蓝绿发布和金丝雀发布策略配置,并且支持通过 自动测试实现服务发布或者回滚。此外,Argo Rollout 还提供了更精细的流量管理和监控能力,开发者 能够在部署过程中实施健康检查、A/B测试以及性能评估,从而确保新版本的稳定性和可靠性。