为什么需要 ApplicationSet
假设你有 20 个微服务,每个服务需要部署到 3 个环境(dev/staging/prod),手动维护 60 个 Application YAML 不仅繁琐,还容易出错且难以维护。ApplicationSet 允许你用一个模板定义,通过 Generator 自动生成多个 Application。
ApplicationSet Controller 是 ArgoCD 的独立组件(ArgoCD 2.x 起已内置),它监听 ApplicationSet 资源,根据 Generator 的输出动态创建、更新或删除对应的 Application。
ApplicationSet 结构
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-appset
namespace: argocd
spec:
goTemplate: true # 使用 Go 模板(推荐,功能更强)
generators: # Generator 列表(产生参数集合)
- list:
elements:
- app: frontend
- app: backend
template: # Application 模板,{{ }} 引用参数
metadata:
name: '{{.app}}'
spec:
project: default
source:
repoURL: https://github.com/my-org/config
targetRevision: HEAD
path: 'apps/{{.app}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{.app}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Git Generator:自动发现目录
Git Generator 扫描仓库中的目录结构,自动为每个匹配目录生成一个 Application,真正实现"新增服务目录即自动部署":
generators:
- git:
repoURL: https://github.com/my-org/my-gitops-config
revision: HEAD
directories:
- path: services/*/overlays/prod # 通配符匹配目录
- path: services/infra
exclude: true # 排除此目录
# 仓库目录结构示例
services/
├── user-service/overlays/prod/ # 自动生成 Application: user-service
├── order-service/overlays/prod/ # 自动生成 Application: order-service
├── payment-service/overlays/prod/ # 自动生成 Application: payment-service
└── infra/ # 被排除
Cluster Generator:多集群批量部署
Cluster Generator 遍历 ArgoCD 中注册的所有(或过滤后的)集群,为每个集群生成 Application:
generators:
- clusters:
selector:
matchLabels:
environment: production # 只选择生产集群
values: # 为每个集群添加自定义参数
revision: stable
Matrix Generator:多维组合
Matrix Generator 将两个 Generator 的输出进行笛卡尔积组合,例如"5 个服务 × 3 个集群 = 15 个 Application":
generators:
- matrix:
generators:
- git: # 第一维:服务列表
repoURL: https://github.com/my-org/config
revision: HEAD
directories:
- path: services/*
- clusters: # 第二维:集群列表
selector:
matchLabels:
type: workload
Pull Request Generator:预览环境
PR Generator 监听 Git 仓库的 Pull Request,为每个开放的 PR 自动创建一个隔离的预览环境(Preview Environment),PR 关闭后自动销毁:
generators:
- pullRequest:
github:
owner: my-org
repo: my-app
tokenRef: # GitHub Token(用于 API 访问)
secretName: github-token
key: token
labels: # 只为有此 label 的 PR 创建环境
- preview
requeueAfterSeconds: 60 # 每60秒检查一次 PR 状态
template:
metadata:
name: 'preview-pr-{{.number}}' # PR 编号作为 App 名
spec:
source:
repoURL: https://github.com/my-org/my-app
targetRevision: '{{.head_sha}}' # PR 的最新 commit
path: helm
helm:
parameters:
- name: ingress.hostname
value: 'pr-{{.number}}.preview.example.com'
destination:
server: https://kubernetes.default.svc
namespace: 'pr-{{.number}}' # 每个 PR 独立命名空间
syncPolicy:
automated:
prune: true
实战:单仓库管理 20 个微服务
完整示例:使用一个 ApplicationSet 管理所有微服务的生产部署,新增服务只需在仓库中创建目录:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: microservices-prod
namespace: argocd
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- git:
repoURL: https://github.com/my-org/microservices-config
revision: main
directories:
- path: services/*/overlays/prod
template:
metadata:
name: '{{.path.basename | replace "-overlays-prod" ""}}-prod'
labels:
managed-by: appset-microservices
environment: production
spec:
project: microservices
source:
repoURL: https://github.com/my-org/microservices-config
targetRevision: main
path: '{{.path}}'
destination:
server: https://prod-cluster.example.com:6443
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
syncPolicy:
applicationsSync: create-update # 自动创建和更新,但不自动删除
preserveResourcesOnDeletion: false
ApplicationSet 的 syncPolicy.applicationsSync 设置为 create-update(而非 create-update-delete)可防止因配置误删而级联删除所有应用。在生产环境,建议手动管理 ApplicationSet 中 Application 的删除,而非自动化。
ApplicationSet 通过模板化消除了大量重复的 Application YAML。Git Generator 实现了"目录即服务"的自动发现,Cluster Generator 支持多集群批量部署,Matrix Generator 实现多维组合,PR Generator 为每个 PR 创建隔离预览环境。这些 Generator 组合使用,可以用极少的配置管理数十个应用的跨环境跨集群部署。