GitOps 实践 以仓库为唯一事实源
彩球呐喊
6 min read
GitOps 实践 以仓库为唯一事实源
GitOps 的核心判断:集群里跑什么,不该由人手动敲命令决定,而该由 Git 仓库里声明的状态决定。一个控制器持续比对“仓库里的期望态”和“集群里的实际态”,不一致就自动拉平。它把发布、回滚、审计都收敛成 Git 的提交与合并。对需要多环境、多集群、多人协作的团队,GitOps 是把“谁改了什么、为什么、能不能回退”回答清楚的机制,也让“集群现在应该是什么样”有了唯一权威答案。
为什么是 Git 而不是控制台
手动 kubectl apply 留下的痕迹只在执行者脑子里,集群漂移后没人说得清“现在到底该是什么样”。把期望态写进仓库,每一次变更都可追溯、可评审、可回放。仓库即文档,也是事故时的恢复基准。当集群被误改,控制器会自动把它拉回仓库定义,这种自愈能力是手工操作给不了的,也把“恢复生产”从依赖某人的记忆变成了依赖一份文件。
基本闭环
- 把 manifest 或 Helm/Kustomize 产物提交到仓库。
- 控制器(运行在集群内)轮询或接收 webhook,拉取最新提交。
- 比对集群现状,有差异就 apply 拉平。
- 若集群被手动改坏,控制器检测后自动纠正回仓库定义。
# 回滚就是回退提交,控制器会跟着把集群拉回旧态
git revert HEAD
git push
注意回退的是“期望态”,控制器负责把它落到集群。若某次手动改绕过了仓库,它就成漂移,下一次同步会被覆盖——这正是 GitOps 想要的效果,也是它和“允许手工改集群”的根本分歧。接受这一点,才真正用对了 GitOps。
控制器:拉取还是接收推送
控制器同步有两种触发:定时轮询仓库,或仓库有变更时通过 webhook 主动通知。轮询实现简单、容错好,但同步有延迟;webhook 实时性强,但要保证控制器地址可达且鉴权可靠。生产常用两者结合:webhook 做近实时触发,轮询做兜底对账,防止通知丢失导致集群静默偏离。
目录结构即环境
clusters/
prod/
apps/
web.yaml
staging/
apps/
web.yaml
不同环境是不同的子目录或分支,避免一套配置误推到生产。经验上,环境隔离用目录比用分支更不容易误操作,因为分支切换是全局的、容易带错上下文,目录是显式的、改哪份就是哪份。多集群则再上层加集群名目录,结构一目了然,谁都能看懂哪份配置对应哪个环境。
漂移检测与审批
发布不再靠敲命令,而是提 PR。合并即生效,未合并不改集群。控制器报告“同步中 / 已漂移 / 已同步”三种状态,运维看面板就知道集群是否偏离仓库。漂移出现说明有人手改了集群或仓库,要去查根因,而不是默默覆盖了事。把漂移当告警而非常态,才是健康的 GitOps 实践,否则仓库迟早和实际脱钩。
密钥不能进仓库
GitOps 仓库是明文可达的,直接提交密钥等于公开。正确做法是用外部密钥管理,仓库只放对密钥的“引用”或“指针”,控制器在集群内解析成真实 Secret。具体可以用加密后入库的方案,密钥在仓库里是密文,只有控制器持有解密密钥;也可以仓库只放 Secret 名,真实值存在集群外的专用系统里。无论哪种,即便测试环境也别把明文密钥写进仓库,时间一长谁都记不清哪些仓库泄露过。
权限与护栏
控制器要有写集群的权限,权限过大,一旦仓库被恶意推送就能改全集群。最小权限加分支保护是必要的护栏:只允许特定分支合并、要求评审、对敏感路径加额外审批。把“谁能改生产”从“谁有 kubectl 权限”变成“谁的代码过了评审”,这是 GitOps 的安全价值,也是它能被审计的基础。没有护栏的 GitOps,等于把生产开关挂在了一个人人可推的仓库上。
与渐进式交付的衔接
GitOps 负责“把声明的状态落到集群”,但它本身不关心“怎么逐步放量”。把金丝雀、蓝绿这类发布策略叠加在 GitOps 之上,由另一个控制器读取仓库里的流量权重字段、逐步修改它,既保留仓库为事实源,又获得渐进发布能力。两者职责分离:GitOps 管“是什么”,发布控制器管“怎么切”。
踩坑清单
- 把密钥也提交进仓库,哪怕测试环境,也会扩大泄露面。用外部密钥管理,只在仓库放引用。
- 控制器权限过大,一旦仓库被恶意推送就能改全集群。最小权限 + 分支保护是必要的护栏。
- 大仓库里放所有环境,一次错误提交影响面很广。按业务或环境拆分仓库,爆炸半径更小。
- 只同步不校验,apply 成功但 Pod 一直 CrashLoop,状态显示“已同步”却不可用。要配合健康探针,把“能跑”也纳进事实源判断。
- 多人同时改产生竞争,没开 PR 审批就允许直推,等于把生产开关交给了每个人。
- 仓库和集群网络不通,控制器拉不到更新,集群静默停在旧态,要在监控里补“同步心跳”告警。
- 把 GitOps 当成纯发布工具,忽略它带来的审计价值,事故复盘时反而没留下变更记录。
GitOps 不消灭运维判断,它只是把“变更怎么发生”标准化。真正难的仍是写好那些 manifest,以及定清楚“什么算期望态”、谁有权改它。
1 view
0 likes
0 comments