4. Application 资源定义:Source(Git仓库)、Destination(目标集群)、Sync Policy(同步策略)详解

Argo CD 的 Application 是 GitOps 工作流的核心实体,它定义了“从何处拉取期望状态”、“部署到哪个目标集群”以及“如何执行同步”三个关键维度。本章将深入解析 Application 清单中的三大核心字段:Source、Destination 和 Sync Policy,帮助你在生产环境中精准控制每个应用的部署行为。

核心认知: Application 清单是一个声明式 YAML 文件,存储在 Git 仓库中,Argo CD 通过持续对比 Source 与 Destination 的差异来驱动集群状态收敛。

4.1 Source:定义期望状态的来源

Source 字段指定了 Argo CD 从哪个 Git 仓库、哪个分支、哪个路径拉取 Kubernetes 资源清单。它支持 Helm、Kustomize、Jsonnet 等多种配置管理工具。

4.1.1 Source 核心参数

参数 必填 说明 示例值
repoURL 是 Git 仓库地址,支持 HTTPS/SSH https://github.com/example/gitops-repo.git
path 是 仓库内资源清单的相对路径 environments/production/app
targetRevision 是 分支、标签或 commit SHA main 或 v1.2.3
helm 否 Helm 特定配置(values、参数覆盖) valueFiles: ["values-prod.yaml"]
kustomize 否 Kustomize 特定配置(namePrefix、images) namePrefix: prod-
directory 否 纯 YAML 目录的递归/排除规则 recurse: true

4.1.2 多 Source 与多目标模式

Argo CD 2.6+ 支持 多 Source(Multi-Source),允许一个 Application 从多个 Git 仓库或同一仓库的不同路径合并资源。这在微服务架构中尤为实用:基础层(如 CRD、RBAC)来自一个仓库,业务层来自另一个仓库。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: multi-source-app
spec:
  sources:
    - repoURL: 'https://github.com/example/infra-base.git'
      targetRevision: main
      path: crds
    - repoURL: 'https://github.com/example/app-config.git'
      targetRevision: release-1.0
      path: overlays/production
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
多 Source 注意事项: 多个 Source 的资源合并顺序由 Argo CD 内部决定,若存在资源名称冲突,后合并的 Source 会覆盖前者。建议通过命名空间或资源前缀隔离不同 Source 的资源。
多 Source 合并流程 Source 1: infra-base CRDs / RBAC Source 2: app-config Deployments / Services Source 3: secrets Encrypted Secrets Argo CD 资源合并器 合并后的期望状态 统一资源清单 同名资源:后合并覆盖前 建议使用 namespace 隔离

4.2 Destination:定义目标集群与命名空间

Destination 字段告诉 Argo CD 将应用部署到哪个 Kubernetes 集群的哪个命名空间。它支持单集群、多集群(通过 Cluster Secret)以及控制平面自身。

4.2.1 Destination 核心参数

参数 必填 说明 示例值
server 是 目标集群的 API Server URL https://kubernetes.default.svc(本地集群)
namespace 是 目标命名空间,若不存在则自动创建 production
name 否 集群名称(与 server 二选一) prod-cluster-01

4.2.2 多集群部署模式

通过 Argo CD 的 Cluster Secret 机制,可以注册多个外部集群。Application 的 Destination 指向不同集群,实现“一次 Git 提交,多集群同步”。

# 注册外部集群的 Secret 示例
apiVersion: v1
kind: Secret
metadata:
  name: prod-cluster-01
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
  name: prod-cluster-01
  server: https://192.168.1.100:6443
  config: |
    {
      "bearerToken": "<your->",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "<base64-ca>"
      }
    }
生产建议: 对于多集群场景,建议使用 name 字段而非 server 字段,因为集群 URL 可能变更,而名称更稳定。同时,为每个集群创建独立的 Cluster Secret,并严格控制 RBAC 权限。

4.3 Sync Policy:定义同步行为与自动化策略

