**Argo 介绍
https://argoproj.github.io/
Argo 是一个开源项目,旨在提供一套用于在 Kubernetes 上运行和管理容器化工作负载的工具。
Argo 项目最早在2017年由Applatix公司创立开源,在2018年被美国加利福尼的 Intuit 公司收购并持续维护,并得到了广泛的社区支持。
Argo 项目主要包括以下几个子项目,每个子项目都有其特定的用途:
简介: Argo Workflows 是一个 Kubernetes 原生的工作流引擎,用于在 Kubernetes 集群上创 建、管理和协调容器化任务。
用途: 支持DAG(有向无环图 Directed Acyclic Graph),复杂的工作流定义和依赖管理,适用 于数据处理、机器学习训练和 CI/CD 管道等场景。
特性: 提供可视化界面、支持各种编程语言的模板、内置重试和错误处理机制。
简介: Argo CD 是一个用于 Kubernetes 的持续交付工具,通过声明式的 GitOps 方法来管理 Kubernetes 资源。
用途: 将 Git 仓库中的配置和应用程序声明与 Kubernetes 集群的实际状态进行同步。
特性: 提供可视化的同步状态监控、自动回滚、支持多种 Git 提供商、提供丰富的 RBAC(基 于角色的访问控制)。
简介: Argo Events 是一个事件驱动的工作流自动化框架,允许用户根据特定的事件触发工作 流。
用途: 通过各种事件源(如 GitHub、S3、HTTP 请求等)触发 Argo Workflows 或 Kubernetes 资源。
特性: 支持多种事件源、灵活的事件依赖管理、提供事件驱动的自动化功能。
简介: Argo Rollouts 是一个用于管理 Kubernetes 中高级部署策略的工具。
用途: 支持蓝绿部署、金丝雀部署、分阶段发布等高级发布策略,确保应用程序的平滑升级和 回滚。
特性: 提供可视化的发布状态监控、细粒度的流量控制、内置指标和健康检查功能。
这些子项目协同工作,为在 Kubernetes 上实现高效、可扩展和自动化的应用程序交付提供了强大的工 具集。
Argo Rollouts 介绍
Argo Rollouts 是 Argo 开源项目的一部分。Argo Rollouts 是一个用于渐进式交付的 Kubernetes 控制器,相当于增强版的deployment资源Argo Rollouts 包括一组自定义资源定义 (CRD),向 Kubernetes 引入蓝绿部署blue-green、金丝雀 发布canary、金丝雀分析canary analysis、渐进式交付progressive delivery 等高级部署功能。
Argo Rollouts 支持与ServiceMesh(Istio、Linkerd和SMI)和Ingress Controller 集成,以利用其流量 治理能力,并在更新期间逐渐将流量转移到新版本。
Argo Rollouts 还能够查询和解释来自多种指标系统(Prometheus、Kubernetes Jobs、Datadog等) 的指标来检查Blue-Green或Canary部署结果,并根据结果自动决定执行升级或回滚
发布模式:
蓝绿发布:
蓝绿发布提供了一种零宕机的部署方式。不停老版本,部署新版本进行测试,确认OK,将流量切到新版本,然后老版本同时也升级到新版本。始终有两个版本同时在线,有问题可以快速切换。
如下灰度发布的大致流程:
先切分20%的流量到新版本,若表现正常,逐步增加流量占比,继续测试新版本表现。若新版本一直很稳定,那么将所有流量都切分到新版本,并下线老版本。

切分20%的流量到新版本后,新版本出现异常,则快速将流量切回老版本。

金丝雀发布:
采用金丝雀部署,可以在生产环境的基础设施中小范围的部署新的应用代码。一旦应用签署发布,只有少数用户被路由到它。最大限度的降低影响。如果没有错误发生,新版本可以逐渐推广到整个基础设施。下图示范了金丝雀部署:

