告别手工管理 Argo CD Application:ApplicationSet 批量编排实战指南
告别手工管理 Argo CD Application:ApplicationSet 批量编排实战指南
当你需要把同一套应用部署到 10 个集群、为每个分支创建预览环境,或者管理几百个微服务时,手动维护 Application 资源会变成噩梦。Argo CD ApplicationSet 就是为这种批量场景而生。本文带你吃透它的核心原理、生成器机制和实战用法。
目录
单个 Application 的局限
什么是 ApplicationSet?
核心机制:模板 + 生成器
七大生成器详解
4.1 List 生成器
4.2 Cluster 生成器
4.3 Git 生成器(目录/文件)
4.4 SCM Provider 生成器
4.5 Pull Request 生成器
4.6 Matrix 与 Merge 生成器
ApplicationSet vs App of Apps:区别与组合
实战:用 ApplicationSet 部署多集群 AI 推理服务
最佳实践与避坑指南
总结
1. 单个 Application 的局限
在上一篇 Argo CD 文章中,我们学会了如何创建一个 Application 来同步一个 Git 仓库中的应用。但现实中的需求往往更复杂:
多集群部署:同一套应用要部署到 dev、staging、prod 等多个集群,每个集群的 Application 参数稍有不同(namespace、集群地址等)。
多环境差异化:每个分支需要独立的预览环境,Application 需要动态指向不同分支或目录。
大规模微服务:几十上百个微服务,每个都需要一个 Application,手动管理会疯掉。
你当然可以用App of Apps 模式,即写一个根 Application 来管理一堆子 Application 的 YAML。但那些子 Application 的 YAML 还是要你自己维护,而且当集群数量、环境数量增加时,静态文件会急剧膨胀。
ApplicationSet 正是为解决这种“模板化 + 批量生成”问题而生的。
2. 什么是 ApplicationSet?
ApplicationSet 是 Argo CD 的一个CRD(自定义资源),它利用模板(Template)和生成器(Generator)自动创建多个 Application 资源。
简单来说:
模板:定义了一个 Application 的“骨架”,其中部分参数用变量表示。
生成器:负责产生多组变量值,每组值渲染出一个完整的 Application。
一个 ApplicationSet 可以生成几十、几百个 Application,你只需维护这个 ApplicationSet 资源即可。
ApplicationSet 控制器内置于 Argo CD(从 v2.3 开始稳定),无需额外安装。
3. 核心机制:模板 + 生成器
来看一个最小示例,感受一下它的运作方式:
yaml
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook namespace: argocd spec: generators: - list: elements: - cluster: engineering-dev url: https://kubernetes.default.svc - cluster: engineering-prod url: https://prod-cluster.example.com template: metadata: name: 'guestbook-{{cluster}}' spec: project: default source: repoURL: https://github.com/argoproj/argocd-example-apps.git targetRevision: HEAD path: guestbook destination: server: '{{url}}' namespace: guestbook这个 ApplicationSet 会生成两个 Application:
guestbook-engineering-dev→ 部署到https://kubernetes.default.svcguestbook-engineering-prod→ 部署到https://prod-cluster.example.com
模板里的{{cluster}}和{{url}}就是从 List 生成器的元素中取值的。
控制器的行为:ApplicationSet 控制器会监测生成器的输入变化,并动态创建、更新或删除 Application。当删除 ApplicationSet 时,默认不会级联删除其生成的 Application,但可通过设置.spec.syncPolicy.preserveResourcesOnDeletion: false来改变。
4. 七大生成器详解
生成器是 ApplicationSet 的灵魂。Argo CD 提供了多种生成器,可单独使用,也可通过 Matrix/Merge 组合。
4.1 List 生成器
最直接:提供一个固定列表,每个元素是一组 key-value。
yaml
generators: - list: elements: - env: dev cluster: dev-cluster namespace: myapp-dev - env: prod cluster: prod-cluster namespace: myapp-prod
模板中使用{{env}}、{{cluster}}、{{namespace}}。
适用于环境数量固定、差异不大的场景。
4.2 Cluster 生成器
自动从 Argo CD 已连接的集群列表生成参数。它会查询所有已注册的集群,输出name、server、metadata.labels等字段。
yaml
generators: - clusters: selector: matchLabels: env: staging
Argo CD 中任何带有env: staging标签的集群都会被选中,模板里可以用{{name}}、{{server}}以及集群标签作为变量。这使得动态添加新集群时,应用会自动部署过去,真正实现“集群即服务”。
4.3 Git 生成器
Git 生成器根据 Git 仓库中的目录结构或文件内容生成参数,分为两种子类型:
4.3.1 目录生成器(Git Directory)
扫描 Git 仓库中指定路径下的子目录,每个子目录生成一个 Application。
yaml
generators: - git: repoURL: https://github.com/example/apps.git revision: HEAD directories: - path: apps/*
假设仓库结构为:
text
apps/ frontend/ kustomization.yaml backend/ kustomization.yaml
则会生成两个 Application,{{path}}变量分别是apps/frontend和apps/backend,同时还有{{path.basename}}(目录名)等派生变量。
这正是微服务批量管理的最佳实践:每新增一个服务,只需在仓库中新建目录并放入配置,ApplicationSet 会自动生成对应的 Application。
4.3.2 文件生成器(Git File)
读取仓库中的 JSON/YAML 文件,每个文件条目作为一个参数。比如有一个envs.json:
json
[ { "env": "dev", "cluster": "dev-cluster" }, { "env": "prod", "cluster": "prod-cluster" } ]生成器配置:
yaml
generators: - git: repoURL: https://github.com/example/config.git revision: HEAD files: - path: envs.json
每个 JSON 对象会渲染出一个 Application。适合将环境配置集中到单个文件中。
4.4 SCM Provider 生成器
与 Git 目录生成器类似,但它是直接从 Git 组织/仓库中查找所有符合条件的仓库,并为每个仓库生成 Application。支持 GitHub、GitLab、Bitbucket 等。
yaml
generators: - scmProvider: github: organization: my-org # 可选过滤 allBranches: true cloneProtocol: https
这常用于组织级仓库发现:公司有几十个微服务仓库,每个仓库根目录都有 Kustomize/Helm 配置,ApplicationSet 会自动为每个仓库创建一个 Application。
4.5 Pull Request 生成器
当 Git 仓库有新的 PR(Pull Request)创建时,自动生成一个临时 Application 用于预览环境。
yaml
generators: - pullRequest: github: owner: my-org repo: my-app requeueAfterSeconds: 180
生成的 Application 会包含 PR 编号、分支、head SHA 等变量,可以部署到独立的 namespace(如pr-{{number}})。PR 合并或关闭后,ApplicationSet 会自动删除对应的 Application,实现预览环境的全生命周期管理。
4.6 Matrix 与 Merge 生成器
当单一生成器无法满足需求时,可用 Matrix 和 Merge 组合多个生成器。
Matrix:取两个子生成器的笛卡尔积。例如,将 List(环境)和 Cluster(集群)组合,生成
{dev}×{cluster-a}、{dev}×{cluster-b}等所有组合。Merge:将两个子生成器生成的项目进行一对一合并(类似 SQL JOIN),要求两个生成器产出的数量相等,按索引合并。用于从不同来源提取属性合并到同一个参数集中。
yaml
generators: - matrix: generators: - list: elements: - env: dev - env: prod - clusters: selector: matchLabels: env: '{{env}}' # 这里不能直接引用上层变量,需注意作用域Matrix 生成器有一些作用域限制,使用时建议仔细阅读官方文档。
5. ApplicationSet vs App of Apps:区别与组合
很多人会困惑:ApplicationSet 和 App of Apps 都是批量管理 Application,它们有何不同?
| 对比维度 | App of Apps | ApplicationSet |
|---|---|---|
| 原理 | 手动编写多个 Application YAML,由一个根 Application 统一 apply | 用生成器动态创建 Application |
| 扩展性 | 新增服务需要新增 YAML 文件 | 新增目录/集群/PR 自动生成 |
| 配置量 | 较多,每个 Application 一份 | 很少,只需一个模板 |
| 参数化能力 | 较弱,可用 Helm/Kustomize 辅助 | 内建模板变量,非常灵活 |
| 动态感知 | 弱,需手动更新 Git | 强,自动感知集群/仓库变化 |
最佳组合:
用ApplicationSet动态生成和管理 Application,作为“工厂”。
用一个 App of Apps 类型的 ApplicationSet来管理多个 ApplicationSet(即管理管理者的管理者),不过这种模式通常直接用 ApplicationSet 的嵌套即可,或者将 ApplicationSet 本身放入 Git,并用 App of Apps apply 进去。
更实用的组合:使用ApplicationSet(Git 目录生成器)来替代静态的 App of Apps,让服务数量自由扩展。
6. 实战:用 ApplicationSet 部署多集群 AI 推理服务
回顾我们之前的文章,我们有一个 vLLM 推理服务部署到 Kubernetes。假设现在我们要把同一个推理服务部署到三个不同的集群(dev、staging、prod),每个集群的 GPU 类型和副本数略有不同。
我们可以这样设计 ApplicationSet:
yaml
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: vllm-inference namespace: argocd spec: generators: - list: elements: - env: dev server: https://dev-cluster.example.com replicas: "1" gpu: "nvidia-t4" - env: staging server: https://staging-cluster.example.com replicas: "2" gpu: "nvidia-a10" - env: prod server: https://prod-cluster.example.com replicas: "4" gpu: "nvidia-a100" template: metadata: name: 'vllm-{{env}}' spec: project: default source: repoURL: https://github.com/my-org/ai-services.git targetRevision: HEAD path: vllm helm: parameters: - name: replicas value: '{{replicas}}' - name: gpu.type value: '{{gpu}}' destination: server: '{{server}}' namespace: ai-inference syncPolicy: automated: prune: true selfHeal: true这里我们用了Helm 参数化,vllm目录下的 Helm Chart 读取replicas和gpu.type,每个环境生成不同的配置。
如果你想为每个环境添加不同的模型版本,还可以在 List 元素中加入modelVersion字段,然后在 Helm 参数中传递。
如果后续 dev 集群被移除,只需从 List 中删除对应元素,ApplicationSet 控制器会负责清理对应的 Application(前提是.spec.syncPolicy.preserveResourcesOnDeletion设为false)。
7. 最佳实践与避坑指南
避免生成的 Application 命名冲突:模板中的
name必须是唯一的,通常使用组合变量,如'myapp-{{env}}-{{cluster}}'。谨慎设置资源清理策略:默认删除 ApplicationSet 不会删除已生成的 Application。如果希望级联删除,设置
syncPolicy.preserveResourcesOnDeletion: false。使用项目(Project)做权限隔离:在模板中指定
project,利用 Argo CD 的 Project 限制可访问的仓库和集群。不要滥用 Matrix 生成器:组合爆炸可能产生大量 Application,给 Kubernetes API 和 Argo CD 控制器带来压力。建议生成总数控制在几百以内。
测试新生成器:先在一个测试集群上验证生成逻辑,确保模板变量没有拼写错误。
结合 GitOps 管理 ApplicationSet 自身:把 ApplicationSet 的 YAML 也放在 Git 仓库中,用 App of Apps 或手动 apply 的方式部署它,实现自举。
监控 ApplicationSet 控制器的日志:如果生成的 Application 一直不出现,检查
argocd-applicationset-controller的日志,通常能找到原因(如模板变量未定义)。
8. 总结
ApplicationSet 是 Argo CD 进入“规模化 GitOps”的关键拼图。它让你从一个个手工创建 Application 的繁琐劳动中解放出来,用模板 + 生成器的声明式方法,自动应对多集群、多环境、多服务的复杂部署需求。
从今天开始,请检查一下你的 Argo CD 中是否还躺着一堆静态的 Application YAML。如果是,不妨把它们重构成一个 ApplicationSet,感受一下“一个 CR 管所有”的畅快。
如果本文帮你理清了 ApplicationSet 的用法,欢迎点赞、收藏。你有哪些独家的生成器组合玩法?评论区聊聊!