argo cd 不应集成到 go 代码中,而应通过 git 中独立的 manifests 目录同步 yaml;spec.source.path 必须指向已提交且含合法 kubernetes 清单的子目录(如 manifests/prod),镜像更新需写回 git,推荐结合 argocd-image-updater 实现自动更新。

Argo CD 不该也不需要“集成”进 Go 代码里——它只读 YAML,不管 Go 怎么编译、怎么跑。真正要打通的,是 Go 微服务的构建产物(镜像)和 Git 中声明的部署清单之间的闭环。
spec.source.path 必须指向已提交的 manifests 子目录
很多人把 spec.source.path 设成 ./ 或 ./cmd,结果 Argo CD 一直报 Unable to get app details: failed to load manifests。原因很简单:它根本找不到 Kubernetes 清单文件。
-
spec.source.path必须是 Git 仓库中一个**已提交**的子目录,比如manifests/prod或infra/argocd/apps/order-service - 该目录下至少得有一个合法的
*.yaml文件(如deployment.yaml、service.yaml) - Go 源码结构(
cmd/、internal/、go.mod)和部署清单必须物理分离,不能混在同一个目录层级 - 如果用 Kustomize,路径要指向含
kustomization.yaml的目录,并显式开启spec.source.kustomize.enabled: true
镜像更新必须写回 Git,不能只推镜像
CI 构建完 my-registry/order:v2.1.0-abc123 后,若只推送镜像却不改 Git 中的 image: 字段,Argo CD 就永远同步旧版本。
使用约定式提交(Conventional Commits)从 Git 历史记录中生成结构化变更日志,支持多种格式、AI 增强型描述以及可自定义的范围……
- CI 脚本必须执行类似
sed -i 's/image: .*/image: my-registry\/order:v2.1.0-abc123/' manifests/prod/kustomization.yaml,再git commit -m "deploy: v2.1.0-abc123"并 push - 禁止使用
latest标签;镜像 tag 必须绑定 Git commit SHA 或语义化版本,确保可追溯 - 想自动更新?得额外部署
argocd-image-updater,它会轮询 registry 并 patchkustomization.yaml中的images:字段——Argo CD 自身不感知 registry 变更
probe 配置不当会导致同步反复失败
Argo CD 同步后 Pod 进入 CrashLoopBackOff,往往不是部署失败,而是 readinessProbe 太激进,服务还没启动完就被判定失败。
- 务必设置
initialDelaySeconds: 10和periodSeconds: 5,避免首次同步时因连接拒绝触发反复重建 - probe 路径用最简
/ready,直接由http.HandleFunc("/ready", )实现,不要依赖中间件或 DB 连接 - 禁用
startupProbe(Argo CD v2.8 之前支持不稳定),优先靠initialDelaySeconds缓冲启动时间 - 高频 probe(如
periodSeconds: 1)会在低配环境引发 CPU 尖刺,间接导致同步日志出现无明确错误的Failed sync attempt
生产环境别开 autoSync,手动确认才是安全底线
autoSync 看似省事,但一旦 Git 提交出错(比如误删了 Service 定义、改错了 namespace),Argo CD 会立刻把集群打挂,且没有缓冲窗口。
- 推荐设为
syncPolicy: { automated: { prune: true, selfHeal: false } },即允许自动同步 + 自动清理废弃资源,但禁用 selfHeal(防止误覆盖人工调整) - 所有上线操作应走 PR + Review 流程,合并后手动点一次 Sync,或通过
argocd app sync触发 - 回滚只需 revert 对应 Git commit,无需操作 CLI 或 UI——这是 GitOps 最核心的确定性保障
最容易被忽略的是:probe 的健康端点必须在应用二进制启动完成前就 ready,否则 Argo CD 会反复 kill-recreate Pod,掩盖真实部署问题。这点在 Go 应用里尤其容易踩坑,因为 net/http.ListenAndServe 默认是阻塞的,/ready handler 必须在主 goroutine 启动前注册好。










