一、Argo Rollouts介绍

官方数据:https://argo-rollouts.readthedocs.io/en/stable/

Argo Rollouts 是 Argo 项目下的一个子项目,专门用于实现渐进式交付(Progressive Delivery)策略, 如蓝绿部署(Blue/Green)、金丝雀部署(Canary)等。它为 Kubernetes 提供了一种简单而强大的方 式来管理和自动化应用的部署流程,特别是在复杂的应用程序更新场景中。

1.1 主要特性

  • 蓝绿部署

  • 灰度发布

  • 细粒的,带权重的流量调度(traffic shifting)

  • 自动 rollback 和 promote

  • 手动管理

  • 可定制的 metric 查询和 kpi 分析

  • Ingress controller集成:Nginx,APISIX,Traefik

  • Service Mesh集成:Istio,Linkerd

  • Metric provider集成:Prometheus

1.2 工作原理

Argo 原理和 Deployment 差不多,只是加强 rollout 的策略和流量控制。

当 spec.template 发送变化时,Argo-Rollout 就会根据 spec.strategy 进行 rollout,通常会产生一个新的 ReplicaSet,逐步 scale down 之前的ReplicaSet 的 pod 数量。

1.3 渐进式交付(Progressive Delivery)

下图显示了 Argo Rollouts 的简单工作流程,它使用 Ingress Controller、Argo CD 进行可视化和 Prometheus 进行监控。

主要工作模式:

渐进式交付通常被描述为持续交付的演变,将 CI/CD 中的速度优势扩展到部署过程。通过将新版本限制在一部分用户,观察和分析正确的行为,然后逐渐增加更多的流量,同时不断验证其正确性。

Day17-ArgoCD-图30

1.4 Argo Rollouts 部署策略

Argo Rollouts 支持两种主要的渐进式交付策略:蓝绿发布(Blue/Green Deployment)和金丝雀发布 (Canary Deployment)

Blue/Green:

同时部署应用程序的新旧(蓝绿)版本。一个是当前正在使用的生产环境(蓝色),另一个是备用环境(绿色)。新版本部署到备用环境后,通过切换路由来实现流量的切换。

Canary:

金丝雀(canary)发布是一种更为精细的部署策略,它通过逐步将流量引入新版本来验证其稳定性和性能。新版本最初只服务于一小部分用户,随着验证的进行,逐渐增加新版本的流量比例。

Day17-ArgoCD-图31

1.5 Argo Rollouts 架构 & 组件

Day17-ArgoCD-图32

Argo Rollouts 架构组件:

  • Argo Rollout Controller

  • Rollout CRD

  • ReplicaSet

  • Ingress/Service

  • AnalysisTemplate/AnalysisRun

  • Metric providers

  • CLI/GUI 等组件构成

Argo Rollout Controller

  • 功能:负责监控和管理 Rollout 对象的状态,执行部署策略。

  • 用处:确保按照定义的策略逐步更新应用程序,实现蓝绿部署或金丝雀发布。

Rollout CRD (Custom Resource Definition)

  • 功能:定义了 Argo Rollouts 的自定义资源类型,用于描述应用程序的部署策略。

  • 用处:通过 YAML 文件配置 Rollout 对象,实现对部署过程的精细控制。

ReplicaSet

  • 功能:Kubernetes 中用于管理 Pod 副本数量的对象。

  • 用处:在 Argo Rollouts 中用于创建和管理新版本的 Pod 副本,逐步替换旧版本。

Ingress/Service

  • 功能:Ingress 用于管理外部访问集群内应用的规则,Service 用于定义集群内服务间的通信。

  • 用处:通过 Ingress 或 Service 实现流量路由,支持蓝绿或金丝雀发布时的流量控制。

AnalysisTemplate/AnalysisRun

  • 功能:AnalysisTemplate 定义了分析策略和度量标准,AnalysisRun 是执行分析的具体实例。

  • 用处:用于自动或手动验证新版本的健康状况和性能,决定是否继续推广或回滚。

Metric Providers

  • 功能:集成外部度量系统,如 Prometheus,用于收集和分析度量数据。

  • 用处:提供度量数据支持,帮助决策自动回滚或推广新版本。

CLI/GUI

  • 功能:命令行工具(CLI)用于交互式管理 Rollout 对象,图形用户界面(GUI)提供可视化操作体验。

  • 用处:便于用户手动干预部署过程,监控状态,执行回滚或推进部署。

二、安装配置 Argo Rollouts

2.1 安装环境

  • kubernetes版本:1.27.4;

  • kubectl 可访问 Kubernetes 集群

