GitOps 工作流解析:Pull vs Push 模式、Git 仓库作为单一事实来源、Operator/Agent 的角色

GitOps 的核心在于将声明式配置与自动化协调相结合。理解其工作流中的两种主要模式——Pull 与 Push,以及 Git 仓库作为单一事实来源(Single Source of Truth)和 Operator/Agent 的角色,是排查故障和设计高可靠发布系统的前提。

2.1 Pull 模式 vs Push 模式

GitOps 工作流根据协调触发方式分为 Pull 模式和 Push 模式。生产环境推荐 Pull 模式,因为它更安全、更符合声明式原则。

对比维度 Pull 模式(推荐) Push 模式
触发方式 集群内的 Operator/Agent 定期对比 Git 仓库与集群状态 CI/CD 管道或外部工具主动将配置推送到集群
安全模型 集群无需对外暴露 API,Agent 只读访问 Git CI 工具需要集群凭据,攻击面较大
网络要求 集群可访问 Git 仓库(出站) 外部工具可访问集群 API(入站)
状态收敛 持续自愈,自动修复漂移 仅推送时生效,漂移需额外检测
典型工具 Argo CD, Flux 传统 CI/CD + kubectl apply
故障排查要点: Pull 模式下,如果 Agent 无法拉取 Git 仓库(网络、认证、仓库变更),集群将维持最后已知状态,不会自动回滚。Push 模式下,如果 CI 管道推送失败,集群状态可能停留在中间状态,导致部分更新。

2.2 Git 仓库作为单一事实来源

在 GitOps 中,Git 仓库中存储的声明式配置(YAML、Kustomize、Helm Chart)是系统的期望状态。集群的实际状态必须无条件向 Git 仓库对齐。任何手动修改集群的行为都会被视为“配置漂移”,并被 Operator 自动纠正。

  • 期望状态:Git 仓库中的配置,是权威版本。
  • 实际状态:集群中运行的资源。
  • 协调循环:Operator 持续对比两者,将实际状态收敛到期望状态。
常见故障: 当 Git 仓库被错误合并(如错误的镜像标签、缺失的 ConfigMap),Operator 会立即将错误配置应用到集群,导致大规模故障。此时应使用 git revert 回滚仓库,而非手动修改集群。
Pull vs Push 工作流对比 Pull 模式(推荐) Git 仓库 Operator/Agent Kubernetes 集群 定期拉取 协调 Push 模式 Git 仓库 CI/CD 管道 Kubernetes 集群 触发 推送 Pull 模式:Agent 主动拉取 Git,集群无需暴露 API,安全性高,自动修复漂移。 Push 模式:CI/CD 主动推送,需要集群凭据,漂移需额外检测。

2.3 Operator/Agent 的角色

Operator(如 Argo CD Application Controller、Flux Kustomize Controller)是 GitOps 的“大脑”和“执行者”。它们运行在集群内部,负责执行协调循环(Reconciliation Loop)。

核心职责

  1. 监听 Git 仓库:定期轮询或通过 Webhook 感知仓库变更。
  2. 对比状态:将 Git 中的期望状态与集群实际状态进行 Diff。
  3. 执行同步:创建、更新或删除集群资源以对齐期望状态。
  4. 报告状态:将同步结果写回 Git(如更新 Commit Status)或展示在 Dashboard。

常见 Operator/Agent 对比

特性 Argo CD Flux v2
同步策略 手动/自动同步,支持 Prune 自动同步,默认启用 Prune
漂移检测 每 3 分钟(默认) 可配置间隔(默认 10 分钟)
回滚方式 UI 或 CLI 回滚到历史版本 Git revert 后自动同步
多集群支持 原生支持(Hub-Spoke) 通过 Kustomize 或 Cluster API
故障排查提示: 当 Operator 无法同步时,首先检查 argocd app get <app-name> 或 flux get kustomization <name> 的输出。常见错误包括:Git 认证失败、仓库 URL 变更、CRD 版本不匹配、资源冲突(如 Namespace 已存在)。
Operator 协调循环 Git 仓库(期望状态) Operator 对比 Diff 执行同步(Apply/Delete) Kubernetes 集群(实际状态) 拉取 有差异 更新 持续循环

2.4 故障排查关键点

  • Git 仓库访问性:Operator 是否有权限读取仓库?SSH 密钥或 是否过期?
  • 声明式配置语法:YAML 缩进错误、Helm 值类型不匹配、Kustomize 资源路径错误。
  • 资源冲突:尝试创建已存在的资源(如 Namespace、ClusterRole),或删除被其他资源依赖的对象。
  • Operator 版本兼容性:Operator 版本与 Kubernetes API 版本不匹配(如旧 Operator 不支持新 CRD)。
  • 网络策略:Pull 模式下,集群出站规则是否允许访问 Git 服务器?Push 模式下,CI 工具入站规则是否开放?
最佳实践: 始终在 Git 仓库中保留清晰的 Commit 历史,并使用 Signed Commit 确保配置来源可信。Operator 的日志(kubectl logs -n <namespace> <operator-pod>)是排查同步失败的第一手资料。