渐进式交付 – 使用 Argo Rollouts 实现金丝雀与蓝/绿发布

渐进式交付 – 使用 Argo Rollouts 实现金丝雀与蓝/绿发布


Argo Rollouts 是什么?为何需要它?

标准的 Kubernetes Deployment 对象在执行滚动更新时,虽然能做到不中断服务,但它存在两大“天生”的局限:

缺乏精细的流量控制: 它无法实现“先将 10% 的流量切换到新版本,观察一下,然后再切换到 30%”这样的精细化操作。
对应用健康状况一无所知: Deployment 只关心 Pod 是否能成功启动并响应 readinessProbe(就绪探针)。它完全不知道新版本的应用在真实流量下的表现如何——例如,错误率是否飙升?延迟是否增加?它只管“发布”,不管“后果”。

Argo Rollouts 正是为了解决这些问题而生的。它是一个专门为 Kubernetes 设计的、专注于高级部署策略的控制器。

它是 Deployment 的超集: 你可以把 Rollout 看作是一个功能更强大的 Deployment。它的 spec 字段与 Deployment 高度兼容,迁移成本很低。
它能精细化地控制流量: 通过与服务网格 (Service Mesh) 或 Ingress 控制器集成,Argo Rollouts 可以精确地按百分比分配流量。
它能基于数据做决策: 这是它的“杀手级特性”。Argo Rollouts 可以在发布的关键步骤暂停,并自动查询监控系统(如 Prometheus, Datadog),分析新版本的性能指标。只有当指标(如错误率、延迟)符合预设的健康标准时,它才会继续发布;否则,它会自动回滚。

第一步:安装 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 插件 (非常重要!):
Argo Rollouts 提供了一个功能极其强大的 kubectl 插件,用于与之交互。

macOS 用户:

brew install argocd-rollouts

Linux 用户:

# (请参考 Argo Rollouts 官方文档获取最新命令)
VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-rollouts/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/1/')
curl -sSL -o /usr/local/bin/kubectl-argo-rollouts "https://github.com/argoproj/argo-rollouts/releases/download/$VERSION/kubectl-argo-rollouts-linux-amd64"
chmod +x /usr/local/bin/kubectl-argo-rollouts

安装后,你就可以使用 kubectl argo rollouts 命令了。

第二步:改造应用为 Rollout

现在,让我们回到 my-gitops-manifests Git 仓库,将我们之前的 Nginx 应用从 Deployment 改造为 Rollout

替换 deployment.yaml:
apps/nginx/base/ 目录下,删除 deployment.yaml,并创建一个新的 rollout.yaml 文件。

apps/nginx/base/rollout.yaml
apiVersion: argoproj.io/v1alpha1
# 注意 Kind 变成了 Rollout
kind: Rollout 
metadata:
  name: nginx-rollout
spec:
  replicas: 5 # 我们用 5 个副本,方便观察百分比
  selector:
    matchLabels:
      app: nginx
  # Pod 模板部分与 Deployment 完全相同
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.5
        ports:
        - containerPort: 80
  
  # --- 这是 Rollout 的精髓所在 ---
  strategy:
    canary:
      # 定义金丝雀发布的步骤
      steps:
      - setWeight: 20  # 第 1 步: 将 20% 的流量(即 1/5 的 Pods)更新到新版本
      - pause: {
              }      # 第 2 步: 无限期暂停,等待人工审核
      - setWeight: 40  # 第 3 步: 升级到 40%
      - pause: {
               duration: 10s } # 第 4 步: 暂停 10 秒
      - setWeight: 60  # 第 5 步: 升级到 60%
      - pause: {
               duration: 10s }
      # 后续会自动完成到 100%

strategy.canary.steps: 这个部分定义了发布流程。setWeight 控制了新版本 Pod 所占的百分比。pause: {} 表示无限期暂停,需要人工干预才能继续;pause: { duration: 10s } 表示自动暂停指定的时长。

更新 kustomization.yaml:
修改 apps/nginx/base/kustomization.yaml,将 deployment.yaml 替换为 rollout.yaml

git commitgit push 你的变更。Argo CD 会自动同步,删除旧的 Deployment 并创建新的 Rollout 资源。

第三步:执行一次金丝雀发布

现在,让我们来触发一次发布!

触发变更: 修改 apps/nginx/base/rollout.yaml 中的镜像版本,例如改为 image: nginx:1.26.1,然后提交并推送到 Git。

观察发布过程: Argo CD 同步后,Argo Rollouts 控制器会检测到 Rollout 的变更并开始执行我们定义的发布策略。打开你的终端,运行下面这个神奇的命令:

kubectl argo rollouts get rollout nginx-rollout -n default -w

-w 参数表示持续观察 (watch)。*

你会看到一个非常直观的、实时更新的文本 UI,清晰地展示了:

