第一篇:认识 Argo CD ------ 从传统发布到云原生 GitOps
第一次有人跟我提 Argo CD,我脑子里冒出来的第一反应是:又一个新工具?
那会儿我刚把 Kubernetes 的 Service、Ingress 折腾明白,正觉得"部署不就是 kubectl apply 一把梭"嘛。结果同事说,生产环境早就不这么干了,现在讲究 GitOps。我当场愣住:GitOps 又是什么鬼?Kubernetes 不是已经会自己维持状态了吗,怎么还要再套一层东西?
这篇就记录我把它彻底想明白的过程------从"我为什么要这玩意儿"到"它到底在我看不见的地方干了什么"。
一、先看传统发布是怎么一步步变成泥潭的
最朴素的发布方式,是老运维的做法:登录服务器,手工改配置,重启进程,靠脑子记"这台机器改过什么"。后来有了容器和镜像,流程进化成------把代码打成镜像,登录集群,kubectl apply 一下,完事。
这套流程听起来没毛病,用着用着就会发现几个扎心的事实:
- 谁在生产环境上改过什么,没人说得清。 昨天还好好的,今天突然出问题,一查发现有人前几天手工
kubectl edit了 deployment。 - 配置漂移。 每台机器、每个环境,时间一长就长得不一样。看起来"应该一样的配置",实际上早就分叉了,生产环境变成了独一无二的雪花,谁也复刻不出来。
- 发布全靠人肉。 顺序记不记得住另说,回滚基本靠运气------改回去十个文件,漏掉一个,接着炸。
这堆问题的根源是同一个:期望状态存在人的脑子里,而不是存在一个可靠的地方。
二、Kubernetes 是声明式的------那它为什么不叫 GitOps?
要理解 GitOps,得先搞清楚 Kubernetes 到底是怎么工作的。
Kubernetes 是个声明式 系统。你告诉它"我要 3 个 Pod"(replicas: 3),它不关心你是条条创建的还是一把 apply 的,它只关心一件事:实际状态到底是不是 3 个。
不是?控制器就开始干活。多了就删,少了就补。这套"不断对比实际状态和期望状态,然后把它拉向期望状态"的循环,在 Kubernetes 里有个正式名字,叫 reconciliation loop(调和循环)。Pod 挂了,ReplicaSet 控制器发现实际是 2 个、期望是 3 个,马上补一个起来------这就是大家常说的"K8s 自愈"。
看到这我冒出一个问题:那 Kubernetes 不是已经自带自愈了吗?这已经很 GitOps 了吧?
问题恰恰就出在这。
Kubernetes 的"期望状态"是存在 etcd 里的,而这份期望状态来自你最后一次 apply 或 edit 的 manifest。它是"你上次告诉它的那个状态",而不是"你 Git 仓库里那个状态"。
换句话说:kubectl apply 完之后,如果某个人又手工 kubectl edit 了生产环境,Kubernetes 不会反驳------它会老老实实把 edit 后的内容当成新的期望状态,一丝不苟地维持下去。
打个比方:Git 仓库是你的原始蓝图,集群是施工中的房子。 kubectl apply 相当于你亲手把蓝图拍在施工队面前:"就按这个干。"之后蓝图你收进保险柜,而施工队手里留着的,只是你刚才递过去的那一份。半夜有人偷偷改了施工队手里的图纸,房子就按错的建;你保险柜里的原始蓝图毫发无损------但没人知道。
这就是传统 apply 和 GitOps 的分水岭:前者是一次性 的"提交期望状态",交完就没人管了;后者是持续地"盯住期望状态",一有偏差就拉回来。
三、GitOps:把"唯一真实来源"锁进 Git
GitOps 的核心思想一句话就能说完:
Git 是整个系统状态的唯一真实来源(single source of truth)。
期望状态长什么样,以 Git 仓库为准,不以上一次 apply 为准,更不以某个人脑子里的记忆为准。
它由四个原则撑起来:
① 声明式------所有资源用 YAML 描述。描述的是"最终应该长什么样",而不是"怎么一步步把它干出来"。
② 版本控制 ------所有变化都变成 Git 提交,带作者、带时间、带 diff。谁改的、改了什么、为什么,全查得到。出问题 git revert 一下就完成了回滚------而且回滚的不是"代码",是整套环境的状态。
③ 自动同步------系统(也就是 Argo CD)发现 Git 里的描述和集群实际情况对不上,就自动把集群拉回 Git 描述的状态。
④ 自动恢复 ------哪怕有人绕过 Git,直接 kubectl edit 生产环境,系统检测到"集群偏离了 Git",也会把这次改动撤销,恢复成 Git 里的样子。
这里的关键机制是:GitOps 工具不是部署完就不管了 。它会周期性地把"Git 渲染出来的期望状态"和"集群里的实际状态"做一次 diff。有偏差,就叫 Drift(漂移) ;能自动纠正回来,就叫 self-healing(自愈)。
四、Argo CD 到底是个什么东西
Argo CD 就是把上面这套 GitOps 思想在 Kubernetes 里落地实现的工具------一个跑在集群里的持续交付工具。
有意思的是,它自己也以一组 Pod 的形式跑在 Kubernetes 里,所以它本质上也是个控制器------不过是个管"控制器"的控制器,你可以叫它元控制器(meta controller)。它靠三个组件分工:
- argocd-server:对外的大门。 Web UI、CLI、API 都从这进。你登录、点那个 SYNC 按钮,走的就是它。
- argocd-repo-server:图纸翻译官。 它负责从 Git 拉代码,把仓库里的内容渲染成真正的 Kubernetes manifest 。这一步很关键:如果仓库里存的是 Helm Chart 或 Kustomize 模板,直接
apply是行不通的,得先渲染成最终的 YAML,Repo Server 就是干这个的,还带缓存。 - argocd-application-controller:监工。 它不断比较"Git 渲染出来的期望状态"和"集群里的实际状态",一旦发现不一致就执行同步。它才是真正干活的核心。
把这三个角色用监工的比喻串一遍:Repo Server 是负责把保险柜里的蓝图复印出来的人;Application Controller 是拿着复印件天天在工地上核对的人;argocd-server 是前台------业主(也就是你)要来找监工汇报、下指令,都走前台。
至于"某个应用部署到哪、从哪个 Git 仓库来、怎么同步",这一切在 Argo CD 里被描述成一个叫 Application 的对象------一张写着"应用从哪来、到哪去"的清单。
五、一次发布在 Argo CD 里是怎么走完的
把前面所有东西串起来,一次发布大概是这么个流程:
开发改代码
↓
push 到 Git 仓库
↓
Argo CD 发现仓库变了
(默认轮询,约 3 分钟;配了 webhook 能秒级触发)
↓
Repo Server 把仓库内容渲染成 manifest
↓
Application Controller 把 manifest 和集群现状对比 → 发现不一致
↓
执行同步,把期望状态提交给 Kubernetes API
↓
Kubernetes 自己把 Pod 等资源收敛到期望状态
↓
应用发布完成
注意看最后两步:Argo CD 其实不直接"部署"Pod------真正部署的永远是 Kubernetes 自己。 Argo CD 干的事是"把该有的期望状态喂给 Kubernetes,并确保它不被任何人悄悄改掉"。
所以它站在 Kubernetes 之上,管的不是 Pod,而是描述 Pod 的那份定义。
六、小结
把这一篇收个尾,我记住的就是这几条:
- 传统发布靠人肉,容易漂移、难回滚、不知道谁改过生产环境。
- Kubernetes 是声明式的,但它只认"最后一次告诉它的期望状态",不认你的 Git 仓库。
- GitOps 把 Git 当成唯一真实来源,靠声明式 + 版本控制 + 自动同步 + 自动恢复四根柱子撑起来。
- Argo CD 是 GitOps 在 Kubernetes 里的实现,由 server / repo-server / controller 三个组件分工,核心是持续对比"期望"与"实际"、再纠正偏差。
写到这我还有一个没解决的疑问:自动同步这么省事,那生产环境直接开自动同步不就完事了?万一 Git 里推了个有问题的配置,岂不是全集群一起遭殃?这个"安全网"的问题------sync 策略、Prune(删除多余资源)、self-healing 开关、审批流程------我得动手装了之后才验证得了。
下一篇就装一个 Argo CD,部署第一个应用,把今天纸上谈兵的东西跑一遍。
------ 2026-08-24 · 学 Kubernetes 部署方式随手记