暂停自动化不等于禁止所有变更
一句话总结
停止自动同步并不等于锁定所有变更。运维流程必须结合证据说明停止了什么,以及哪些操作仍然可以进行。
为什么需要它
暂停部署并开始重要检查后,却有人触发 manual sync,使新配置得到应用。如果认为关闭自动同步后就无人能够变更,就会错误解释事故原因。automation policy 决定 reconciler 何时自行行动,并不是移除所有 user request permission 或其他 deployment path 的机制。
maintenance mode 在不同团队中含义不同:可能继续比较 Git,只暂停 apply;也可能禁止 manual apply;还可能阻断 user traffic。这些并不是同一件事。如果把所有含义都塞进 UI 的一个 button,每个人都会想象不同状态并开始操作。本实验会分别观测 comparison、automatic apply 与 manual apply。
工作原理
在 parent template 中关闭 child automation 后,向 Git commit ConfigMap value two。Application 可以比较新 commit 并显示 OutOfSync,而 actual ConfigMap 中仍保留旧值 one。这并不表示无法读取 repository。sync.revision 指向新 commit,只有 actual data 保持旧值,说明 comparison 与 apply 已经分离。如果是 Git read failure,则应另行调查 condition 与 revision。
| 问题 | 确认依据 | 仅凭该依据无法知道的事 |
|---|---|---|
| 是否读取了新 Git? | 当前 sync.revision | actual data 是否已 apply |
| 是否关闭 automatic apply? | enabled=false 与重复观测 | manual apply permission 是否也被阻断 |
| 是否执行 manual apply? | operation result 与 actual value | automatic apply 之后是否重新开启 |
| 是否恢复正常 automation? | parent、child policy 与新 Git 的真实应用 | 所有外部运维路径是否都已验证 |
接着对同一个 commit 显式执行 manual sync。如果在保持 enabled=false 的情况下,actual data 变为 two,就直接证明了暂停 automation 与禁止 change 并非同一回事。应同时查看 operationState revision 与 phase、initiatedBy information、ConfigMap data 与 UID。initiatedBy username 是可随请求携带的 metadata,不能仅凭该字符串就声称已经证明 authenticated actor identity。预实验中,manual request 后有时还会保留先前 automated=true 显示。因此,不能只依赖该标记,而要关联 API 接受的 operation receipt、requested revision 以及 apply 前后 data,判断真实行为。
通过 kubectl 请求 Argo CD sync 时,operation 位于 Application 顶层,而不是 spec 内。该请求同样会导致真实 apply,不能与 dry-run 或 read query 混淆。本实验会指定准确 commit,并且不使用 prune 与 force。用于比较的 ConfigMap 和 Application UID 会一直保持。生产环境是否允许同类请求,还应同时审查 RBAC、approval procedure、sync window 与其他 deployment path。
现场会遇到的情况
有时无需停止全部 child,只要让某个 Application 暂时进入 manual operation。ApplicationSet 的 ignoreApplicationDifferences 可以声明 parent 在比较时应忽略的 child field。指定 name 可以限定某个 child,再通过 jsonPointers 收窄 target field。本实验只把 enabled 一个字段设为例外。如果无意间忽略整个 syncPolicy 或 source,会漏掉范围更广的 drift。
该例外改变的是 ApplicationSet 与 Application 之间的 comparison,并不是要求忽略 Application 与 ConfigMap 之间的 Git diff。名称中有 ignore,不表示所有 ignore setting 的 target 相同。请用完整句子说明:谁与谁比较时,不查看哪个字段。省略 target 的 exception 文档,往往会制造新误解,而不是解决问题。
exception 还需要结束条件:由谁解除、保留到何时、解除后用哪项新 change 验证 automatic apply。不能仅因当前页面显示 Synced,就判断 automation 已经恢复,因为手动对齐后的状态同样会显示 Synced。本实验会移除 exception,让 child 再次遵循 parent 的 true,然后确认 Git 中第三个 value three 是否自动生效。不得把既有 success 复用为新验证证据。
把 list 内 field 设为 exception 时,还有额外陷阱。ApplicationSet 使用的 MergePatch 可能整体替换已变化 list,导致其他项目的变更也覆盖 exception value。本实验把范围限定为 single source 与 scalar enabled field,不能泛化为 multi-source array 的所有变更组合都安全。此类情况应额外确认官方文档限制与真实 apply result。
下一项实验要做什么
连续三次观测“Git 已变化但未自动 apply”的状态,再比较同一 commit 的 manual apply。短暂使用一个有名称且范围狭窄的 exception,随后移除,并通过新的 Git change 验证 automation。三次短观测只是学习样本,并不能证明无限期禁止变更。最终报告要区分 automation pause 与 full deployment block,以及 internal observation 与 operational guarantee。无需停止全局 controller 或修改其他团队权限,也能理解这种差异。
官方文档
- 通过 kubectl 请求同步:确认 operation 与 result field 的位置。
- ApplicationSet 变更控制:阅读特定 child exception 与 MergePatch 限制。