概述
发布冻结通常只是口头或日历上的约定,而自动化并不会遵守日历。Argo CD 的同步窗口把冻结写进调谐逻辑:处于 deny 窗口时控制器停止自动同步,因此冻结期间合并到 main 也不会重启生产 Pod。关键在于 manualSync: true,如果连手动同步一起禁用,一次小故障就会因为无人能执行修复而升级为事故。窗口按顺序求值,越具体的规则优先,建议同时保留冻结期的 deny 与工作日的 allow。
步骤
- 在 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: ["*"]
- 确认控制器实际生效的窗口:
argocd proj windows list payments
- 检查处于 OutOfSync 的应用在窗口内没有被自动同步:
argocd app get payments-api -o json | jq -r '.status.sync.status, .status.operationState.phase'
- 需要紧急发布时显式执行手动同步:
argocd app sync payments-api --server-side --prune --timeout 300
验证
窗口列表应显示正确的 schedule、duration、时区与 manualSync 标志。冻结期间应用应保持 OutOfSync,且 operationState.phase 为空;手动同步后,操作历史中会出现发起账号与此次 diff。若应用在冻结期仍然自动同步,先检查它是否仍属于 default 项目,因为窗口只作用于拥有该应用的 AppProject。
注意事项
- 同步窗口不能阻止直接用 kubectl 修改资源,真正的冻结还需要准入策略配合。
- 显式设置
timeZone,控制器默认使用 UTC,按本地时间书写的周六窗口可能提前或延后数小时。 - 紧急覆盖后应在事故复盘中检查应用历史,确认变更内容与执行人。
- 把冻结时间与覆盖流程写在同一个公告渠道,避免值班人员猜测是否可以手动同步。
- 不要为了让窗口“简单”而禁用全部同步,失去紧急通道的代价远高于一次误发布。