2.2 通过 yaml 文件安装

1)安装 argo-rollouts 的 controller 和 crd:

# 创建ns

[root@master01 17]# kubectl create namespace argo-rollouts

# 安装crd和controller

[root@master01 17]# kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

这里会创建一个名为 argo-rollouts 的命名空间,Argo Rollouts 控制器运行在下面。

[root@master01 17]# kubectl get pods -n argo-rollouts

2.3 通过 Argo CD 部署 Argo Rollouts(推荐)

2.3.1 部署

创建ns

[root@master01 17]# kubectl create namespace argo-rollouts

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

root,密码为<gitlab-password>。登录成功后,依次点击【群组】-【demoteam】

image-20250422101143705

点击【新建项目】-【创建空白项目】,添加项目名称为Argo Rollouts,项目标识串为argo-rollouts

image-20250422101220049

image-20250422101301596

取消勾选【使用自述文件初始化仓库】,点击【新建项目】

image-20250424162331748

在本地虚机创建 git 相关目录 argo-rollouts/argorollouts:

[root@master01 17]# mkdir -p argo-rollouts/argorollouts

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

[root@master01 argorollouts]# wget https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

# 修改镜像为国内镜像

[root@master01 argorollouts]# sed -i s#quay.io/argoproj/argo-rollouts:latest#registry.cn-hangzhou.aliyuncs.com/github_images1024/argo-rollouts:latest#g install.yaml

# 验证查看

[root@master01 argorollouts]# grep -ri "image: re" install.yaml 

      - image: registry.cn-hangzhou.aliyuncs.com/github_images1024/argo-rollouts:latest 

注意:使用 Argo CD YAML 资源清单创建 APP 服务,首先我们需要先 删除 上面创建的 argo-rollouts 服务

推送本地文件到私仓gitlab

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

[root@master01 argorollouts]# git init

[root@master01 argorollouts]# git remote add origin http://gitlab.example.com/demoteam/argo-rollouts.git

[root@master01 argorollouts]# git add .

[root@master01 argorollouts]# git commit -m "add new argo rollout"

[root@master01 argorollouts]# git branch -M main

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

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

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

先添加如上 gitlab 仓库(私有仓库),到 argocd 的 repo 中,不然遇到错误:

Failed to load target state: failed to generate manifest for source 1 of 1: rpc error: code = Unknown desc = authentication required

添加私有 gitlab 仓库到 argocd repo 中,记得需要先登录,再次添加:

# 先使用初始密码登录

[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/argo-rollouts.git --username root --password <gitlab-password> --insecure-skip-server-verification 

# 验证查看

[root@master01 argorollouts]# argocd repo list | grep argo-rollouts

git         http://gitlab.example.com/demoteam/argo-rollouts.git  true      false  false  true   Successful      

部署验证:

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

[root@master01 argo-rollouts]# vim argo-rollouts.yaml 

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

  name: argo-rollouts

  namespace: argocd

spec:

  destination:

    namespace: argo-rollouts

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

  source:

    repoURL: 'http://gitlab.example.com/demoteam/argo-rollouts.git'

    path: argorollouts

    targetRevision: main

  sources: []

  project: default

  syncPolicy:

    automated:

      prune: true

      selfHeal: true

    syncOptions:

      - CreateNamespace=true

# 应用

[root@master01 argo-rollouts]# kubectl apply -f argo-rollouts.yaml

# 查看applications

[root@master01 argorollouts]# kubectl -n argocd get applications | grep argo-rollouts

argo-rollouts            Synced        Healthy

# 查看pod

[root@master01 argorollouts]# kgp -n argo-rollouts

NAME                             READY   STATUS    RESTARTS   AGE

argo-rollouts-6d64b9f869-7l8cx   1/1     Running   0          9m44s

因为syncPolicy设置的是automated,所以会自动部署应用

image-20250422113009077

2.3.2 遇到的问题

问题描述:

当执行完kubectl apply -f argo-rollouts.yaml命令后,pod一直处于0/1

[root@master01 argorollouts]# kgp -n argo-rollouts

NAME                             READY   STATUS    RESTARTS   AGE

argo-rollouts-846cf74f8c-xvh5f   0/1     Running   0          9m44s

问题排查:

查看日志,显示使用的 Argo Rollouts 版本过旧,需要升级到兼容新 API 的版本

[root@master01 argo-rollouts]# k logs -f argo-rollouts-846cf74f8c-xvh5f  -n  argo-rollouts

...

...

ta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

time="2025-04-24T08:46:48Z" level=info msg="Waiting for controller's informer caches to sync"

E0424 08:46:50.331942       1 reflector.go:178] pkg/mod/k8s.io/client-go@v0.18.2/tools/cache/reflector.go:125: Failed to list *v1beta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