部署 Argo Rollouts
https://argoproj.github.io/argo-rollouts/installation/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| [root@rocky01 ~] [root@rocky01 ~]
[root@rocky01 ~] NAME SHORTNAMES APIVERSION NAMESPACED KIND analysisruns ar argoproj.io/v1alpha1 true AnalysisRun analysistemplates at argoproj.io/v1alpha1 true AnalysisTemplate clusteranalysistemplates cat argoproj.io/v1alpha1 false ClusterAnalysisTemplate experiments exp argoproj.io/v1alpha1 true Experiment rollouts ro argoproj.io/v1alpha1 true Rollout [root@rocky01 ~] NAME READY STATUS RESTARTS AGE pod/argo-rollouts-bdbddf5fb-zftjw 1/1 Running 0 3m21s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/argo-rollouts-metrics ClusterIP 10.68.187.95 <none> 8090/TCP 3m21s
NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/argo-rollouts 1/1 1 1 3m21s
NAME DESIRED CURRENT READY AGE replicaset.apps/argo-rollouts-bdbddf5fb 1 1 1 3m21s
|
部署 Dashboard
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| [root@rocky01 ~] [root@rocky01 ~] NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argo-rollouts-dashboard ClusterIP 10.68.192.197 <none> 3100/TCP 40s argo-rollouts-metrics ClusterIP 10.68.187.95 <none> 8090/TCP 6m10s
[root@rocky01 ~] [root@rocky01 ~] NAME CLASS HOSTS ADDRESS PORTS AGE rollouts nginx rollout.k8slab.io 192.168.5.239 80 18s [root@rocky01 ~] Server: 192.168.5.1 Address: 192.168.5.1#53
Name: rollout.k8slab.io Address: 192.168.5.239 [root@rocky01 ~]
|

部署 kubectl argo rollouts 命令插件
argo rollouts 没有提供相关专用命令管理 argo rollouts 资源,可以通过安装kubectl的插件实现管理argo rollouts的命令功能.
1 2 3 4 5 6 7 8 9 10
| [root@rocky01 ~] [root@rocky01 ~] kubectl-argo-rollouts: v1.7.1+6a99ea9 BuildDate: 2024-06-24T22:46:25Z GitCommit: 6a99ea9908e8f1e816ccd71e4c35adbbbbdd5f6c GitTreeState: clean GoVersion: go1.21.11 Compiler: gc Platform: linux/amd64 [root@rocky01 ~]
|
kubectl argo rollouts 命令常见用法:
1 2 3 4 5 6 7 8 9 10 11 12
| kubectl argo rollouts set image ROLLOUT_NAME CONTAINTER=NEW_IMAGE
kubectl argo rollouts get rollout ROLLOUT_NAME --watch
kubectl-argo-rollouts promote ROLLOUT_NAME [flags]
kubectl-argo-rollouts abort ROLLOUT_NAME [fags]
kubectl-argo-rollouts retry rollout ROLLOUT_NAME [fags]
kubectl-argo-rollouts undo ROLLOUT_NAME [flags]
|
基础案例:
https://github.com/argoproj/argo-rollouts/tree/master/examples
Canary (金丝雀) 进行 部署发布
https://github.com/argoproj/argo-rollouts/blob/master/examples/rollout-rolling-update.yaml
案例说明:
- 部署 Argo Rollouts 和 dashboard 及 kubectl argo rollouts 命令插件 部署 ingress-nginx
- 准备一个有两个新旧版本的myapp应用
- 依赖一个Service的调度功能, 通过Pod 数量来实现灰度发布
- 基于Pod 数量来实现流量的分配, 所以精确程度不足
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| --- apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: argo-rollouts-bulegreen spec: replicas: 10 strategy: canary: steps: - setWeight: 10 - pause: {} - setWeight: 20 - pause: {duration: 20} - setWeight: 30 - pause: {duration: 20} - setWeight: 40 - pause: {duration: 20} - setWeight: 60 - pause: {duration: 20} - setWeight: 80 - pause: {duration: 20} revisionHistoryLimit: 5 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: registry.cn-beijing.aliyuncs.com/wangxiaochun/myapp:v1.0 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 kind: Service metadata: name: myapp spec: ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: myapp --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myapp spec: ingressClassName: "nginx" rules: - host: myapp.k8slab.io http: paths: - path: / pathType: Prefix backend: service: name: myapp port: number: 80
|
1 2 3 4 5 6 7 8 9
| [root@rocky01 mnt] [root@rocky01 mnt] NAME CLASS HOSTS ADDRESS PORTS AGE myapp nginx myapp.k8slab.io 192.168.5.239 80 56m myapp-active nginx active.k8slab.io 192.168.5.239 80 68m myapp-preview nginx preview.k8slab.io 192.168.5.239 80 68m rollouts nginx rollout.k8slab.io 192.168.5.239 80 39h [root@rocky01 ~] <h1>Welcome to MyAPP v1.0</h1>
|


实施镜像更新
1 2 3 4
| [root@rocky01 mnt] rollout "argo-rollouts-canary" image updated [root@rocky01 ~] [root@rocky01 ~]
|

在页面上点击了Promote
以后,就会每隔20S,更新10%的资源。


实施回滚