Stable (稳定版)Canary (金丝雀版) 的 ReplicaSet。
两个版本的 Pod 数量和健康状况。
当前执行到的 steppause 状态。
发布会执行到第一步(创建 1 个 canary Pod,占比 20%),然后进入无限期暂停。

人工干预 (Promote):
在暂停阶段,我们可以对新版本进行小范围的验证。确认无误后,手动“放行”发布到下一步:

kubectl argo rollouts promote nginx-rollout -n default

执行后,你会看到 dashboard 上的发布流程继续向下执行,经过后续的自动暂停,最终完成 100% 的发布。

中止发布 (Abort):
如果在发布过程中发现新版本有问题,可以立即中止发布并回滚:

kubectl argo rollouts abort nginx-rollout -n default

Rollouts 控制器会迅速将 canary 版本的 Pod 缩容到 0,并将 stable 版本扩容回原来的数量,实现快速、安全的回滚。

第四步:自动化分析 – GitOps 的超级能力

手动 promote 虽然比全自动的滚动更新更安全,但仍然依赖人工判断。Argo Rollouts 最强大的地方在于它可以基于应用的性能指标来自动做出发布或回滚的决策

核心理念: 我们定义一个**“分析模板 (AnalysisTemplate)”**,告诉 Rollouts 如何衡量应用的健康状况(例如,去 Prometheus 查询应用的请求成功率)。然后在 Rolloutsteps 中,用 analysis 步骤来调用这个模板。如果分析成功,则自动 promote;如果分析失败,则自动 abort

前提: 这需要你的集群中已经部署了 Prometheus 监控系统,并且它正在抓取你的应用的指标。

示例 AnalysisTemplate:
(这是一个概念性示例,需要根据你的实际监控系统进行调整)

# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate-check
spec:
  # args 可以让模板更通用,这里定义一个 service-name 作为参数
  args:
  - name: service-name
  metrics:
  - name: success-rate
    # 每隔 1 分钟查询一次 Prometheus
    interval: 1m
    # 如果连续 3 次查询都失败,则整个分析失败
    failureLimit: 3
    # 如果查询结果 >= 95%,则认为本次测量成功
    successCondition: result[0] >= 0.95 
    provider:
      prometheus:
        address: http://prometheus.monitoring.svc:9090 # Prometheus 的地址
        # 查询语句,查询指定 service 的请求成功率
        query: |
          sum(irate(nginx_http_requests_total{job="{
              {args.service-name}}",status!~"5.."}[1m])) 
          / 
          sum(irate(nginx_http_requests_total{job="{
              {args.service-name}}"}[1m]))

Rollout 中使用分析模板:
修改 rollout.yamlsteps

# ...
steps:
- setWeight: 20
- pause: {
              } # 第一次仍然手动,用于初始观察
- setWeight: 50
# 将 pause 替换为 analysis
- analysis:
    templateName: success-rate-check # 引用分析模板
    args: # 传递参数
    - name: service-name
      value: nginx-canary # 假设有一个 service 指向 canary pods
# ...

这就是数据驱动的、最安全的自动化发布。SRE 的职责从“手动点击按钮”转变为“定义成功的标准”,剩下的交给机器去执行。

蓝/绿部署简介

Argo Rollouts 同样完美支持蓝/绿部署。只需将 strategy 修改为 blueGreen 即可:

strategy:
  blueGreen:
    # 指向当前线上 (blue) 版本的 Service
    activeService: nginx-active-svc
    # 指向新 (green) 版本的 Service,用于发布前的预览和测试
    previewService: nginx-preview-svc
    # 部署完 Green 版本后是否自动切换流量,设为 false 则会暂停等待人工 promote
    autoPromotionEnabled: false

promote 操作会通过修改 activeServiceselector 来实现流量的瞬间切换。

总结与展望

今天,我们从标准的滚动更新迈出了一大步,进入了渐进式交付的领域。我们学习了如何使用 Argo Rollouts 这一强大的工具来替代原生的 Deployment,并动手实践了分步骤、可控的金丝雀发布。更重要的是,我们了解了其最核心的能力——基于性能指标的自动化分析,这是 SRE 实现高速度与高安全性的终极武器。

我们现在拥有了一套既能规模化管理应用,又能以极低风险进行发布的顶级 GitOps 平台。

然而,还有一个关键的安全问题悬而未决:在我们的 Git 仓库中,无论是应用配置还是 Argo CD 的 Application 定义,我们都避免了存储任何敏感信息。那么,像数据库密码、API Key 这样的机密 (Secrets),在 GitOps 的世界里究竟该如何管理呢?

在下一篇中,我们将直面这个挑战,深入探讨在 GitOps 流程中安全管理密钥的各种主流方案。敬请期待!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容