argocd —— GitOps CLI
一句话定义
argocd 是 Argo CD(K8s 上最主流的 GitOps 工具)的命令行客户端,对 Argo CD 服务端发 API。Argo CD 本身跑在集群里、通过 web UI 操作,但 CLI 在自动化 / CI 流水线 / 紧急排错时不可替代。
典型场景
- 创建 / 查看 / 同步 Application:
argocd app create / get / sync - 看 OutOfSync 的具体差异:
argocd app diff - 看为啥同步失败:
argocd app get my-app - 手动登录 + token:CI 流水线用
- 添加私有 git repo
这篇文档假设你已经在集群里跑着 Argo CD(通过
helm install argocd或kubectl apply -n argocd -f install.yaml)。
装
# Linux
curl -sSL -o /usr/local/bin/argocd \
https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd
# macOS
brew install argocd
登录
Argo CD 默认有内置 admin 用户:
# 1. 拿初始密码(首次安装后)
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath='{.data.password}' | base64 -d
# admin password: xxx
# 2. 暴露 argocd-server(开发用 port-forward)
kubectl port-forward -n argocd svc/argocd-server 8080:443
# 3. 登录
argocd login localhost:8080 --username admin --password xxx --insecure
--insecure 因为 Argo CD 默认是 self-signed cert。
用 token 登录(CI 推荐)
# 在 web UI 里给 admin 或自定义账户生成 token,或:
argocd account generate-token --account ci-bot
# CI 里
argocd login argocd.example.com --auth-token $ARGOCD_TOKEN --insecure
context 管理
argocd 客户端配置在 ~/.argocd/config:
argocd context # 看 context
argocd context dev # 切
argocd logout argocd.example.com # 退出
跟 kubectl 思路一样——多集群多账号常用。
Application 是 Argo CD 的核心
一个 Argo CD Application = 一段 Git 仓库 → 一个 K8s 集群 / namespace 的映射。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
source:
repoURL: https://github.com/myorg/manifests
targetRevision: main
path: apps/my-app
destination:
server: https://kubernetes.default.svc
namespace: my-app
syncPolicy:
automated:
prune: true
selfHeal: true
CLI 操作就是围绕 Application 的 CRUD。
看 Application
argocd app list # 列所有
argocd app list -p my-project # 按 project
argocd app list -o wide # 加更多字段
argocd app get my-app # 单个详情
argocd app get my-app --refresh # 强制从 git 拉新对比
argocd app history my-app # 历史 revision
argocd app get 输出:
Name: my-app
Project: default
Server: https://kubernetes.default.svc
Namespace: my-app
URL: https://argocd.example.com/applications/my-app
Repo: https://github.com/myorg/manifests
Target: main
Path: apps/my-app
SyncWindow: Sync Allowed
Sync Policy: Automated (Prune)
Sync Status: Synced to main (abc1234)
Health Status: Healthy
GROUP KIND NAMESPACE NAME STATUS HEALTH
Service my-app my-app Synced Healthy
apps Deployment my-app my-app Synced Healthy
ConfigMap my-app my-app-config Synced Healthy
最关键两行:
- Sync Status ——
Synced/OutOfSync - Health Status ——
Healthy/Degraded/Progressing
同步:argocd app sync
argocd app sync my-app # 手动同步
argocd app sync my-app --prune # 删除 git 中已不存在的资源
argocd app sync my-app --force # 强制(删除冲突资源重建)
argocd app sync my-app --dry-run # 只看会做什么
argocd app sync my-app --resource '*:Deployment:my-app' # 只同步特定资源
自动同步 vs 手动
argocd app set my-app --sync-policy automated --auto-prune --self-heal
# 开启 auto sync + auto prune + auto heal
argocd app set my-app --sync-policy none
# 关闭自动 sync
生产推荐 automated + selfHeal:检测到漂移会自动 sync 回去。
看差异 / 排查 OutOfSync
OutOfSync 意味着 git 期望 vs 集群实际不一致。看差异:
argocd app diff my-app
# 显示 git 想要 vs 集群实际的 diff(unified diff 格式)
或者更精确:
argocd app manifests my-app --source git # git 中的渲染结果
argocd app manifests my-app --source live # 集群里实际的
排查"为啥 sync 失败":
argocd app sync my-app
# 失败 ...
argocd app get my-app -o json | jq '.status.operationState.message'
# 错误信息
argocd app logs my-app # 看 hook job 日志
添加 git repo
# 公开 repo
argocd repo add https://github.com/myorg/public-manifests
# 私有 repo(HTTPS + token)
argocd repo add https://github.com/myorg/private-manifests \
--username myuser \
--password ghp_xxx
# SSH key
argocd repo add git@github.com:myorg/private-manifests.git \
--ssh-private-key-path ~/.ssh/id_ed25519
argocd repo list
argocd repo rm https://github.com/myorg/public-manifests
添加远端集群(Argo CD 管多集群)
# 用你本地 kubeconfig 中的 context 注册
argocd cluster add my-cluster-context
# 列已注册集群
argocd cluster list
argocd cluster rm https://k8s.example.com
argocd cluster add 在目标集群里创建一个 ServiceAccount + 把 token 给 argocd-server。
创建 Application(CLI 方式)
argocd app create my-app \
--repo https://github.com/myorg/manifests \
--revision main \
--path apps/my-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace my-app \
--sync-policy automated \
--auto-prune \
--self-heal
或者更"GitOps"——把 Application 本身写成 yaml、apply:
kubectl apply -f my-app-application.yaml
生产推荐 yaml,version control。CLI 创建适合临时 / 实验。
ApplicationSet(批量生成 Application)
ApplicationSet 是 Argo CD 的 CRD,自动批量生成 Application——比如"每个 git 仓库一个 app" / "每个 cluster 一个 app"。
kubectl apply -f appset.yaml
kubectl get applicationset -n argocd
kubectl get app -n argocd # 看生成的 Application
CLI 操作 ApplicationSet 用 kubectl + 直接编辑 CRD,argocd CLI 对它支持有限。
Hook / Sync Wave
Argo CD 同步时可以加 hook(pre-sync / post-sync / sync-fail):
# manifests 里的 yaml
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
argocd.argoproj.io/sync-wave: "-1" # 同步顺序(小先后大)
CLI 看 hook 状态:
argocd app get my-app | grep -i hook
实战场景
1. CI 流水线触发 sync
# CI 里
argocd login argocd.example.com --auth-token $TOKEN --insecure --grpc-web
# 等待应用 healthy(部署完才往下走)
argocd app sync my-app --prune
argocd app wait my-app --health --sync --timeout 600
argocd app wait 阻塞直到条件满足,CI 常用。
2. 一次同步多个 app
for app in app1 app2 app3; do
argocd app sync $app --prune
done
# 或并行
argocd app list -o name | xargs -P 5 -I {} argocd app sync {}
3. 排查 "ComparisonError"
argocd app get my-app
# Sync Status: Unknown
# Message: ComparisonError: ...
通常:
- git repo 凭证错(
argocd repo list检查) - targetRevision 分支不存在
- path 错(manifests 目录拼错)
修后:
argocd app sync my-app --refresh
4. 强制 prune 卡住的资源
argocd app delete my-app # 默认带 cascade(删 git 同步的资源)
argocd app delete my-app --cascade=false # 只删 Application,保留 K8s 资源
kubectl 替代视角
Argo CD 的所有状态都是 K8s CRD,kubectl 也能管:
kubectl get app -n argocd # 列 Application
kubectl describe app my-app -n argocd # 详情
kubectl edit app my-app -n argocd # 改
kubectl get applicationset -n argocd
kubectl get appproject -n argocd
纯 kubectl 也能完成大部分操作——CLI 优势是更短、有 progress 显示。
常见踩坑
坑 1:登录失败 "transport closed by foreign host"
argocd login argocd.example.com
# FATA[0000] rpc error: code = Unavailable desc = transport closed
通常是 grpc 端口不通或 TLS 问题。试:
argocd login argocd.example.com --grpc-web --insecure
--grpc-web 让客户端走 HTTPS 而不是原生 grpc(H2)——适合通过 ingress 暴露的 argocd。
坑 2:admin 初始密码丢了
kubectl -n argocd patch secret argocd-secret \
-p '{"stringData": {"admin.password": "$2a$10$<bcrypt-hash>", "admin.passwordMtime": "'$(date +%FT%T%Z)'"}}'
或者更简单:
argocd admin initial-password -n argocd
或者重新生成密码:
kubectl -n argocd delete secret argocd-initial-admin-secret
kubectl -n argocd rollout restart deploy argocd-server
# 重启后看新的 argocd-initial-admin-secret
坑 3:自动 sync 卡 OutOfSync
argocd app get my-app
# Sync Status: OutOfSync
# Sync Policy: Automated ← 应该自动同步啊?
argocd app sync my-app
# Error: sync window blocks
可能在 sync window("非工作时间不允许 sync")。看:
argocd proj windows list default
# 或在 web UI 项目设置看
坑 4:被 webhook validation 拦下
argocd app sync my-app
# Error: admission webhook denied the request: ...
集群里有 admission webhook(PSP / OPA / Kyverno),同步的资源被拒。看 webhook 日志,按需修 manifests / webhook 策略。
坑 5:repo 添加成功但 sync 失败
argocd repo add ... --username u --password p
argocd app sync ...
# Error: failed to clone repo: authentication required
确认是否启用了 SSO / 2FA、token 是否过期、是否需要 deploy key。生产推荐 deploy key + SSH:
ssh-keygen -t ed25519 -f /tmp/argocd-deploy-key
# 把 .pub 加到 GitHub repo deploy keys(read-only)
argocd repo add git@github.com:org/repo.git \
--ssh-private-key-path /tmp/argocd-deploy-key
坑 6:自动 prune 删了不该删的
argocd app set my-app --auto-prune
# 一些"不在 git 里" 的资源被删了
auto-prune 删所有 Argo CD 认为"不该存在"的资源。如果你手动 kubectl apply 了一些没在 git 的资源,会被它清掉。
防御:用 argocd.argoproj.io/sync-options: Prune=false annotation 保护特定资源。
坑 7:CLI 版本和服务端不一致
argocd version
# argocd: v2.10.0
# argocd-server: v2.8.0
通常向下兼容,但偶尔遇到字段不支持。保持 CLI 和服务端同版本。
坑 8:sync 之后 status 没立刻变
argocd app sync my-app
# 立刻 argocd app get
# Sync Status: Progressing
需要时间收敛。用 argocd app wait:
argocd app sync my-app && \
argocd app wait my-app --health --sync --timeout 300