从流水线推机器到 GitOps

上一篇 CI/CD 讲的流水线,工作方式是:构建出镜像后,由流水线主动去「推」到目标环境——调 kubectl apply、调云 API。这种方式有个隐藏问题:集群里实际跑的版本,和 Git 仓库里写的版本,之间没有任何强制对应关系。有人在生产上手动 kubectl edit 改了个东西,Git 里完全看不出来,时间一长两边就漂移了。

GitOps 换了个方向:不再让流水线去推集群,而是让集群自己盯着 Git 仓库里那份声明,把自己对齐过去。你要改生产,就改 Git 仓库并合并——剩下的交给集群里的同步组件。Git 仓库因此变成了「唯一事实来源」:想知道生产跑的是什么,看仓库就够了。

传统流水线是「我推给你」;GitOps 是「仓库里写着应该是什么样,集群自己去对齐」。
本文核心知识点
  • 声明式你只在 Git 里写「要什么」,同步组件负责把它在集群里实现。
  • 唯一事实来源集群现状和 Git 仓库始终对齐,漂移会被立刻发现。
  • Argo CD最主流的 GitOps 工具之一,盯着仓库、把集群拉齐。
  • 回滚即回退 Git生产出问题,把仓库版本回退一下就行。
GitOps 与声明式交付配图:左侧发光仓库方块向右连到一排环境节点、中间环形同步箭头、右侧回流曲线箭头的蓝色扁平科技插画
仓库是图纸,环境是施工现场,同步组件就是那个不停把现场对齐图纸的监理。

声明式交付:Git 是唯一事实来源

GitOps 说的「声明式」,和 Terraform、Kubernetes 是同一个思路:你不写动作,只写期望。在 GitOps 里,这份期望就是放在 Git 仓库里的一堆 YAML——哪个服务跑什么镜像版本、副本数多少、暴露什么端口。

它和传统流水线最大的区别是方向反过来了:流水线时代是「构建产物 → 推送集群」,集群是被动的;GitOps 时代是「仓库声明 → 集群主动拉取对齐」,集群里有个组件一直在监听仓库。这么换来的好处很实在:任何一次环境变更,Git 历史里都能查到——谁、什么时候、把哪个镜像版本合进去的。想知道生产为什么是这个样子,git log 一翻就清楚了。

另一个好处是权限收敛:开发和发布人员不需要再持有生产集群的直接操作权限,他们能做的就是改仓库、提合并请求。真要对生产动手,得走代码评审——权限收紧的同时,审计链反而完整了。

Argo CD:让集群对齐仓库

Argo CD 是 Kubernetes 上用得最多的 GitOps 工具。它在集群里跑一个组件,持续盯着你指定的 Git 仓库路径,发现仓库里的声明和集群现状不一致,就把它对齐过去:

# 一个最小的 Argo CD 应用定义
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-prod
spec:
  project: default
  source:
    repoURL: https://git.example.com/platform/manifests.git
    path: overlays/prod
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: web
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

几个关键字段:repoURL + path 告诉 Argo CD 去哪个仓库的哪个目录读声明;destination 是对齐到哪个集群哪个命名空间;automated 表示发现漂移就自动同步回来。selfHeal: true 尤其关键——有人手动在集群里改了东西,Argo CD 发现和仓库不一致,会自动把它改回仓库里的样子,手工漂移从此无处遁形。

多环境:一份配置,多套叠加

测试、预发、生产三个环境跑的是同一套服务,只是副本数、资源规格、副本数不同。GitOps 的做法和 Kustomize 天然契合:一份 base 声明,每个环境一个 overlay 叠加差异:

manifests/
├── base/
│   ├── deployment.yaml     # 服务名、镜像、基础配置
│   └── service.yaml
└── overlays/
    ├── dev/                # 副本数 1、小规格
    ├── staging/            # 副本数 2、中规格
    └── prod/               # 副本数 3、大规格、开 HPA

Argo CD 里就配三个 Application,分别指向 overlays/dev、overlays/staging、overlays/prod。服务本身的定义只写一份,环境差异全部在 overlay 里。想从预发推到生产,就是把同一份镜像版本号在 prod overlay 里改一下——全程走 Git 评审,没有任何一步是直接对生产集群动手。