← 中文资源

简体中文版本

用 Argo CD 同步窗口实现发布冻结

通过 AppProject 的 syncWindows 在冻结期禁止自动同步,同时保留带审计的手动同步,用于真正的紧急修复。

阅读英文原文

概述

发布冻结通常只是口头或日历上的约定,而自动化并不会遵守日历。Argo CD 的同步窗口把冻结写进调谐逻辑:处于 deny 窗口时控制器停止自动同步,因此冻结期间合并到 main 也不会重启生产 Pod。关键在于 manualSync: true,如果连手动同步一起禁用,一次小故障就会因为无人能执行修复而升级为事故。窗口按顺序求值,越具体的规则优先,建议同时保留冻结期的 deny 与工作日的 allow。

步骤

  1. 在 AppProject 中声明冻结窗口与放行窗口:
syncWindows:
  - kind: deny
    schedule: "0 0 * * 6"
    duration: 48h
    timeZone: Europe/London
    applications: ["*"]
    manualSync: true
  - kind: allow
    schedule: "0 0 * * 1-5"
    duration: 120h
    timeZone: Europe/London
    applications: ["*"]
  1. 确认控制器实际生效的窗口:
argocd proj windows list payments
  1. 检查处于 OutOfSync 的应用在窗口内没有被自动同步:
argocd app get payments-api -o json | jq -r '.status.sync.status, .status.operationState.phase'
  1. 需要紧急发布时显式执行手动同步:
argocd app sync payments-api --server-side --prune --timeout 300

验证

窗口列表应显示正确的 schedule、duration、时区与 manualSync 标志。冻结期间应用应保持 OutOfSync,且 operationState.phase 为空;手动同步后,操作历史中会出现发起账号与此次 diff。若应用在冻结期仍然自动同步,先检查它是否仍属于 default 项目,因为窗口只作用于拥有该应用的 AppProject。

注意事项

  • 同步窗口不能阻止直接用 kubectl 修改资源,真正的冻结还需要准入策略配合。
  • 显式设置 timeZone,控制器默认使用 UTC,按本地时间书写的周六窗口可能提前或延后数小时。
  • 紧急覆盖后应在事故复盘中检查应用历史,确认变更内容与执行人。
  • 把冻结时间与覆盖流程写在同一个公告渠道,避免值班人员猜测是否可以手动同步。
  • 不要为了让窗口“简单”而禁用全部同步,失去紧急通道的代价远高于一次误发布。