结合Service进行Blue-Green部署
部署说明:
- 部署 Argo Rollouts 和 dashboard 及 kubectl argo rollouts 命令插件
- 部署 ingress-nginx
- 准备一个有两个新旧版本的myapp应用
- 使用Argo Rollouts提供的Rollout资源编排运行该应用 使用blueGreen更新策略
- 通过两个Service 实现Blue-Green 发布的版本 更新后,推出所有PreviewPod后即暂停,需要用户手动Promote
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: rollouts-bulegreen-myapp spec: replicas: 10 strategy: blueGreen: activeService: myapp-active previewService: myapp-preview autoPromotionEnabled: false previewReplicaCount: 10 scaleDownDelaySeconds: 60 revisionHistoryLimit: 5 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: registry.cn-beijing.aliyuncs.com/wangxiaochun/myapp:v1.0 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 kind: Service metadata: name: myapp-active spec: ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: myapp --- apiVersion: v1 kind: Service metadata: name: myapp-preview spec: ports: - port: 80 targetPort: http protocol: TCP name: http selector: app: myapp --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myapp-active spec: ingressClassName: "nginx" rules: - host: active.k8slab.io http: paths: - path: / pathType: Prefix backend: service: name: myapp-active port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myapp-preview spec: ingressClassName: "nginx" rules: - host: preview.k8slab.io http: paths: - path: / pathType: Prefix backend: service: name: myapp-preview port: number: 80
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| [root@rocky01 mnt] NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/myapp nginx myapp.k8slab.io 192.168.5.239 80 14m ingress.networking.k8s.io/myapp-active nginx active.k8slab.io 192.168.5.239 80 88m ingress.networking.k8s.io/myapp-preview nginx preview.k8slab.io 192.168.5.239 80 88m ingress.networking.k8s.io/rollouts nginx rollout.k8slab.io 192.168.5.239 80 40h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/argo-rollouts-dashboard ClusterIP 10.68.192.197 <none> 3100/TCP 40h service/argo-rollouts-metrics ClusterIP 10.68.187.95 <none> 8090/TCP 40h service/myapp ClusterIP 10.68.161.129 <none> 80/TCP 14m service/myapp-active ClusterIP 10.68.130.229 <none> 80/TCP 88m service/myapp-preview ClusterIP 10.68.247.67 <none> 80/TCP 88m [root@rocky01 mnt] <h1>Welcome to MyAPP v1.0</h1> [root@rocky01 mnt] <h1>Welcome to MyAPP v1.0</h1>
|
更新新版本镜像
1 2 3
| [root@rocky01 mnt] rollout "rollouts-bulegreen-myapp" image updated [root@rocky01 mnt]
|


访问测试,目前应该是预览版和稳定版都可以访问
1 2 3 4
| [root@rocky01 mnt] <h1>Welcome to MyAPP v2.0</h1> [root@rocky01 mnt] <h1>Welcome to MyAPP v1.0</h1>
|
将新版本切换为稳定版本:
1 2 3
| [root@rocky01 mnt] rollout 'rollouts-bulegreen-myapp' promoted [root@rocky01 mnt]
|


进阶案例
结合Prometheus指标进行Analysis实现canary部署
案例说明
- 部署 Argo Rollouts 和 dashboard 及 kubectl argo rollouts 命令插件
- 准备一个有两个新旧版本的myapp应用
- 安装 prometheus 安装Ingress-nginx,并修改ingress-nginx-controller的service,实现支持prometheus采集指标
- 定义了两个参数: service-name和namespace的,用于传递要测量的服务的名称及其所在的名称空 间
- 定义了success-rate指标,测试指定服务的请求成功率
- 每隔20s查询一次prometheus服务,共执行3次
- 成功条件为:第1个指标(下标为0)的结果值大于等于0.95,遇到3次错误即终止进一步的测试 AnalysisRun CRD
- 配置格式与AnalysisTemplaste大致相同,所不同的是,AnalysisRun用于调用并实例化分析模板
结合Prometheus指标进行Analysis实现Blue- Green部署
案例说明
- 部署 Argo Rollouts和dashboard 及 kubectl argo rollouts命令插件
- 准备一个有两个新旧版本的myapp应用
- 安装prometheus安装Ingress-nginx,并修改ingress-nginx-controller的service,实现支持prometheus采集指标
- 使用Argo Rollouts提供的Rollout资源编排运行该应用 使用blueGreen更新策略,更新镜像后,首先推出新版本的所有Preview Pod,引用一点流量进行测试访问
- 接着将调用切换前分析prePromotionAnalysis所定义的analysistemplate/success-rate进行分析
- 满足成功条件后即自动进行Promote,从而将preview版本提升为stable,此时全部流量才会将由提 升后的preview版本承载
- 随后将再次调用切换后分析postPromotionAnalysis所定义的analysistemplate/success-rate进行分析
- 满足成功条件后,即自动缩减旧版的RS规模到0实例,否则,将流量切换回此前的版本,旧的版本将 重新变为stable