GitOps 工作流:以 Git 为单一事实源
title: "GitOps 工作流完整指南:以 Git 为单一事实源" description: "系统学习 GitOps 工作流,理解声明式配置、版本控制、自动交付的核心原理,并使用 Flux 或 Argo CD 实现持续部署。" author: "免费在线教程" date: "2025-04-08"
什么是 GitOps 工作流?
GitOps 是一种以 Git 仓库 作为基础设施和应用配置的唯一真实来源的现代运维模式。它将开发人员熟悉的 Git 工作流(拉取请求、代码审查、合并)引入到运维领域,让基础设施和应用的声明式描述一起存储在 Git 中。当仓库中的配置发生变更时,由自动化控制器将期望状态同步到生产环境,确保系统始终与 Git 中定义的状态一致。
核心理念:如果你想改变集群状态,就去修改 Git 仓库。控制器保证把仓库里的描述变成现实,而不会再手动执行
kubectl apply或点击 Button。
GitOps 工作流的四大支柱
要真正理解 GitOps,需要先掌握它的四个基本原则:
1. 声明式配置
整个系统的期望状态都用声明式语言描述(如 YAML、JSON、Terraform HCL)。不写“怎么做的步骤”,只写“我想要什么结果”。例如,一个 Kubernetes 的 Deployment 清单就是一个声明:我想要 3 个副本的 Nginx 容器。
2. 版本化且不可变存储
所有声明式配置都存储在 Git 仓库中,享受 Git 带来的全部好处:版本历史、差异对比、回滚、审计日志。每一次环境变更都对应一次 Git 提交,环境状态完全可追溯。
3. 自动拉取(Pull-Based)同步
GitOps 的自动化控制器(Agent)运行在目标环境中,会主动拉取 Git 仓库的期望状态,并与实际状态持续对比。一旦出现偏差,要么自动修正,要么发送警报。这种“拉取”模式比外部推送更安全,因为集群不需要暴露给外部的 CI 系统。
4. 持续协调(Reconciliation Loop)
控制器通过一个无限循环不断检查:Git 仓库里的配置(期望状态)与实际运行环境的状态是否一致?如果不一致,就执行操作使其同步。这个循环也保证了即使有人手动修改了集群,GitOps 也能自动将其恢复为 Git 中定义的状态(自我修复)。
GitOps 工作流 vs 传统 CI/CD Push 模式
传统 CD 流水线通常是 Push 模式:CI 构建镜像 → 推送镜像仓库 → 然后 CD 工具直接调用 kubernetes API 或执行命令来更新应用。这种方式需要授权给 CI/CD 流水线访问集群的凭证,且部署结果受流水线当时状态影响。
| 对比维度 | 传统 Push 模式 | GitOps Pull 模式 |
|---|---|---|
| 驱动方式 | CI 系统主动推送更新 | 集群内 Agent 拉取配置 |
| 集群凭证 | CI 需要保存集群外网凭证 | 凭证在集群内部,无需外露 |
| 状态来源 | 流水线执行瞬间的配置 | Git 仓库里的声明式配置文件 |
| 环境修复 | 手动排查,可能漂移 | 持续自动协调,自动修复漂移 |
| 审计与回滚 | 查看 CI 历史或日志 | git log 与 git revert 直接完成 |
正因如此,GitOps 将部署操作的安全边界从 CI 系统转移到了 Git 和集群内部,大幅提升了安全性。
基础 GitOps 工作流:从代码合入到自动发布
下面是一个典型的端到端 GitOps 工作流(以 Kubernetes 为例),你只需要学会这一套流程就能覆盖 90% 的场景。
第 1 步:应用开发与代码提交
开发者修改应用代码,推送到应用仓库(App Repo)的特征分支,然后发起合并请求(PR)。合并到主干后触发 CI 流水线,完成单元测试、构建镜像并推送到镜像注册中心(如 Docker Hub)。
第 2 步:更新配置仓库(Config Repo)
关键区别:应用的部署清单并不放在应用仓库里,而是单独存放在一个环境配置仓库中。CI 在成功构建新镜像后,不会直接部署,而是会向配置仓库自动提交一个 PR,将 Deployment 或其他资源里的镜像 Tag 更新为新版本号(例如 v1.2.3)。
配置仓库的目录结构示例:
config-repo/
├── apps/
│ ├── frontend/
│ │ ├── deployment.yaml
│ │ └── kustomization.yaml
│ └── backend/
├── infrastructure/
│ └── monitoring/
└── clusters/
├── staging/
└── production/
第 3 步:合并配置 PR 并触发部署
经过审核后,运维或发布负责人将该 PR 合并到主分支。此时,部署在集群内的 GitOps 控制器(如 Argo CD 或 Flux)会自动检测到配置仓库的变化。
第 4 步:控制器自动同步
控制器将仓库的期望状态与集群实际运行状态进行对比(Diff),并决定需要创建、更新或删除哪些资源。随后自动将新版本的 Deployment 应用到集群,滚动更新 Pod。
第 5 步:持续监控与自我修复
部署完成后,控制器不会停止。它会每隔一段时间(例如 3 分钟)重新执行一次对比。如果有人手动修改了集群里的副本数,控制器会发现 Git 中仍然定义为 3 个副本,于是自动将其改回 3,从而实现自我修复。
实战:用 Argo CD 搭建一个 GitOps 工作流
下面以最受欢迎的开源工具 Argo CD 为例,展示最小化可行 GitOps 的实施步骤。
环境准备
- 一个可访问的 Kubernetes 集群(Minikube 或 Kind 亦可)
- 安装 kubectl 并配置好 context
- 一个 Git 仓库(GitHub/GitLab 等),用于存放应用配置
- 一个普通应用镜像(如
nginx:1.25)
安装 Argo CD
在集群中执行:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
等待所有 Pod 就绪。然后访问 Argo CD UI(默认使用 LoadBalancer 或 kubectl port-forward ):
kubectl port-forward svc/argocd-server -n argocd 8080:443
使用 CLI 获取初始密码:
argocd admin initial-password -n argocd
准备配置仓库
在你的 Git 仓库中创建一个目录 apps/nginx-deployment,并包含以下 YAML 文件:
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
将文件提交并推送到远程仓库。
创建 Argo CD Application
现在告诉 Argo CD 去监控你刚创建的配置仓库。可以通过 CLI 或 UI 创建 Application。下面使用 CLI 方式:
argocd app create nginx-app \
--repo <你的仓库地址> \
--path apps/nginx-deployment \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--sync-policy automated \
--auto-prune
--path指向仓库中存放清单的子目录。--sync-policy automated开启自动同步和自修复。--auto-prune允许控制器删除 Git 中移除的资源。
创建成功后,Argo CD 会立即从仓库拉取配置并在集群中创建资源。你可以在 UI 中看到应用状态变为 "Synced"(已同步)且 "Healthy"。
验证 GitOps 的自我修复能力
尝试手动修改集群中的副本数:
kubectl scale deployment nginx --replicas=5
等待几秒钟,观察 Argo CD 界面,应用状态会短暂变为 "OutOfSync"(不同步),然后控制器自动将副本数改回 2,状态再次变为 "Synced"。这就是 GitOps 的自动协调能力。
进阶:基于 Pull Request 的 GitOps 部署流水线
企业级实践通常会加入 PR 审查环节,避免直接推送配置变更。整个流程如下:
- 开发者在配置仓库中创建分支,修改应用的镜像 Tag。
- 提交 PR,触发自动化差异检查(可以在 PR 中展示一个“预览差异”,展示即将在集群上发生的变更)。
- 团队审核代码并合并。
- 合并事件触发 GitOps 控制器立即同步(或按照设定间隔同步)。
- 控制器执行滚动更新,并在 UI 上报告健康状态。
这种工作流将部署决策完全代码化、可视化,并且天然拥有审批和审计能力。
多环境与多集群的 GitOps 模式
当你有开发、暂存、生产等多个环境,甚至多个集群时,GitOps 也有成熟的模式。
按分支或目录划分环境
- 目录结构模式:在同一个配置仓库中使用不同目录代表不同环境,例如
clusters/staging和clusters/production。每个目录独立定义该环境的完整配置。Argo CD 可以为每个目录创建独立的 Application,指向不同的集群或命名空间。 - 分支模式:生产配置使用
main分支,暂存配置使用staging分支。这种模式灵活性较低,目录结构模式更为通用。
使用 Kustomize 或 Helm 管理环境差异
直接维护多个几乎相同的 YAML 文件会产生大量重复。一般会引入 Kustomize 或 Helm 来管理变量和补丁。Argo CD 原生支持 Kustomize、Helm、Jsonnet 等工具。推荐使用 Kustomize 的 overlay 模式,从一个基础配置中派生出环境特定配置。
GitOps 工具生态速览
虽然 Argo CD 和 Flux 是主流控制器,但它们只是 GitOps 生态的一部分。
- Argo CD:专注于持续部署,拥有强大的 Web UI,支持多集群管理,适合可视化与管理。
- Flux CD:CNCF 毕业项目,与 Kubernetes 控制器深度集成,强调可扩展性和自动化,适合偏好低资源消耗的团队。
- Jenkins X:内置 GitOps 理念的 CI/CD 平台,结合了 Tekton 和无服务器 Jenkins,适合从零开始的团队。
- Terraform Cloud / Atlantis:将 GitOps 思想用于基础设施即代码,通过 PR 触发
terraform plan和apply。
GitOps 最佳实践清单
在落地 GitOps 时,请记住以下关键点:
- 永远不要手动修改集群:所有变更必须通过 Git 提交产生。如果紧急修复需要直接操作,事后也必须反向回写到 Git。
- 分离应用源代码仓库与配置仓库:源代码仓库只关心代码与构建,配置仓库只关心部署状态。这样可以解耦开发与发布权限。
- 用好 Secrets 管理:敏感信息绝不以明文存入 Git。可使用 Sealed Secrets、External Secrets Operator 或 Vault 集成,在同步阶段将加密值解封。
- 启用自动同步但谨慎使用自动修剪:自动同步带来自我修复,自动修剪(删除 Git 中不存在的资源)需要谨慎,建议生产环境先用手动同步和告警,确认无误后再打开。
- 监控同步状态:为 GitOps 控制器设置健康告警,确保它能正常工作。同时关注应用的实际运行健康状态,而不仅仅是配置是否同步。
- 渐进式交付:将 GitOps 与 Flagger 或 Argo Rollouts 结合,实现金丝雀发布、蓝绿部署等高级发布策略,真正实现无风险的持续交付。
常见问题
问:GitOps 只能用于 Kubernetes 吗?
答:虽然起源于 Kubernetes 生态,但 GitOps 理念可用于任何由声明式配置管理的系统,包括虚拟机、无服务器、基础设施等。例如使用 Crossplane 管理云资源时,也可以采用 GitOps。
问:如果 Git 仓库宕机了,集群会受影响吗?
答:GitOps 控制器会在本地缓存一份最新的期望状态。短时间不可用只会暂停同步,不会影响正在运行的应用。长时间中断则需要考虑仓库高可用。
问:如何处理多个团队同时修改配置仓库的冲突?
答:这正是 Git 所擅长解决的问题。通过分支、PR 和合并策略处理冲突,与开发代码库的操作一致。这也强制团队实践更好的协作与沟通。
结语
GitOps 工作流将 Git 从单纯的代码版本库,提升为整个系统的控制平面。你只需要学习一次基于 Git 的协作方式,运维就能和开发使用同一套流程。从今天开始,尝试用一个简单的 Nginx 部署上手 Argo CD,你将很快体会到“将基础设施当作代码来审查”带来的信心与速度。
继续学习:查看我们《Argo CD 生产级实践》《Flux 入门到精通》以及《Kubernetes 声明式配置深入》系列教程。