1. GitOps 基础概念:声明式部署、Git 作为单一事实来源、GitOps 工作流与传统 CI/CD 的区别

1.1 声明式部署:定义“期望状态”而非“操作步骤”

传统运维模型通常采用命令式(Imperative)方式:运维人员通过 kubectl run、kubectl scale 等指令,一步步告诉系统“做什么”。GitOps 则完全转向声明式(Declarative)模型——你只需要在 Git 仓库中描述系统的最终期望状态,GitOps 控制器会自动将实际环境收敛到该状态。

核心区别:
命令式:“创建 3 个 Pod,副本数扩展到 5,然后更新镜像版本。”
声明式:“我的系统应该运行 5 个副本,镜像版本为 v2.1.0,暴露 8080 端口。”
GitOps 控制器负责将“当前状态”与“期望状态”之间的差异自动调和。

声明式配置通常以 YAML 或 JSON 格式存储在 Git 仓库中。以下是一个典型的 Kubernetes 声明式 Deployment 示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-service
  namespace: production
spec:
  replicas: 5
  selector:
    matchLabels:
      app: payment
  template:
    metadata:
      labels:
        app: payment
    spec:
      containers:
      - name: payment
        image: registry.example.com/payment:v2.1.0
        ports:
        - containerPort: 8080

1.2 Git 作为单一事实来源(Single Source of Truth)

在 GitOps 体系中,Git 仓库是整个系统的唯一权威来源。所有环境配置、应用版本、基础设施定义、策略规则都必须通过 Pull Request 提交到 Git,经审核合并后,由自动化流程同步到目标环境。任何手动修改集群的行为都被视为“配置漂移”,会被 GitOps 控制器自动回滚。

特性 传统运维 GitOps
配置存储位置 数据库、CMDB、运维脚本、文档 Git 仓库(唯一)
变更入口 SSH 登录、Web 控制台、临时脚本 Pull Request / Merge Request
审计追溯 分散、依赖日志聚合 Git 提交历史 + GPG 签名
配置漂移处理 人工巡检、告警后修复 自动调和(Reconciliation)
回滚方式 执行反向操作或恢复快照 git revert + 自动同步
实践要点:Git 仓库应遵循“环境即代码”原则,每个环境(dev/staging/production)有独立目录或分支,且所有敏感信息必须使用 Sealed Secrets、SOPS 或 External Secrets 加密存储,禁止明文提交密钥。

1.3 GitOps 工作流与传统 CI/CD 的对比

传统 CI/CD 流水线通常将“构建-测试-部署”视为一个连续管道,CI 阶段产出制品,CD 阶段将制品推送到环境。GitOps 则引入了一个关键转变:CD 阶段不再直接操作目标环境,而是通过更新 Git 仓库中的配置来触发环境同步。

传统 CI/CD 流水线 vs GitOps 工作流 传统 CI/CD 流水线 CI:构建 + 测试 CD:直接推送 目标环境(直接变更) ⚠ 常见问题 配置漂移、手动热修复、审计缺失、回滚困难 GitOps 工作流 CI:构建 + 测试 更新 Git 配置 Git 仓库(事实来源) GitOps 控制器(调和) 目标环境(自动同步) 回滚:git revert → 自动调和

1.4 关键差异总结

维度 传统 CI/CD GitOps
部署触发方式 CI 管道完成后直接调用 API 部署 CI 管道更新 Git 仓库,GitOps 控制器检测变更后同步
配置一致性 依赖部署脚本和运行时参数,易漂移 Git 仓库始终是权威状态,控制器持续调和
回滚机制 重新运行旧版本管道或手动恢复 git revert 提交,控制器自动回滚环境
权限控制 CI 系统通常拥有集群直接访问权限 仅 GitOps 控制器持有集群凭证,开发者通过 PR 间接变更
审计能力 依赖 CI/CD 平台日志,可能不完整 每次变更对应一个 Git 提交,可签名、可追溯、可复现
故障恢复速度 依赖运维人员介入和脚本准备 回滚提交后,控制器在秒级到分钟级自动恢复

1.5 GitOps 工作流核心步骤

  1. 开发者提交变更:修改应用代码或配置,发起 Pull Request。
  2. CI 流水线验证:运行单元测试、集成测试、安全扫描、镜像构建。
  3. 合并到主分支:代码审查通过后,PR 合并到 Git 仓库的主分支(如 main 或 release)。
  4. GitOps 控制器检测变更:控制器(如 Argo CD、Flux)轮询或通过 Webhook 感知 Git 仓库更新。
  5. 差异对比与调和:控制器比较 Git 中的期望状态与集群当前状态,生成差异报告。
  6. 自动同步:控制器将差异应用到目标环境,使集群状态与 Git 仓库一致。
  7. 持续监控:控制器持续运行调和循环,检测并修复配置漂移。
常见误区:GitOps 不等于“把 YAML 文件放到 Git 里”。真正的 GitOps 要求:
(1) 系统必须能够自动从 Git 同步状态;
(2) 任何手动变更都会被自动回滚;
(3) Git 仓库的提交历史就是完整的变更审计日志。
如果只是把配置文件存到 Git 但依然手动 kubectl apply,那只是“Git + 运维”,不是 GitOps。

1.6 为什么 GitOps 更适合自动化回滚

在传统 CI/CD 中,回滚通常意味着“找到上一个版本的制品,重新运行部署管道”。这个过程可能因为环境差异、依赖版本冲突、数据库迁移等问题而失败。GitOps 的回滚本质上是状态恢复而非操作重放:

  • 原子性:git revert 一次提交即可将整个环境的期望状态恢复到上一个已知正确版本。
  • 可测试性:回滚后的配置在 Git 中即可审查,无需先部署到环境。
  • 一致性:控制器确保回滚后的状态与 Git 仓库完全一致,不会遗留中间状态。
  • 速度:对于大规模集群,GitOps 控制器可以并行调和多个资源,回滚速度远快于逐一手动操作。