Chapter 06

ApplicationSet 多应用管理

用 ApplicationSet CRD 模板化批量生成 Application,通过多种 Generator 实现自动发现、多集群部署和 PR 预览环境,用一个 YAML 管理数十个微服务。

为什么需要 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 删除保护

ApplicationSet 的 syncPolicy.applicationsSync 设置为 create-update(而非 create-update-delete)可防止因配置误删而级联删除所有应用。在生产环境,建议手动管理 ApplicationSet 中 Application 的删除,而非自动化。

本章小结

ApplicationSet 通过模板化消除了大量重复的 Application YAML。Git Generator 实现了"目录即服务"的自动发现,Cluster Generator 支持多集群批量部署,Matrix Generator 实现多维组合,PR Generator 为每个 PR 创建隔离预览环境。这些 Generator 组合使用,可以用极少的配置管理数十个应用的跨环境跨集群部署。