“GitOps 一上多集群,为什么就开始天天打架?”——聊聊多集群 GitOps 的推广与冲突治理
这两年,GitOps 基本已经成了 Kubernetes 运维的“政治正确”。
- 不上 GitOps?
👉 显得不够云原生 - 只在单集群玩 GitOps?
👉 领导一句话:那能不能推广到所有集群?
于是问题来了。
GitOps 在单集群是信仰,在多集群往往是灾难。
如果你现在正经历下面这些场景,那这篇文章你一定会点头:
- 一个 YAML 改动,引发 10 个集群同时翻车
- 集群 A 正常,集群 B 同样的配置直接 Crash
- 运维、开发、SRE 在 Git 仓库里互相覆盖配置
- Argo CD / Flux 一直在 Sync,但你心里一点不踏实
今天我们就专门聊两件事:
- GitOps 在多集群环境,为什么这么容易冲突
- 怎么设计一套“能活下去”的冲突解决策略
一、先泼盆冷水:GitOps ≠ 自动化天堂
很多人对 GitOps 的第一印象是:
只要 Git 对了,集群就对了
但我负责任地说一句:
GitOps 真正的复杂度,不在 Git,而在 Ops。
尤其是多集群,一定会遇到三个“灵魂拷问”:
- 谁能改?
- 改的是“全局”,还是“某个集群”?
- 同一份配置,在不同集群是不是一定成立?
如果这三个问题没想清楚,GitOps 推得越快,事故来得越早。
二、多集群 GitOps,冲突从哪儿来?
1️⃣ 冲突一:配置的“作用域”不清晰
这是最常见、也最致命的。
很多团队一开始的仓库结构长这样:
repo/
├── deployment.yaml
├── service.yaml
└── ingress.yaml
后来集群多了,就开始在 YAML 里写判断:
replicas: {
{
if eq .cluster "prod" }}5{
{
else }}2{
{
end }}
你以为这是“灵活”,
实际上这是冲突制造机。
- Git 上看不出真实生效配置
- Review 根本没法做
- 出问题没人敢背锅
2️⃣ 冲突二:同一资源被多个 GitOps Controller 管
这是我见过最隐蔽的坑。
比如:
- 平台组用 Argo CD 管基础组件
- 业务组用 Flux 管应用
- 两边都“顺手”管了一点 Namespace / ConfigMap
结果就是:
GitOps Controller A:你咋又改我东西
GitOps Controller B:Git 上就是这么写的啊
然后你就会看到集群在反复自愈、反复被打回。
3️⃣ 冲突三:环境差异被假装不存在
多集群从来不是“多一份副本”那么简单:
- 云厂商不同
- CNI 不同
- LB 行为不同
- 存储类不同
但 GitOps 最大的诱惑是:
能不能一套 YAML 走天下?
答案很现实:
能跑,不代表跑得对。
三、我推 GitOps 多集群时的一个核心原则
我一直坚持一个非常“土”的原则:
多集群 GitOps,先分权,再复用。
听起来有点反直觉,但它救过我很多次命。
四、一个“能活”的多集群 GitOps 仓库结构
先上结构,再讲思想。
gitops-repo/
├── clusters/
│ ├── prod-cn/
│ │ ├── kustomization.yaml
│ │ └── patches/
│ ├── prod-us/
│ └── staging/
├── apps/
│ ├── payment/
│ │ ├── base/
│ │ └── overlays/
│ └── order/
└── platform/
├── ingress/
└── monitoring/
核心思想只有一句话:
集群是“最终裁决者”,应用只是“候选配置”。
五、用 Kustomize 明确“谁能覆盖谁”
这是我最推荐、也最稳的一种方式。
应用的 base(不带环境判断)
# apps/payment/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
集群级 overlay 决定最终状态
# clusters/prod-cn/patches/payment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 5
好处非常现实:
- Git Diff 一眼能看懂
- Review 能明确责任人
- 出问题知道该找谁
六、冲突治理的三条“铁律”
这是我踩坑之后总结出来的,真不是 PPT 上抄的。
✅ 铁律一:一个资源,只能有一个 GitOps Source of Truth
不管你用 Argo CD 还是 Flux:
- Namespace
- CRD
- ConfigMap
必须明确:谁管,谁说了算。
哪怕配置重复一点,也比“多头治理”强。
✅ 铁律二:禁止在 GitOps 仓库里写“环境判断逻辑”
别再搞这种了:
{
{
if eq .Values.env "prod" }}
你以为是工程能力,
实际上是运维债务。
环境差异,应该体现在:
- 目录
- overlay
- repo 边界
而不是模板里的 if-else。
✅ 铁律三:冲突不是技术问题,是权限问题
我说句可能有点扎心的:
GitOps 冲突 80% 不是工具选错,是权限没设计。
- 谁能 merge 到 base?
- 谁只能改自己集群目录?
- 紧急变更走不走 PR?
这些不想清楚,GitOps 只是把“人肉运维”变成“自动化打架”。
七、我对 GitOps 多集群的一点真实感受
说实话,GitOps 并不会让运维“更轻松”。
它只是:
- 把线上不确定性
- 提前到 Git 仓库里
你累的地方,从:
SSH 上机器
变成了:
Review PR、设计结构、管边界
但一旦跑顺了,你会发现:
- 回滚变得不再恐慌
- 多集群不再靠记忆
- 运维终于有“工程感”了
写在最后
如果你准备在多集群推广 GitOps,我送你一句压箱底的话:
GitOps 的敌人不是 Kubernetes,而是“所有人都能随便改”。
别急着全量推广,
先把冲突怎么发生、怎么停下来想明白。