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 在决定是否允许自动同步时的窗口评估流程:
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 工作流中的位置: