4. 同步窗口配置实战:通过 ArgoCD ConfigMap 配置全局与项目级别的同步窗口

同步窗口(Sync Window)是 ArgoCD 中用于控制自动同步触发时段的策略机制。在生产集群排障场景中,错误配置的同步窗口可能导致应用在业务高峰期意外更新,或使紧急修复无法在窗口外生效。本章通过 ConfigMap 配置实战,分别演示全局与项目级别同步窗口的设定方法,并对比其生效优先级。

4.1 同步窗口核心概念与参数

同步窗口由 argocd-cm ConfigMap 中的 sync.window 字段定义。每个窗口包含以下关键属性:

参数 类型 说明 示例值
kind string 窗口类型:allow(允许同步)或 deny(禁止同步) allow
schedule string Cron 表达式,定义窗口生效的时间周期 * 9-17 * * 1-5
duration string 窗口持续时长,格式为 Nh、Nm 或组合 8h
applications string list (可选)应用列表,用于限定窗口影响范围 ["guestbook"]
namespaces string list (可选)命名空间列表,用于限定窗口影响范围 ["prod"]
clusters string list (可选)集群列表,用于限定窗口影响范围 ["cluster-*"]
timeZone string (可选)时区,默认 UTC Asia/Shanghai
排障要点: 同步窗口仅影响 自动同步(auto-sync)。手动触发同步(CLI 或 UI 点击)不受窗口限制,这在紧急回滚场景中至关重要。

4.2 全局同步窗口配置

全局同步窗口定义在 argocd-cm ConfigMap 的 sync.window 字段中,影响集群中所有 Application。以下配置禁止在工作日 9:00-17:00 之外的时间段自动同步:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  sync.window: |
    - kind: deny
      schedule: "* * * * *"
      duration: 1h
      timeZone: Asia/Shanghai
      applications:
        - "*"
    - kind: allow
      schedule: "* 9-16 * * 1-5"
      duration: 8h
      timeZone: Asia/Shanghai
      applications:
        - "*"

配置逻辑说明:

  • 第一条 deny 规则:全天候禁止同步,作为兜底策略。
  • 第二条 allow 规则:在工作日 9:00-16:00 开启 8 小时允许窗口,覆盖 deny 规则。
  • 生效顺序:ArgoCD 按列表顺序评估窗口规则,allow 规则优先级高于 deny 规则。
常见陷阱: 如果只配置 allow 窗口而不配置 deny 兜底,窗口外时段将处于“未定义”状态,ArgoCD 默认行为是 允许同步。务必使用 deny 规则明确禁止非窗口时段。

4.3 项目级别同步窗口配置

项目级别窗口通过 argocd-cm 中的 sync.window 字段配合 applications 或 clusters 筛选器实现,或直接在 AppProject CRD 的 spec.syncWindows 字段中定义。推荐使用 AppProject 方式,配置更清晰:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: production
  namespace: argocd
spec:
  syncWindows:
    - kind: allow
      schedule: "* 10-14 * * 1-5"
      duration: 5h
      timeZone: Asia/Shanghai
      applications:
        - "prod-*"
      clusters:
        - "https://kubernetes.default.svc"
    - kind: deny
      schedule: "* * * * *"
      duration: 1h
      timeZone: Asia/Shanghai
      applications:
        - "*"
  sourceRepos:
    - "*"
  destinations:
    - namespace: "*"
      server: "*"

项目级别窗口与全局窗口的优先级规则:

  • 项目窗口覆盖全局窗口:如果项目定义了 syncWindows,则全局 sync.window 对该项目内的 Application 不生效。
  • 项目内多窗口叠加:同一项目内允许多个窗口规则,按列表顺序评估。
  • 空项目窗口:如果项目未定义 syncWindows,则回退到全局窗口配置。

4.4 全局与项目窗口优先级决策流程

以下 SVG 图展示了 ArgoCD 在决定是否允许自动同步时的窗口评估流程:

同步窗口优先级决策流程 触发自动同步 项目定义了 syncWindows? 是 否 使用项目 syncWindows 使用全局 sync.window 按列表顺序评估窗口规则 允许 / 禁止自动同步 项目窗口优先于全局窗口;allow 规则优先于 deny 规则;手动同步不受窗口限制

4.5 配置验证与排障命令

配置完成后,使用以下命令验证同步窗口是否生效:

# 查看全局同步窗口配置
kubectl get configmap argocd-cm -n argocd -o jsonpath='{.data.sync\.window}' | jq .

# 查看项目级别同步窗口
kubectl get appproject production -n argocd -o jsonpath='{.spec.syncWindows}' | jq .

# 查看某个 Application 当前是否在同步窗口内
argocd app get guestbook -o json | jq '.status.sync.window'

# 实时监控同步窗口状态变化
argocd app wait guestbook --sync --timeout 300
排障案例: 某团队配置了全局 allow 窗口为 9:00-17:00,但未配置 deny 兜底。结果在凌晨 3 点 CI/CD 触发自动同步,ArgoCD 因无 deny 规则而允许同步,导致生产服务中断。修复方案:添加 deny 规则作为兜底,并设置 timeZone 为本地时区。

4.6 多窗口叠加与冲突解决

当同一作用域内存在多个窗口规则时,ArgoCD 按以下逻辑解决冲突:

  • 列表顺序优先:规则按在 syncWindows 或 sync.window 中出现的顺序评估。
  • allow 覆盖 deny:如果一条 allow 规则匹配当前时间,则允许同步,即使后续有 deny 规则匹配。
  • 精确匹配优先:如果规则中指定了 applications 或 clusters,则仅影响匹配的应用或集群,未匹配的应用不受该规则影响。

以下表格对比了不同配置场景下的最终行为:

场景 全局窗口 项目窗口 最终行为
1 未配置 未配置 始终允许自动同步(默认行为)
2 deny 全天 未配置 禁止自动同步(项目继承全局)
3 allow 9-17 deny 全天 项目窗口覆盖全局,禁止同步
4 deny 全天 allow 10-14 项目窗口覆盖全局,10-14 允许同步
5 allow 9-17 allow 14-16 项目窗口覆盖全局,仅 14-16 允许同步
最佳实践: 在项目级别配置同步窗口时,始终同时定义 allow 和 deny 规则,并将 deny 规则放在列表末尾作为兜底。这样即使 allow 规则因 Cron 表达式错误而失效,deny 规则仍能阻止非预期同步。

4.7 同步窗口与 GitOps 工作流集成

在实际 GitOps 排障场景中,同步窗口需要与以下组件协同工作:

  • AppSet 生成器:当 AppSet 生成大量 Application 时,同步窗口可以防止所有子应用同时触发同步,避免控制平面压力。
  • PR 驱动的同步:在 CI/CD 流水线中,PR 合并后触发的自动同步应严格受窗口控制,而紧急修复的 PR 应通过手动同步绕过窗口。
  • 样本留存策略:在窗口外发生的同步事件(如手动同步)应被记录到审计日志,作为排障样本留存。

以下 SVG 图展示了同步窗口在 GitOps 工作流中的位置:

同步窗口在 GitOps 工作流中的位置 Git 仓库 Webhook / 轮询 同步窗口 评估允许/禁止 ArgoCD 允许:执行自动同步 目标 Kubernetes 集群 禁止:记录日志,等待下一窗口