
Argo CD 同步后应用仍显示 OutOfSync 怎么定位并忽略无关字段差异【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd执行一次 Sync 成功之后Application 的状态却仍然停在OutOfSync。这种情况在 Argo CD 中并不罕见同步操作本身没有失败而是 Git 中的期望状态和集群里的实际状态之间存在一些预期内的差异导致 diff 无法收敛。这篇文章针对的排查路径是先在 UI 中定位具体是哪个资源、哪个字段产生了差异判断差异来源然后使用 Argo CD 的 diffing customizationignoreDifferences等配置把无关字段从 diff 中排除最后重新触发比较验证状态恢复。依据来自 docs/faq.md 和 docs/user-guide/diffing.md。先定位确认差异出在哪个资源的哪个字段文档列出了同步成功后仍可能OutOfSync的典型原因见 docs/user-guide/diffing.mdmanifest 本身有 bug包含真实 K8s spec 之外的额外/未知字段。这些字段在从 Kubernetes 查询 live state 时会被丢弃于是出现检测到字段缺失的OutOfSync同步时禁用了 pruningpruning disabled而 Git 中已删除的资源还存在于集群需要被删除某个 controller 或 mutating webhook 在对象提交到 Kubernetes 之后修改了它使其与 Git 中的版本不一致Helm chart 使用了randAlphaNum这类模板函数每次调用helm template生成不同数据HPA 对象的spec.metrics会被 HPA controller 按特定顺序重排见 kubernetes issue #74099。文档给出的规避方式是在 Git 中把spec.metrics排成 controller 偏好的顺序。另外 docs/faq.md 还补充了两个常见现象resource limits 等带单位字段的假漂移Kubernetes 应用时会规范化数值例如1000m变成1、0.1变成100m、3072Mi变成3Gi、8760h变成8760h0m0s。Git 里的原始值和集群里规范化后的值不相等diff 就报差异。这类问题用后文的knownTypeFields定制解决。app.kubernetes.io/instance标签被其他工具抢先写入Argo CD 自动设置该标签并靠它判定哪些资源属于应用如果 Kustomize common labels 这类工具也在设置它会造成冲突。解决办法是在argocd-cm中设置application.instanceLabelKey文档推荐argocd.argoproj.io/instance。注意做这个改动后所有应用会变为 out of sync需要重新同步文档原文 NOTE。定位时先在 Argo CD UI 打开应用页面查看 SYNC STATUS 下各资源的差异明细确认差异字段属于上面哪一类是 manifest 自身问题、webhook/controller 注入字段、模板随机值还是数值规范化差异。差异字段能对上号之后才决定用哪条忽略路径。应用级在 Application spec 中配置 ignoreDifferences上游问题无法修复时Argo CD 允许按 JSON path 忽略差异支持 RFC6902 JSON pointerjsonPointers和 JQ path 表达式jqPathExpressions也可以按 live 资源metadata.managedFields中的 manager 忽略managedFieldsManagers。在 Application 的spec.ignoreDifferences中声明。文档示例忽略该应用下所有 Deployment 的spec.replicas差异spec: ignoreDifferences: - group: apps kind: Deployment jsonPointers: - /spec/replicasgroup是 Kubernetes API group 去掉版本号的部分。作用范围可以进一步收窄到具体名称和命名空间spec: ignoreDifferences: - group: apps kind: Deployment name: guestbook namespace: default jsonPointers: - /spec/replicas忽略列表中的某些元素时用 JQ 表达式按内容定位列表项例如忽略某个被注入的 init containerspec: ignoreDifferences: - group: apps kind: Deployment jqPathExpressions: - .spec.template.spec.initContainers[] | select(.name injected-init-container)忽略 live 资源中由特定 manager 拥有的字段group/kind可用*通配整个应用的所有资源spec: ignoreDifferences: - group: * kind: * managedFieldsManagers: - kube-controller-manager两个容易踩的写法细节pointer 路径中含有/时必须转义为~1例如忽略 Node 标签node-role.kubernetes.io/workerspec: ignoreDifferences: - kind: Node jsonPointers: - /metadata/labels/node-role.kubernetes.io~1worker如果集群里存在field not declared in schema报错managedFieldsManagers这类依赖静态 schema 的功能会受影响见 docs/faq.md 的field not declared in schema一节需要升级到包含相应 schema 的 Argo CD 版本或按文档给出的绕行方式处理。系统级通过 argocd-cm 配置忽略差异需要对该 Argo CD 实例的多个应用统一生效时把定制放在argocd-cmConfigMap 的resource.customizations下按group_kind命名 key。忽略特定资源类型的指定字段文档示例忽略MutatingWebhookConfigurationwebhooks 的caBundledata: resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: | jqPathExpressions: - .webhooks[]?.clientConfig.caBundle按 manager 忽略作用到指定类型忽略Deployment上由kube-controller-manager造成的变更data: resource.customizations.ignoreDifferences.apps_Deployment: | managedFieldsManagers: - kube-controller-manager对实例内所有应用的全部资源生效key 使用alldata: resource.customizations.ignoreDifferences.all: | managedFieldsManagers: - kube-controller-manager jsonPointers: - /spec/replicas关闭 status 字段比较。很多资源的status会被提交到 Git但status是 controller 用来持久化当前状态、不能作为期望配置下发的字段。通过resource.compareoptions关闭data: resource.compareoptions: | # crd - CustomResourceDefinitions # all - all resources (default) # none - disabled ignoreResourceStatusField: all文档 NOTE由于 CRD 的status常被提交进 Git建议在这类场景使用crd而不是none。忽略 Aggregated ClusterRole 带来的rules漂移。如果你使用 Aggregated ClusterRoles 且不想让 Argo CD 把rules变化当作需要 sync 的漂移事件apiVersion: v1 kind: ConfigMap metadata: name: argocd-cm data: resource.compareoptions: | ignoreAggregatedRoles: trueCRD 复用内置 K8s 类型导致的序列化差异。一些 CRD 复用了 Kubernetes 基础数据结构如argoproj.io/Rollout复用core/v1/PodSpec自定义序列化器可能把cpu: 100m重新序列化为cpu: 0.1造成误报漂移。解决方法是在argocd-cm中声明哪些 CRD 字段使用了内置类型apiVersion: v1 kind: ConfigMap metadata: name: argocd-cm namespace: argocd labels: app.kubernetes.io/name: argocd-cm app.kubernetes.io/part-of: argocd data: resource.customizations.knownTypeFields.argoproj.io_Rollout: | - field: spec.template.spec type: core/v1/PodSpec支持的 Kubernetes 类型列表见仓库内的 util/argo/normalizers/diffing_known_types.txt另外还支持core/Quantity和meta/v1/Duration。辅助手段与边界配置把多余资源排除出 sync 状态。某些资源由工具生成、不希望影响应用整体 sync 状态时可以给资源加注解见 docs/user-guide/compare-options.mdmetadata: annotations: argocd.argoproj.io/compare-options: IgnoreExtraneous文档 NOTE 明确该注解只影响 sync status如果资源健康度退化应用健康度仍然会退化。Kustomize 用户可以通过configMapGenerator的generatorOptions.annotations自动给生成的 configmap/secret 加这个注解文档建议可与Prunefalsesync option 搭配使用。JQ 表达式超时。JQPathExpression 求值默认限制 1 秒如果复杂表达式报 JQ patch execution timed out在argocd-cmd-params-cmConfigMap 中延长超时apiVersion: v1 kind: ConfigMap metadata: name: argocd-cmd-params-cm data: ignore.normalizer.jq.timeout: 5s验证配置是否生效以上配置分别落在 Application 的spec和argocd-cm/argocd-cmd-params-cmConfigMap 中。修改完成后按下面的方式核对检查配置内容kubectl get configmap argocd-cm -n argocd -o yaml确认resource.customizations各 key 拼写正确group_kind与目标资源一致Application 侧用kubectl get application name -n ns -o yaml查看spec.ignoreDifferences。触发重新比较后在 UI或argocd app get name查看应用 SYNC STATUS之前被忽略的字段不再出现在资源差异中。若差异确实只来自被忽略的字段应用状态应从OutOfSync回到Synced如果仍OutOfSync说明还有未覆盖的字段差异回到先定位一节继续核对差异明细。注意各机制的适用范围IgnoreExtraneous只影响 sync status 不影响健康度ServerSideDiff默认不包含 mutation webhook 的改动是否纳入需按 docs/user-guide/diff-strategies.md 单独配置注解。限制与边界忽略差异只能用于预期内的差异。manifest 自身的字段错误多余的未知字段应优先修 manifest而不是用jsonPointers绕过。managedFieldsManagers、Server-Side Apply 等依赖静态 schema 的能力在 schema 缺少字段时会报field not declared in schema升级版本是文档给出的根治方式。修改application.instanceLabelKey会让所有应用变为 out of sync必须重新同步变更前先评估影响面。【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考