Sync Policy 决定了 Argo CD 如何将 Source 中的期望状态应用到 Destination 集群。它包含自动化策略、修剪策略、自愈策略以及同步选项。

4.3.1 同步策略核心参数

参数 子参数 说明 默认值
automated prune 是否自动删除集群中多余资源 false
selfHeal 是否自动修复集群中手动修改的资源 false
allowEmpty 是否允许 Source 为空时删除所有资源 false
syncOptions Validate 是否在同步前进行资源验证 true
CreateNamespace 目标命名空间不存在时自动创建 false
PruneLast 先同步新资源,最后再删除多余资源 false
ApplyOutOfSyncOnly 仅同步 OutOfSync 的资源,减少 API 调用 false
retry limit 同步失败时的最大重试次数 0
backoff.duration 重试间隔初始值 5s
backoff.factor 重试间隔倍增因子 2
backoff.maxDuration 最大重试间隔 3m

4.3.2 三种典型同步策略配置

# 策略一:完全自动化(生产推荐)
syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - CreateNamespace=true
    - ApplyOutOfSyncOnly=true
    - PruneLast=true

# 策略二:仅自动同步,不修剪(安全模式)
syncPolicy:
  automated:
    prune: false
    selfHeal: false

# 策略三:手动同步 + 重试机制
syncPolicy:
  retry:
    limit: 5
    backoff:
      duration: 10s
      factor: 2
      maxDuration: 5m
自愈(selfHeal)风险提示: 启用 selfHeal 后,任何对集群资源的直接修改都会被 Argo CD 立即覆盖。这在生产环境中可能导致“配置漂移”被误修复。建议仅在 CI/CD 流水线完全接管资源管理时启用,并配合 PruneLast 降低风险。
同步策略决策流程 检测到 Git 变更 自动化? 等待手动同步 执行自动同步 Prune? 保留多余资源 删除多余资源 PruneLast 选项:先同步新资源,最后再执行删除操作,降低服务中断风险 ApplyOutOfSyncOnly:仅同步状态不一致的资源,减少 API 调用次数

4.4 三大字段协同工作示例

以下是一个完整的 Application 清单,展示了 Source、Destination 和 Sync Policy 如何协同工作,实现生产级 GitOps 部署:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-app
  namespace: argocd
spec:
  project: production

  # Source 定义:从 Git 仓库拉取 Helm Chart
  source:
    repoURL: 'https://github.com/example/helm-charts.git'
    targetRevision: main
    path: charts/web-app
    helm:
      valueFiles:
        - values-production.yaml
      parameters:
        - name: replicaCount
          value: '5'

  # Destination 定义:部署到生产集群
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: production

  # Sync Policy 定义:全自动化 + 安全选项
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - ApplyOutOfSyncOnly=true
      - PruneLast=true
      - Validate=true
    retry:
      limit: 3
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 2m
调优要点:
  • Source 调优: 使用 targetRevision 指向稳定分支(如 main 或 release-*),避免使用 HEAD 导致频繁同步。
  • Destination 调优: 为每个环境(dev/staging/prod)创建独立的 Cluster Secret,并在 Application 中通过 name 引用,便于集群切换。
  • Sync Policy 调优: 生产环境启用 PruneLast 和 ApplyOutOfSyncOnly,减少同步窗口内的资源波动;开发环境可关闭 selfHeal 允许临时调试。

4.5 常见问题与避坑指南

问题场景 根因 解决方案
同步后资源被意外删除 prune: true 且 Source 中移除了资源定义 启用 PruneLast 并配合 allowEmpty: false
手动修改集群资源后被覆盖 selfHeal: true 导致自动回滚 临时关闭 selfHeal 或使用 argocd app diff 确认差异
多 Source 资源冲突 不同 Source 定义了同名资源 使用 directory.exclude 排除冲突文件,或重构仓库结构
目标命名空间不存在 未启用 CreateNamespace 在 syncOptions 中添加 CreateNamespace=true
同步超时或失败 集群不可达或资源验证失败 配置 retry 重试策略,并检查集群连接状态