ArgoCD 常见问题与解决方案

devops进阶7 分钟阅读2026/10/26

ArgoCD 常见问题与解决方案:我踩过的坑和填坑方法

一开始的问题

去年我们团队把三十多个微服务迁到 ArgoCD 做持续部署,本以为就是“装好、连上 Git、点个 Sync”的事。结果第一个月我就被半夜叫醒三次:应用卡在 Progressing、镜像明明推了却不更新、还有一次同步直接把生产数据库的 Secret 给清了。这篇文章就是把我踩过的坑,连同排查和解决办法,一次性讲清楚。

问题一:镜像推了,但 ArgoCD 不更新

这是我们遇到频率最高的问题。CI 流水线显示镜像已推送到 Harbor,但集群里的 Pod 还是旧版本。

排查第一件事:先看 ArgoCD 究竟认为 Git 里应该是什么。打开 Application 详情页,对比 Desired Manifest 和 Live Manifest。如果两者一致,说明 Git 内容没变——问题在 Git 侧,不在 ArgoCD。

最常见的根因是:CI 更新了 Git 仓库里的 tag,但 ArgoCD 默认三分钟才轮询一次。我们的 CI 里写了 git commit && git push,然后立刻检查部署状态,当然查不到。两种解法:

方案 A:Webhook。在 Git 仓库配置 webhook 指向 https://<argocd-server>/api/webhook,并在 ArgoCD 里配好 Git 凭证。配完后推送基本秒级触发同步检测。

方案 B:CI 结束时手动刷新:

argocd app get my-app --refresh
argocd app sync my-app

另一个隐蔽的坑:镜像 tag 用了 latest 或可变 tag。ArgoCD 是声明式的,Git 里写 latest,实际运行镜像变了,Git 和集群看起来“一致”,ArgoCD 认为无事可做。解决办法是每条流水线用不可变 tag(比如 git-sha 或时间戳),或者启用 Image Updater。我们最终用 git commit sha 作为 tag,可追溯性也更好。

问题二:Application 一直卡在 Progressing

有一次一个应用卡了四十分钟。kubectl get pods 看都是 Running 的,但 ArgoCD 状态就是 Healthy: Progressing。

原因:ArgoCD 判断健康状态靠的是内置的健康检查逻辑,主要看 Deployment 的 replicas 是否全部 ready。我们有个 Deployment 配了 readinessProbe 指向一个返回 500 的接口——Pod 是 Running,但永远 Not Ready。所以记住:卡 Progressing 时先看 Pod 是否真正 Ready,再看探针配置。

还有一类更诡异的情况:用了 kind: Job 或 CronJob 的资源。ArgoCD 对这些资源默认的健康判断有延迟。可以在 Application 的 diff 里确认没有实际差异,然后等 Job 完成即可。必要时给资源加注解:

metadata:
  annotations:
    argocd.argoproj.io/ignore-healthcheck: "true"

不过这个要慎用,掩盖问题不如修复问题。

问题三:OutOfSync 死循环

有个应用同步完几秒又变 OutOfSync,无限循环。argocd app diff my-app 显示 Helm 渲染的值每次都不一样——具体是我们的 Chart 里有个字段生成了随机值(比如 randAlphaNum 生成的密码)。

解法是加 ignoreDifferences:

# argocd-ignore.yaml (Application 里配置)
spec:
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas

这里我顺便加了 replicas 的忽略,因为 HPA 在动态调副本数,ArgoCD 总想把它改回 Git 里写的数字——这是另一个经典问题:用 HPA 时必须忽略 replicas 字段,否则 HPA 和 ArgoCD 会打架。

另外还有自动 pruning 引发的惨案:有一次我重构目录,把一个 Service 资源从 Chart 里删了,ArgoCD 自动同步时直接把生产 Service 删了。从那以后我规定:自动同步开启的情况下,selfHeal 可以开,但 prune 必须关,删除资源一律手动确认:

syncPolicy:
  automated:
    selfHeal: true
    prune: false

问题四:Secret 管理和“明文进 Git”

GitOps 的原则是 Git 是唯一事实来源,但没人想把数据库密码明文提交。我们试过 Sealed Secrets,后来换成了 External Secrets Operator + Vault 的组合,Git 里只放 ExternalSecret 资源。这里注意一个问题:ArgoCD 默认会把 Secret 的 data 显示在 diff 里(虽然是混淆过的),建议配置:

resource.customizations:
  secret.argoproj.io/Secret:
    health.lua: ...

或者更简单地,在 Application 级别对 Secret 资源启用忽略。新版 ArgoCD 默认对 Secret data 做脱敏,确认你的版本 ≥ 2.x 即可。

问题五:App-of-Apps 与层级失控

服务多了以后,Application CRD 本身的管理成了问题。我们用 app-of-apps 模式:一个根 Application 指向一个专门存 Application 清单的仓库。这里有个坑:根应用删除子应用时,默认不会级联删除,会留下孤儿资源。给子应用的删除加级联,需要确认 cascade 行为,同时建议对所有 Application 资源加 finalizers 的理解——加了 resources-finalizer.argocd.argoproj.io 后,删 Application 会删真实资源,不加则只删记录。搞混这个的后果要么是资源泄漏,要么是误删。

实用技巧汇总

  1. 先看 diff 再动手:argocd app diff <app> 能解决 80% 的“为什么不同步”。
  2. 硬刷新:怀疑缓存问题时,UI 里点 Hard Refresh,或 argocd app get <app> --refresh --hard。
  3. 开启自动同步前先手动同步观察几天。
  4. 给每个环境独立的项目和仓库权限,用 ArgoCD 的 Project 做 RBAC,别都塞 default project。
  5. 保留一个紧急逃生通道:文档里写清楚 argocd app sync <app> --force 的使用场景——它会在不比较的情况下直接 apply,仅限事故恢复。

诚实的评价

ArgoCD 大幅降低了我们对“谁在集群里改了什么”的焦虑,审计能力是实打实的。但它不是免维护的:健康检查逻辑偶尔和真实情况脱节,Helm 变量渲染和 Git diff 的对齐需要精心配置 ignoreDifferences,Secret 管理方案必须提前设计好而不是事后补救。如果你团队规模小、服务少于十个,一个简单的 CD 脚本可能更划算;一旦服务多了、多环境了、多人协作了,ArgoCD 的声明式模型回报会非常大。建议从非关键服务开始灰度接入,把本文这几个坑在测试环境先趟一遍。

相关 Agent

D

Docker

Docker 是一个容器化平台,允许开发者将应用及其依赖项打包成轻量级、可移植的容器。它简化了跨环境的开发、测试和部署过程。该描述强调它最适合容器化和开发环境,提供免费方案和团队方案,团队方案从每用户每月5美元起。

了解更多 →