E0424 08:46:56.137046       1 reflector.go:178] pkg/mod/k8s.io/client-go@v0.18.2/tools/cache/reflector.go:125: Failed to list *v1beta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

E0424 08:47:03.910421       1 reflector.go:178] pkg/mod/k8s.io/client-go@v0.18.2/tools/cache/reflector.go:125: Failed to list *v1beta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

E0424 08:47:21.584619       1 reflector.go:178] pkg/mod/k8s.io/client-go@v0.18.2/tools/cache/reflector.go:125: Failed to list *v1beta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

E0424 08:47:55.328820       1 reflector.go:178] pkg/mod/k8s.io/client-go@v0.18.2/tools/cache/reflector.go:125: Failed to list *v1beta1.Ingress: the server could not find the requested resource (get ingresses.extensions)

time="2025-04-24T08:48:07Z" level=fatal msg="Error running controller: failed to wait for caches to sync"

...

...

问题解决:

替换docker.io/argoproj/argo-rollouts:latest镜像为quay.io/argoproj/argo-rollouts:latest

# 

[root@master01 argorollouts]# grep -ri "image: re" install.yaml 

      - image: registry.cn-hangzhou.aliyuncs.com/github_images1024/argo-rollouts:latest 

2.4 安装 argo-rollouts plugin

此外,我们还可以安装一个 kubectl 插件,对于命令行管理和可视化发布非常方便。

1)安装 argo-rollouts 的 kubectl plugin:

# 下载插件

[root@master01 17]# 

curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.7.2/kubectl-argo-rollouts-linux-amd64

# 赋权

[root@master01 17]# chmod +x ./kubectl-argo-rollouts-linux-amd64

# 转移到/usr/local/bin/目录下

[root@master01 17]# mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

验证插件是否安装成功:

[root@master01 17]# kubectl argo rollouts version

kubectl-argo-rollouts: v1.7.2+59e5bd3

  BuildDate: 2024-08-13T18:26:20Z

  GitCommit: 59e5bd385c031600f86075beb9d77620f8d7915e

  GitTreeState: clean

  GoVersion: go1.21.13

  Compiler: gc

  Platform: linux/amd64

2.5 安装 Dashboard

下载 dashboard-install.yaml 文件:

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

[root@master01 argorollouts]# wget https://github.com/argoproj/argo-rollouts/releases/download/v1.7.2/dashboard-install.yaml

# 修改镜像为国内镜像

[root@master01 argorollouts]# sed -i s#quay.io/argoproj/kubectl-argo-rollouts:v1.7.2#registry.cn-hangzhou.aliyuncs.com/github_images1024/kubectl-argo-rollouts:v1.7.2#g dashboard-install.yaml

# 验证

[root@master01 argorollouts]# grep -ri "image:" dashboard-install.yaml 

      - image: registry.cn-hangzhou.aliyuncs.com/github_images1024/kubectl-argo-rollouts:v1.7.2

创建 Ingress ,访问 Dashboard

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

[root@master01 argorollouts]# vim argorollouts-dashboard-ing.yaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  name: argorollouts-dashboard-ingress

  namespace: argo-rollouts

spec:

  ingressClassName: nginx

  rules:

  - host: argorollouts.example.com

    http:

      paths:

      - backend:

          service:

            name: argo-rollouts-dashboard

            port:

              number: 3100

        path: /

        pathType: Prefix

把 argorollouts-dashboard-ing.yaml 及 dashboard-install.yaml 文件,放入 Git 仓库http://gitlab.example.com/demoteam/argo-rollouts.git仓库中

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

[root@master01 argorollouts]# git add .

[root@master01 argorollouts]# git commit -m "add new argo rollout"

[root@master01 argorollouts]# git branch -M main

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

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

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

最终目录文件结构:

[root@master01 17]# tree argo-rollouts/

argo-rollouts/

├── argorollouts

│   ├── argorollouts-dashboard-ing.yaml

│   ├── dashboard-install.yaml

│   └── install.yaml

└── argo-rollouts.yaml

1 directory, 4 files

浏览器打开https://argocd.example.com/,输入账号admin/<new-admin-password>进行登录,点击【Applications】-【argo-rollouts】-【SYNC】-【SYNCHRONIZE】

image-20250424174832805

点击【箭头图标】

image-20250422123954773

访问 Dashboard web 界面,目前没有创建数据,所以页面暂时为空

image-20250422124010956