3. 声明式发布模型:声明式配置、期望状态与实际状态、Reconciliation 循环原理
声明式发布模型是 GitOps 的核心理念,它从根本上改变了运维人员与基础设施及应用的交互方式。与传统的“命令式”操作(手动执行 kubectl run、apply 或脚本)不同,声明式模型要求你只描述系统的“期望状态”,而将“如何达到该状态”的复杂逻辑交给控制器自动完成。
3.1 声明式配置:描述“要什么”,而非“怎么做”
在 GitOps 实践中,声明式配置通常以 YAML 或 JSON 文件的形式存储在 Git 仓库中。这些文件完整地定义了应用、基础设施、网络策略、存储卷等所有资源的最终形态。
核心原则: 声明式配置是幂等的。无论你将同一个配置提交多少次,只要期望状态不变,系统最终状态就不会改变。这消除了“配置漂移”的根源。
以下是一个典型的 Kubernetes Deployment 声明式配置示例,它描述了应用 my-app 的期望状态:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production
spec:
replicas: 5
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: registry.example.com/my-app:v2.1.0
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
这份配置明确声明了:
- 副本数:5 个 Pod 实例。
- 镜像版本:
v2.1.0。 - 资源配额:每个 Pod 的 CPU 和内存请求与限制。
- 命名空间:
production。
运维人员无需关心如何扩容、如何滚动更新、如何回滚,只需在 Git 中修改这个文件并提交。
3.2 期望状态与实际状态:永恒的“温差”
在任何一个分布式系统中,始终存在两个状态:
| 状态类型 | 定义 | 存储位置 | 示例 |
|---|---|---|---|
| 期望状态 (Desired State) | 你希望系统最终达到的、在 Git 仓库中声明的配置。 | Git 仓库(单一可信源) | Deployment 中定义的 replicas: 5 |
| 实际状态 (Actual State) | 系统当前正在运行的、实时的配置与拓扑。 | Kubernetes API Server / 运行时集群 | 当前集群中实际运行的 Pod 数量为 3 |
由于网络故障、节点宕机、手动干预、自动伸缩等事件,实际状态会不断偏离期望状态。这种“温差”是常态,而非异常。GitOps 的核心任务就是持续测量并消除这个温差。
灰度批次中的温差管理: 在灰度发布过程中,期望状态是“10% 流量到 v3,90% 到 v2”。实际状态可能因为 Pod 启动缓慢、健康检查失败而停留在“5% 流量到 v3”。Reconciliation 循环会持续工作,直到实际状态精确匹配期望的灰度比例。
3.3 Reconciliation 循环原理:GitOps 的“自动驾驶仪”
Reconciliation(调谐)循环是 GitOps 操作符(如 Argo CD、Flux)内部的无限循环逻辑。它持续执行“观察-对比-行动”的闭环,确保实际状态无限逼近期望状态。
下图展示了 Reconciliation 循环的核心流程:
3.4 循环的五个关键步骤
- 拉取配置: 操作符定期从 Git 仓库拉取最新的声明式配置,并与本地缓存对比。
- 同步期望状态: 将 Git 中的期望状态应用到 Kubernetes API Server(例如通过
kubectl apply)。 - 对比状态: 操作符查询 Kubernetes API Server,获取集群中所有资源的实际状态,并与期望状态进行结构化对比。
- 决策与执行:
- 如果存在偏差,操作符执行纠正操作(创建、更新、删除资源)。
- 如果无偏差,操作符进入等待周期。
- 等待与反馈: 等待预设的调谐间隔(如 3 分钟),然后重新开始循环。
灰度发布中的调谐陷阱: 在灰度批次发布时,如果调谐间隔设置过短(例如 10 秒),操作符可能会在旧 Pod 尚未完全终止、新 Pod 尚未通过健康检查时,反复尝试“纠正”状态,导致发布过程震荡。建议在灰度阶段将调谐间隔适当延长至 60-120 秒,或使用
sync-wave 等机制控制同步顺序。
3.5 声明式模型 vs 命令式模型
| 维度 | 声明式模型 (GitOps) | 命令式模型 (传统运维) |
|---|---|---|
| 操作方式 | 提交 Git 文件,描述最终状态 | 执行 kubectl run / edit / scale 等指令 |
| 状态管理 | 自动调谐,持续修复漂移 | 手动修复,依赖操作记录 |
| 回滚 | git revert 到历史提交 | 手动执行反向操作或依赖历史命令 |
| 审计 | Git 日志天然提供完整审计链 | 需要额外配置审计日志 |
| 灰度发布 | 修改 Git 中的灰度比例配置,自动同步 | 手动调整 Service / VirtualService,易出错 |
声明式模型将运维从“消防员”转变为“架构师”。在灰度批次发布场景中,你只需在 Git 中调整 replicas 或 weight 字段,Reconciliation 循环会自动、可预测地将集群推向新的期望状态,并在每次循环中留下可追溯的运维清单记录。