WEBKT

ArgoCD ApplicationSet 多集群管理与 CI/CD 自动回滚实战指南

46 0 0 0

ArgoCD ApplicationSet 多集群管理与 CI/CD 自动回滚实战指南

在多租户或多集群的 Kubernetes 环境中,手动维护成百上千个 ArgoCD Application 资源简直是运维噩梦。ApplicationSet 插件正是为了解决这一痛点而生,它通过生成器模式(Generators)实现了应用定义的规模化管理。然而,当我们深入 CI/CD 流水线时,一个棘手的问题浮出水面:如果镜像构建失败或新版本不稳定,如何实现自动回滚?

一、利用 ApplicationSet 批量管理多租户/多集群应用

ApplicationSet 的核心在于将应用定义模板化。针对多集群场景,最强大的组合是 Git Generator 配合 Cluster Generator

1. 目录结构规划(GitOps 最佳实践)

建议采用如下仓库结构,将应用定义与集群配置分离:

├── apps/                  # 应用定义模板
│   └── guestbook/
│       ├── appset.yaml    # ApplicationSet 定义
│       └── kustomize/     # 基础 Kustomize 配置
└── clusters/              # 集群清单
    ├── production/
    │   └── config.json    # 集群特定参数(如副本数、域名)
    └── staging/
        └── config.json

2. ApplicationSet 配置示例

这是一个典型的配置,它会遍历 clusters/ 目录下的子目录,并为每个目录生成一个 Application,同时注入对应的集群参数。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: https://github.com/your-org/gitops-repo.git
        revision: HEAD
        directories:
          - path: clusters/*
  template:
    metadata:
      name: '{{path.basename}}-guestbook'
      namespace: argocd
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-repo.git
        targetRevision: HEAD
        path: apps/guestbook/kustomize
        helm:
          valueFiles:
            - 'values.yaml'
            - '{{path}}/config.json' # 动态注入集群特定配置
      destination:
        server: '{{url}}' # Cluster Generator 可以配合使用,这里假设通过目录配置
        namespace: guestbook
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

通过这种方式,当你在 clusters/ 下新增一个 production-us-east 目录,ArgoCD 会自动发现并部署该应用到对应集群,实现了批量管理。


二、CI/CD 流水线中的“自动回滚”悖论与解法

在标准的 GitOps 流程中,ArgoCD 遵循 "Desired State is Git" 的原则。如果 CI 流水线构建镜像失败,Git 仓库中的镜像 Tag 通常不会更新,因此 ArgoCD 不会触发任何动作。

真正的挑战在于:CI 成功推送了新镜像 Tag 到 Registry,同时也更新了 Git Repo,但部署后发现服务异常。

此时,我们不能单纯依赖 ArgoCD 的 SyncPolicy,因为它不知道什么是“异常”。我们需要引入 "Health Check""Image Updater" 策略。

1. 策略 A:利用 Argo CD Image Updater 实现“镜像级”回滚

argocd-image-updater 是一个独立的组件,它能监控镜像仓库的新版本,并自动更新 ArgoCD Application 的源。配合 ignoreTags 策略,可以实现精细化控制。

配置自动回滚的关键参数:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  annotations:
    # 开启 Image Updater
    argocd-image-updater.argoproj.io/image-list: my-app=registry.example.com/my-app
    # 定义回滚策略:仅允许升级 semantic versioning 的 patch 和 minor 版本
    argocd-image-updater.argoproj.io/my-app.update-strategy: semver
    argocd-image-updater.argoproj.io/my-app.allow-tags: regexp:^v[0-9]+\.[0-9]+\.[0-9]+$
    # 关键:如果更新后应用状态为 "Missing" 或 "Unknown",Image Updater 不会盲目升级
    # 但我们需要结合 ArgoCD 的 "Rollback" 动作

2. 策略 B:在 CI 流水线中触发 ArgoCD API 回滚(推荐)

这是最符合“CI/CD 驱动”逻辑的方案。既然 CI 知道构建失败,它就应该负责回滚。

实现逻辑:

  1. CI 流程 (GitHub Actions / Jenkins):

    • Step 1: 构建镜像并打 Tag (e.g., v1.2.0-build.123)。
    • Step 2: 运行 E2E 测试。
    • Step 3: 如果测试失败,不要更新 Git Repo 的生产 Tag,而是直接调用 ArgoCD API 回滚到上一个稳定版本。
  2. ArgoCD CLI 回滚命令:

# 获取 Application 当前历史版本
APP_HISTORY=$(argocd app history my-app -o json)

# 提取上一个成功的版本 ID (通常是最近的一个)
LAST_SUCCESSFUL_ID=$(echo "$APP_HISTORY" | jq -r '.[1].id')

# 执行回滚
argocd app rollback my-app $LAST_SUCCESSFUL_ID --prune
  1. 进阶:使用 ArgoCD Notifications 实现自动修复
    如果你希望 ArgoCD 检测到应用 Degraded 状态后自动回滚,可以配置 argocd-notifications

    Secret 配置 (Trigger):

    trigger.on-degraded:
      - send: [rollback]
      - when: app.status.sync.status == 'OutOfSync' && app.status.health.status == 'Degraded'
    

    Template:

    template.rollback: |
      argocd app rollback {{.app.metadata.name}} --prune
    

    注意:这种方式风险较高,建议仅在非核心业务或配合严格的自动化测试使用。

三、总结

在多集群环境下,ApplicationSet 是管理的基石,它通过 Git Generator 将配置扩散到各处。而针对 CI/CD 中的镜像构建失败或不稳定问题,自动回滚 并不是 ArgoCD 的原生默认行为,而是需要通过 argocd-image-updater 或者在 CI 流水线中通过 argocd app rollback 命令来主动触发。

最稳健的方案是:Git 仓库永远保留上一个稳定版本的引用,当 CI 检测到新版本构建失败或验证失败时,立即撤销 Git 更新并通知 ArgoCD 保持现状或回滚,从而形成闭环。

SRE运维手记 ArgoCD自动回滚

评论点评