ArgoCD GitOps 正在成为 Kubernetes 持续部署的事实标准。它的核心理念只有一句话:把 Git 仓库当作集群状态的唯一可信源,任何部署变更都先改 Git,再由控制器把差异同步到集群。相比传统由人手动执行 kubectl apply 或在 CI 流水线里硬编码部署步骤,GitOps 让”集群现在是什么样”和”Git 里定义的是什么样”始终保持一致,出了问题 git revert 一条命令就能回滚。
一、为什么需要 GitOps
在 GitOps 之前,团队的部署可信源往往是”某个人脑子里的操作步骤”或”上次跑成功的 Jenkins 任务”。当集群被临时改坏、又被遗忘时,没有人说得清生产环境到底该是什么状态。GitOps 把这个问题彻底结构化:Git 里的清单即期望状态,控制器周期性比对实际状态,发现漂移(Drift)就自动或告警式修正。这和 GitHub Actions 实战:从零搭建 CI/CD 流水线 中”CI 负责构建与推送镜像”形成天然分工——CI 产出制品,CD 由 ArgoCD 负责落地。
| 维度 | 传统 CI/CD | GitOps |
|---|---|---|
| 部署触发 | 流水线主动推送 | Git 合并即触发 |
| 可信源 | 人或脚本记忆 | Git 仓库 |
| 集群漂移 | 难以发现 | 自动检测 OutOfSync |
| 回滚 | 手动重跑流水线 | git revert 即回滚 |
| 审计 | 日志分散 | Git 历史即审计 |
举个真实例子:某次线上抖动,值班同学为快速止血直接 kubectl edit 改了副本数和一处环境变量,故障暂时压住,但这次变更没有进任何仓库。两周后一次例行发布把 Deployment 覆盖回旧清单,问题原样复现,却没人能说清当初为什么改。如果走 GitOps,每一次变更都是一条带评审记录的 PR,这种”幽灵修改”从根源上就不会发生。
二、核心架构:三组件与同步循环
ArgoCD 由三部分协作:API Server(提供 UI/CLI/REST)、Repository Server(拉取并缓存 Git/Helm 清单)、Application Controller(持续比对实际状态与期望状态)。控制器每 3 分钟(默认)轮询一次,一旦发现 OutOfSync 就按策略同步。理解这套循环,是后续排查”为什么没同步”的基础,它运行在 K8s 入门:Pod、Deployment、Service 核心概念 之上的控制层。
三、GitOps 工作流:一次变更的生命周期
理解 GitOps 最好的方式是跟踪一次变更从开发到上线的完整链路。开发在功能分支提交清单改动并发起 PR,CI(例如 GitHub Actions)负责构建镜像、跑测试并把新镜像 tag 写回清单仓库;合并到 main 后,ArgoCD 在下一个轮询周期发现 Git 与集群不一致,自动拉取新清单并执行同步。整个过程里,人只和 Git 打交道,集群被视为”可由 Git 重建的声明”。
这条链路带来三个实打实的好处。其一,环境一致性:测试、预发、生产可以共用同一套清单模板,仅通过 overlays 或不同路径区分,再也不会出现”我机器上是好的”。其二,可审计:任何一次上线都能在 Git 历史里精确到人和时间。其三,可恢复:灾难恢复时只要把 Git 仓库克隆下来重新 apply,集群就能在分钟级重建。
值得注意的是,GitOps 并不排斥传统的 CI。相反,二者是黄金搭档——CI 保证”制品正确”,GitOps 保证”部署正确”。把镜像构建这类重活留在 CI,把只改 Git 的轻量同步留给 ArgoCD,职责清晰、互不打扰。
四、快速安装:Helm 一键部署
官方推荐用 Helm 安装,最省心。下列命令会新建独立命名空间并部署整套组件。如果不想用 Helm,也可以直接 kubectl apply 官方提供的 manifests 或 Kustomize 版本,本质一致,只是包管理方式不同。
# 添加 ArgoCD 官方 Helm 仓库并安装到独立命名空间
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
kubectl create namespace argocd
helm install argocd argo/argo-cd \
--namespace argocd \
--set server.service.type=ClusterIP \
--set configs.params.server.insecure=true
等待所有 Pod 进入 Running 后,即可通过端口转发访问 UI:kubectl port-forward svc/argocd-server -n argocd 8080:443。
五、第一个应用:Application 清单详解
ArgoCD 的核心资源是 Application,它声明”从哪个 Git 仓库、哪个路径、同步到哪个集群命名空间”。下面是一个最小可运行示例:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/manifests.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true # 删除 Git 中已移除的资源
selfHeal: true # 集群被手动改坏时自动修正
其中 automated.prune 与 selfHeal 是 GitOps 的两大护法:前者保证”Git 删了集群也删”,后者保证”有人手改集群会被自动拉回 Git 定义”。
六、声明式部署实战:从 Git Push 到集群生效
安装后,用 CLI 登录并触发首次同步:
# 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo
argocd login localhost:8080 --username admin --password <SECRET>
argocd app create guestbook \
--repo https://github.com/example/manifests.git \
--path guestbook --dest-server https://kubernetes.default.svc \
--dest-namespace default
argocd app sync guestbook
此后你只需向 Git 的 guestbook 路径提交变更,ArgoCD 会在下一个轮询周期自动拉取并同步,无需再碰 kubectl。这正是”持续部署”的精髓:部署动作被 Git 事件驱动。
七、多环境管理:App of Apps 模式
当应用变多,逐个维护 Application 会很痛苦。推荐 App of Apps 模式:用一个”父 Application”指向存放其他 Application 清单的目录,实现批量托管。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: apps-all
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/gitops.git
path: apps # 该目录下每个子目录都是一个 Application
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated: { prune: true, selfHeal: true }
| 状态 | 含义 | 处理建议 |
|---|---|---|
| Synced | 集群等于 Git | 正常,无需干预 |
| OutOfSync | 存在差异 | 自动或手动 sync |
| Healthy | 资源已就绪 | 正常 |
| Degraded | 资源异常 | 查 kubectl describe 事件 |
| Progressing | 同步进行中 | 等待完成即可 |
八、健康状态与自愈:Drift 检测与回滚
因为开启了 selfHeal,当有人误执行 kubectl scale 改了副本数,控制器会立刻把集群拉回 Git 定义。若一次发布导致 Degraded,最稳的回滚方式是回到上一个 Git commit 并同步——Git 历史就是你的部署审计与时光机。这一能力在复杂网络环境下尤其有价值,类似 Cilium 实战:用 eBPF 数据面替代 kube-proxy 踩坑记 中强调的”声明式即可恢复”。
需要提醒的是,selfHeal 并非对所有工作负载都该无脑开启。对于有状态应用(如数据库主从、消息队列),集群内部的运行态往往包含 Git 里无法表达的临时状态,盲目自愈可能打断正在进行的副本同步。这类负载建议关闭 selfHeal,改为仅告警、由人工确认后再同步,把”自动修正”降级为”自动发现”。
九、安全与可观测:RBAC、Webhook 与监控接入
生产环境务必收紧权限。ArgoCD 通过 ConfigMap 定义 RBAC 策略,把团队映射到角色:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, */*, allow
g, dev-team, role:developer
可观测性方面,把 ArgoCD 的 metrics 接入既有监控栈即可实时看到同步成功率:
# prometheus 抓取 ArgoCD metrics
- job_name: argocd
metrics_path: /metrics
static_configs:
- targets: ['argocd-metrics.argocd.svc:8082']
这与 Prometheus + Grafana 监控面板实战 的采集体系天然契合,也可和 Istio 服务网格入门:流量治理与 mTLS 实战 组合成完整的云原生可观测闭环。
十、常见坑位与排查清单
落地 ArgoCD 时,下面几个坑出现频率最高,建议上线前逐一核对:
- 仓库凭证失效:Private 仓库需配置 Repository Credentials 或 SSH key,否则控制器拉取超时,状态长期 OutOfSync。
- targetRevision 写死某个 tag:镜像更新后 Git 没变,ArgoCD 不会重新同步;建议生产用固定 commit 或分支,由 CI 负责更新引用。
- 有状态应用误开 selfHeal:参考第八节,避免自动修正打断副本同步。
- RBAC 过宽:默认账号权限很大,务必按团队拆分 role,遵循最小权限原则。
- 忽略 Sync Hook:数据库迁移等必须在同步前后执行的任务,应使用 Pre/Post Sync Hook 而非手动操作。
十一、行动清单:今天就能落地
- 用 Helm 在测试集群装一套 ArgoCD,熟悉 UI 与 CLI。
- 把一个现有 Deployment 改造成 Git 仓库里的清单,托管为第一个 Application。
- 开启
automated.prune + selfHeal,故意手改一次集群验证自愈。 - 接入 RBAC 与 Prometheus 抓取,让部署可审计、可观测。




