先说几个核心判断:Go 微服务与 Argo CD 之间,应当划定一条清晰的边界。服务本身只需专注于运行自己的 HTTP 服务,而 Argo CD 则专门负责从 Git 拉取 YAML 并同步到 Kubernetes 集群。任何在 Go 代码中直接调用 argocd CLI 或 SDK 的尝试,都属于方向性错误,必须立即纠正。
Application 的 spec.source.path 必须指向 manifests 目录,而非 Go 源码根目录
许多项目将 Go 源码整个推入 Git 仓库,然后让 Argo CD 的 Application 指向 . 或 cmd/,结果控制台反复报错 Unable to get app details: failed to load manifests。问题根源在哪里?
spec.source.path必须是一个已经git push的子目录,并且至少包含一个合法的*.yaml文件,例如manifests/prod/deployment.yaml。- 请牢记:Go 编译、镜像构建、Dockerfile 打包等操作都在 CI 阶段完成,Argo CD 只认最终的部署清单。
- 如果使用 Kustomize,路径必须指向包含
kustomization.yaml的目录,同时需要开启spec.source.kustomize.enabled: true。 - 本地开发时容易误用
file://或https://localhost作为repoURL,但在生产环境必须切换为真实的 Git 地址,例如https://git.example.com/myapp.git。
镜像更新不能靠手动修改 image: 字段,必须借助 argocd-image-updater 或 CI 脚本自动提交
CI 构建完 myapp:v1.2.3 后,如果仅仅打个 tag 就结束,Argo CD 完全不会感知——它只拉取 Git,不查询 Registry。
- 推荐做法:在 CI 脚本中使用
sed -i或envsubst更新manifests/prod/kustomization.yaml中的images:列表,然后执行git commit -m "chore(release): update myapp to v1.2.3"并git push。 - 更高级的自动化方案是部署
argocd-image-updater,它会定期轮询镜像仓库,匹配到kustomization.yaml中的name: myapp后,自动 patch 并提交 PR。当然,这需要配合 GitHub/GitLab 的 webhook 或定时任务来触发。 - 绝对要避免写死
image: myapp:latest。先不说latest标签不可追溯,argocd-image-updater默认也会忽略它。 - 如果项目使用 Helm,务必确保
spec.source.helm.valueFiles显式指定了values-prod.yaml,否则 updater 无法找到image.tag字段。
Go 服务 probe 配置不当,会导致 Argo CD 同步卡在 Progressing 状态
Argo CD 判断 Deployment 是否就绪,依赖 Kubernetes 的 healthStatus,而后者完全由 readinessProbe 决定。如果 Go 服务启动缓慢,加上 probe 设置过于激进,就会反复重启、同步超时,让人干着急。
initialDelaySeconds: 10是底线,不要设为1;periodSeconds: 5已经足够,高频 probe 对轻量 Go 服务而言是不小的压力。- probe handler 应使用最简逻辑:
http.HandleFunc("/ready", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })。切勿在上面挂载中间件链或检查 DB 连接池,那样只会拖慢启动速度。 - 建议禁用
startupProbe(Argo CD v2.8 之前对其支持不稳定),改用readinessProbe+initialDelaySeconds的组合更可靠。 - 如果使用了
livenessProbe,务必确保失败时进程能优雅退出(例如os.Exit(1)),否则 Argo CD 会一直看到CrashLoopBackOff状态,导致同步无法推进。
真正容易被忽视的是:Argo CD 的同步节奏与 Go 服务的启动节奏是异步的。它不会等你的服务 ready 了再开始部署 Deployment,而 readinessProbe 是你唯一能控制“何时算部署成功”的开关。这个边界如果没对齐,所有自动化的前提都会崩塌。
