3. Git作为单一事实源
在 GitOps 模型中,Git 仓库不仅是代码的版本控制工具,更是整个系统的单一事实源(Single Source of Truth)。所有环境(开发、测试、预发布、生产)的期望状态都必须以声明式清单的形式存储在 Git 中。本章将深入剖析仓库结构设计、分支策略选择以及配置与代码分离原则,帮助你在实际项目中构建健壮的 GitOps 工作流。
3.1 仓库结构设计:单仓库 vs. 多仓库
选择仓库结构是 GitOps 落地的第一步。常见的模式有两种:单仓库(Monorepo)和多仓库(Multi-Repo)。下表从多个维度对比了两种模式的适用场景与优劣:
| 维度 | 单仓库(Monorepo) | 多仓库(Multi-Repo) |
|---|---|---|
| 管理复杂度 | 较低,所有配置集中管理,权限统一 | 较高,需跨仓库协调,权限粒度细 |
| 原子性回滚 | 支持,一次提交可同时更新应用和基础设施 | 不支持,需在多个仓库中分别回滚 |
| CI/CD 触发 | 需精细路径过滤,避免全量触发 | 天然隔离,变更只触发对应仓库 |
| 团队协作 | 适合中小团队,跨服务协作方便 | 适合大型团队,服务边界清晰 |
| 推荐场景 | 微服务数量 < 20,或基础设施与应用紧密耦合 | 微服务数量 > 50,或团队组织按服务划分 |
实践建议:对于大多数中大型项目,推荐采用混合模式:一个独立的
gitops-config 仓库存放所有环境的 Kubernetes 清单和 Helm values,而应用代码则按服务分散在各自的仓库中。这样既保持了配置的单一事实源,又避免了单仓库过大带来的性能问题。
3.2 分支策略:GitFlow vs. Trunk-Based
分支策略决定了变更如何流入 Git 仓库,并最终影响环境状态。在 GitOps 中,分支策略直接决定了环境一致性和发布节奏。以下是两种主流策略的对比:
| 特性 | GitFlow | Trunk-Based Development |
|---|---|---|
| 分支数量 | 多(master, develop, feature, release, hotfix) | 少(main + 短期 feature 分支) |
| 发布频率 | 低(按版本发布,通常每周/每月) | 高(每日多次,甚至持续发布) |
| 环境映射 | develop → 开发环境;release → 预发布;master → 生产 | main → 生产;短分支 → 开发/测试环境 |
| 回滚复杂度 | 较高,需在多个分支间协调 | 较低,直接 revert main 上的提交 |
| GitOps 适配度 | 中等,适合传统版本发布 | 高,天然匹配声明式持续同步 |
下图展示了 Trunk-Based 分支策略在 GitOps 中的典型工作流:
关键原则:在 GitOps 中,main 分支始终代表生产环境的期望状态。任何对 main 的提交都应触发 GitOps Operator 自动同步到生产集群。Trunk-Based 策略通过缩短分支生命周期,减少了环境漂移的风险,是 GitOps 社区推荐的首选方案。
3.3 配置与代码分离原则
将配置与代码分离是 GitOps 的核心实践之一。配置包括环境变量、数据库连接串、功能开关、资源配额等;代码则指应用二进制、Docker 镜像、Helm Chart 模板等。分离的好处在于:
- 安全隔离:敏感配置(如密钥)可以加密存储,不与代码一起暴露。
- 环境独立:同一份代码可以通过不同的配置部署到开发、测试、生产环境。
- 审计追溯:配置变更独立记录,便于合规审计和问题排查。
下图展示了配置与代码分离后的典型仓库结构:
3.4 配置分层与覆盖策略
在实际项目中,配置通常按环境和服务两个维度进行分层管理。以下是一个推荐的目录结构示例:
gitops-config/
├── environments/
│ ├── dev/
│ │ ├── namespace.yaml
│ │ ├── deployment.yaml
│ │ └── configmap.yaml
│ ├── staging/
│ │ ├── namespace.yaml
│ │ ├── deployment.yaml
│ │ └── configmap.yaml
│ └── prod/
│ ├── namespace.yaml
│ ├── deployment.yaml
│ └── configmap.yaml
├── helm-values/
│ ├── common.yaml # 所有环境共享的默认值
│ ├── dev.yaml # 开发环境覆盖
│ ├── staging.yaml # 预发布环境覆盖
│ └── prod.yaml # 生产环境覆盖
├── secrets/
│ ├── dev.enc.yaml # 使用 SOPS 加密
│ ├── staging.enc.yaml
│ └── prod.enc.yaml
└── kustomization.yaml # 顶层 Kustomize 入口
避坑指南:不要将数据库密码、等敏感信息以明文形式存储在 Git 仓库中。务必使用 SOPS、Sealed Secrets 或 External Secrets Operator 等工具进行加密管理。同时,确保
.gitignore 排除了所有未加密的敏感文件。
3.5 分支策略与配置分离的协同
将分支策略与配置分离结合,可以形成强大的 GitOps 工作流。以下是一个典型的协同流程:
- 开发阶段:开发者从 main 创建短分支(如
feature/add-logging),修改应用代码仓库中的源代码,同时修改配置仓库中environments/dev/下的配置。 - CI 构建:CI 流水线构建 Docker 镜像,并将镜像标签写入配置仓库的
environments/dev/deployment.yaml中。 - 自动同步:GitOps Operator 检测到配置仓库的 dev 目录变更,自动将新配置同步到开发集群。
- 预发布验证:通过 PR 将配置从 dev 合并到 staging 目录,触发预发布环境同步。
- 生产发布:PR 合并到 main 分支后,配置仓库的
environments/prod/被更新,GitOps Operator 自动将变更应用到生产集群。
核心收益:通过这种协同,每一次环境变更都有对应的 Git 提交记录,实现了完整的变更审计链。同时,由于配置与代码分离,运维团队可以独立管理配置,而无需接触应用源代码,降低了误操作风险。