因为总是 OutOfSync 就忽略,结果真正的漂移也看不见了
目标
亲手在 argocd-cm 和 Application 这两处编写忽略规则,并用 CLI 的 diff 确认规则实际会把哪些行从比较中排除。亲眼看一看忽略得太宽时,会有什么东西跟着一起消失。
为什么重要
启用自动同步之后,很快就会遇到“总是 OutOfSync”。原因是 HPA 修改的 replicas、Webhook 插入的 sidecar、控制器添加的注解——这些东西无法写进仓库,却必然会出现在集群里。忽略规则就是处理它们的工具,但它有一种只往一个方向倾斜的力——忽略得宽,界面就安静下来;忽略得窄,界面就一直吵闹。 所以每个人都会倒向宽的一侧。宽规则的代价不会马上显现,要等到几个月后有人手工改了镜像却没有人知道的那一天才会暴露。养成习惯,不靠猜测来写规则,而是亲眼确认“这条规则会删掉的行”之后再提交,就能避免这个代价。
步骤
- 在
/root/ga-ignore/live.yaml中创建ga-ignore命名空间的 Deploymentweb——spec.replicas为 4,容器有两个:app(镜像nginx:1.25)和sidecar(镜像envoy:1.31),并在metadata.annotations中放置deployment.kubernetes.io/revision: "7"。/root/ga-ignore/argocd-cm.yaml是data: {}的空 ConfigMap。把argocd admin settings resource-overrides ignore-differences /root/ga-ignore/live.yaml --argocd-cm-path /root/ga-ignore/argocd-cm.yaml的输出保存到/root/ga-ignore/none.txt。 - 在
/root/ga-ignore/argocd-cm-pointer.yaml中放置键resource.customizations.ignoreDifferences.apps_Deployment,并用jsonPointers只忽略/spec/replicas一项。把针对/root/ga-ignore/live.yaml的输出保存到/root/ga-ignore/pointer.txt。 - 在
/root/ga-ignore/argocd-cm-jq.yaml中用一个jqPathExpressions,只忽略名称为 sidecar 的容器的 image。把输出保存到/root/ga-ignore/jq.txt。app 容器的镜像不能被排除。 - 在同一个
/root/ga-ignore/argocd-cm-both.yaml中同时放置jsonPointers(/spec/replicas)和jqPathExpressions(sidecar 镜像),并把输出保存到/root/ga-ignore/both.txt。两者都要被排除,而 app 容器的镜像必须保留。 - 在
/root/ga-ignore/argocd-cm-wide.yaml中用jsonPointers忽略/spec整个,并把输出保存到/root/ga-ignore/wide.txt。这份输出里连容器镜像那一行都包含在内——也就是说,即使有人偷偷修改镜像,也不会被比较发现。 - 在
/root/ga-ignore/argocd-cm-mfm.yaml中用managedFieldsManagers只放kubectl一项,并把输出保存到/root/ga-ignore/mfm-only.txt。接着在/root/ga-ignore/argocd-cm-mfm2.yaml中同时放置同样的managedFieldsManagers和jsonPointers(/metadata/annotations),并把输出保存到/root/ga-ignore/mfm-plus.txt。看一看两份输出有什么不同。 - 在同一个
/root/ga-ignore/argocd-cm-updates.yaml中放置两个键——resource.customizations.ignoreDifferences.apps_Deployment用jsonPointers忽略/spec/replicas,resource.customizations.ignoreResourceUpdates.apps_Deployment用jsonPointers忽略/metadata/annotations。针对同一个文件,把ignore-differences的输出保存到/root/ga-ignore/updates-diff.txt,把ignore-resource-updates的输出保存到/root/ga-ignore/updates-upd.txt。 - 在
/root/ga-ignore/application.yaml中创建 Applicationga-ignore-web(命名空间argocd,项目default),并应用到 kwok 集群。在spec.ignoreDifferences中放一个 group 为apps、kind 为Deployment的条目,其中同时放入/spec/replicas指针和用来选出 sidecar 镜像的 jq 表达式。然后在/root/ga-ignore/ignore-matrix.tsv中写至少四行<ConfigMap파일>\t<찾을 글자>\t<yes|no>(占位符依次为 ConfigMap 文件、要查找的字符、yes 或 no),用/root/ga-ignore/check-ignore.sh全部检查,并把输出保存到/root/ga-ignore/ignore-result.txt。脚本只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。
参考
- 键名是
resource.customizations.ignoreDifferences.<그룹>_<종류>(占位符依次为组、类型),分隔符是下划线。 - 输出中以
<开头的行,就是被排除在比较之外的行。 - 要按条件挑选数组元素,使用 jqPathExpressions。JSON 指针只能指向位置编号。
- 常见错误:对同一个类型写两次规则块——键会重复,只剩后面那一个。
- 常见错误:为了消除 OutOfSync 而把
/spec整个忽略。 - 参考:https://argo-cd.readthedocs.io/en/stable/user-guide/diffing/
先看没有规则时的输出
在 /root/ga-ignore/live.yaml 中创建 ga-ignore 命名空间的 Deployment web——spec.replicas 为 4,容器有两个:app(镜像 nginx:1.25)和 sidecar(镜像 envoy:1.31),并在 metadata.annotations 中放置 deployment.kubernetes.io/revision: "7"。/root/ga-ignore/argocd-cm.yaml 是 data: {} 的空 ConfigMap。把 argocd admin settings resource-overrides ignore-differences /root/ga-ignore/live.yaml --argocd-cm-path /root/ga-ignore/argocd-cm.yaml 的输出保存到 /root/ga-ignore/none.txt。
如果一条规则都没有,这条命令不会编造判定,而是说“没有配置”。后面的步骤会一直把这个文件当作材料,所以请把值设置准确。
指向一个字段并把它排除
在 /root/ga-ignore/argocd-cm-pointer.yaml 中放置键 resource.customizations.ignoreDifferences.apps_Deployment,并用 jsonPointers 只忽略 /spec/replicas 一项。把针对 /root/ga-ignore/live.yaml 的输出保存到 /root/ga-ignore/pointer.txt。
JSON 指针是沿斜杠向下的路径。输出中以 < 开头的行就是“被排除在比较之外的行”——只应少掉 replicas 这一行,容器镜像必须原样保留。
要在数组中按条件挑选,只有 jq 可以
在 /root/ga-ignore/argocd-cm-jq.yaml 中用一个 jqPathExpressions,只忽略名称为 sidecar 的容器的 image。把输出保存到 /root/ga-ignore/jq.txt。app 容器的镜像不能被排除。
JSON 指针只能按位置编号指向数组,所以顺序一变,就会忽略掉不该忽略的元素。用 jq 表达式则可以像 select(.name == "sidecar") 这样按条件挑选。表达式请从 .spec.template.spec.containers[] 开始写。
在一条规则中同时使用两种方式
在同一个 /root/ga-ignore/argocd-cm-both.yaml 中同时放置 jsonPointers(/spec/replicas)和 jqPathExpressions(sidecar 镜像),并把输出保存到 /root/ga-ignore/both.txt。两者都要被排除,而 app 容器的镜像必须保留。
针对同一个类型的规则块只有一个,两个列表并排放在其中。如果想把规则按类型拆成多个块,键会重复,只剩后面那一个。
忽略得太宽,漂移就永远看不到
在 /root/ga-ignore/argocd-cm-wide.yaml 中用 jsonPointers 忽略 /spec 整个,并把输出保存到 /root/ga-ignore/wide.txt。这份输出里连容器镜像那一行都包含在内——也就是说,即使有人偷偷修改镜像,也不会被比较发现。
消除 OutOfSync 最快的办法就是忽略得宽,所以这也是现场最常犯的错误。请比较第 4 步的输出和这份输出里是否能看到 nginx 这个字符串。
按管理者名称忽略的规则无法预览
在 /root/ga-ignore/argocd-cm-mfm.yaml 中用 managedFieldsManagers 只放 kubectl 一项,并把输出保存到 /root/ga-ignore/mfm-only.txt。接着在 /root/ga-ignore/argocd-cm-mfm2.yaml 中同时放置同样的 managedFieldsManagers 和 jsonPointers(/metadata/annotations),并把输出保存到 /root/ga-ignore/mfm-plus.txt。看一看两份输出有什么不同。
这条规则是按“是谁写的字段”而不是按“哪个字段”来决定要忽略的对象。所以光看资源 YAML 算不出会排除什么,预览命令仅凭这个列表也什么都渲染不出来。
同步判定与唤醒调谐循环是不同的旋钮
在同一个 /root/ga-ignore/argocd-cm-updates.yaml 中放置两个键——resource.customizations.ignoreDifferences.apps_Deployment 用 jsonPointers 忽略 /spec/replicas,resource.customizations.ignoreResourceUpdates.apps_Deployment 用 jsonPointers 忽略 /metadata/annotations。针对同一个文件,把 ignore-differences 的输出保存到 /root/ga-ignore/updates-diff.txt,把 ignore-resource-updates 的输出保存到 /root/ga-ignore/updates-upd.txt。
这两个键的目的不同——前者是“这个差异不算 OutOfSync”,后者是“这个变更不会唤醒调谐循环”。后者是减轻控制器负载的旋钮,不会改变同步判定。请如实记录两份输出有什么不同。
只对单个应用生效的规则,以及回归检查
在 /root/ga-ignore/application.yaml 中创建 Application ga-ignore-web(命名空间 argocd,项目 default),并应用到 kwok 集群。在 spec.ignoreDifferences 中放一个 group 为 apps、kind 为 Deployment 的条目,其中同时放入 /spec/replicas 指针和用来选出 sidecar 镜像的 jq 表达式。然后在 /root/ga-ignore/ignore-matrix.tsv 中写至少四行 <ConfigMap파일>\t<찾을 글자>\t<yes|no>(占位符依次为 ConfigMap 文件、要查找的字符、yes 或 no),用 /root/ga-ignore/check-ignore.sh 全部检查,并把输出保存到 /root/ga-ignore/ignore-result.txt。脚本只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。
全局规则(argocd-cm)对所有应用生效,而 Application 的规则只对该应用生效。两者会合并后应用,所以先在全局放宽、再在应用里收窄是做不到的——收窄方向的规则,从一开始就应该放在应用一侧。表中请混入像 argocd-cm-wide.yaml 与 nginx 这样确认“这条规则会不会删掉这个字符”的行。