3. 声明式配置与期望状态:K8s 声明式 API 原理、期望状态 vs 实际状态、控制器循环
在 Kubernetes 发布流水线中,声明式配置是自动化运维的基石。与传统的“命令式”操作不同,声明式模型要求用户只描述“系统最终应该是什么样子”,而将“如何达到这个状态”的复杂逻辑交给平台自身完成。本章将深入剖析 K8s 声明式 API 的核心原理、期望状态与实际状态的差异,以及控制器循环的工作机制。
3.1 声明式 API 原理
Kubernetes 的 API 设计遵循声明式范式。用户通过 YAML 或 JSON 文件定义资源的期望状态(Desired State),并将其提交到 API Server。系统内部通过一系列控制器持续协调,确保集群的实际状态与期望状态保持一致。
核心特征: 用户只关心“做什么”(What),不关心“怎么做”(How)。系统自动处理差异检测与修复。
3.1.1 声明式 vs 命令式
| 维度 | 声明式(Declarative) | 命令式(Imperative) |
|---|---|---|
| 操作方式 | 提交最终状态文件(YAML) | 执行具体指令(kubectl run/scale) |
| 幂等性 | 天然幂等,重复执行结果一致 | 非幂等,需人工跟踪状态 |
| 漂移检测 | 自动对比期望与实际,持续修复 | 无自动检测,依赖人工审计 |
| 回滚能力 | 通过版本化配置快速恢复 | 需手动逆向操作,易出错 |
| 适用场景 | CI/CD 流水线、生产环境 | 临时调试、快速验证 |
3.1.2 声明式 API 的工作流程
- 用户定义期望状态:编写 Deployment、Service 等资源的 YAML 清单。
- 提交到 API Server:通过
kubectl apply或 GitOps 工具推送。 - 存储到 etcd:API Server 将期望状态持久化到 etcd 集群。
- 控制器检测差异:对应的控制器(如 Deployment Controller)通过 List-Watch 机制获取期望状态。
- 执行协调循环:控制器对比实际状态,执行创建、更新或删除操作。
- 反馈状态:控制器将实际状态写回资源对象的
status字段。
最佳实践: 在 CI/CD 流水线中,始终使用
kubectl apply 而非 kubectl create 或 kubectl replace,以利用声明式配置的自动合并与漂移修复能力。
3.2 期望状态 vs 实际状态
Kubernetes 资源对象通过两个核心字段来管理状态:
spec(期望状态):用户定义的理想配置,由 API Server 持久化存储。status(实际状态):由控制器实时更新的当前集群状态。
两者之间的差距驱动着控制器的协调动作。以下是一个 Deployment 的典型状态对比:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
---
status:
availableReplicas: 2 # 实际可用 Pod 数
readyReplicas: 2 # 就绪 Pod 数
replicas: 3 # 当前总 Pod 数
updatedReplicas: 1 # 已更新到新版本的 Pod 数
conditions:
- type: Available
status: "False"
reason: MinimumReplicasUnavailable
message: "Deployment does not have minimum availability."
注意: 当
status 与 spec 不一致时,控制器会立即启动修复。例如上例中 availableReplicas: 2 小于 spec.replicas: 3,控制器会尝试创建或恢复 Pod。
3.3 控制器循环(Reconciliation Loop)
控制器循环是 Kubernetes 实现声明式自愈的核心机制。每个控制器(如 Deployment Controller、ReplicaSet Controller)都运行着一个无限循环,持续执行以下步骤:
- Watch:监听 API Server 上资源对象的变化事件(Add/Update/Delete)。
- Read:读取当前资源的
spec(期望状态)和status(实际状态)。 - Diff:对比期望状态与实际状态,计算差异列表。
- Act:执行必要的操作(创建 Pod、更新 Service、删除旧资源等)。
- Update Status:将协调后的实际状态写回
status字段。 - Re-queue:将资源重新加入工作队列,等待下一次循环。
关键特性: 控制器循环是事件驱动 + 定时同步的混合模型。除了响应事件,控制器还会定期(默认 10 小时)重新同步所有资源,确保即使事件丢失也能最终一致。
3.3.1 控制器循环流程图
3.4 配置漂移与控制器修复
配置漂移是指集群的实际状态因外部因素(如手动修改、节点故障、资源抢占)偏离了期望状态。控制器循环通过持续对比自动检测并修复漂移。
3.4.1 常见漂移场景
| 漂移类型 | 触发原因 | 控制器修复行为 |
|---|---|---|
| Pod 数量漂移 | 手动删除 Pod、节点资源不足导致驱逐 | ReplicaSet 控制器重新创建 Pod |
| 镜像版本漂移 | 手动修改 Pod 镜像标签 | Deployment 控制器回滚到 spec 定义的版本 |
| 配置漂移 | 手动修改 ConfigMap 或 Secret | Pod 需重建才能生效(需手动触发滚动更新) |
| 网络策略漂移 | 手动修改 NetworkPolicy 规则 | NetworkPolicy 控制器立即同步规则 |
流水线建议: 在 CI/CD 流水线中,每次部署后应执行
kubectl diff 或使用 kubectl apply --server-side 强制同步期望状态,避免手动操作导致的漂移累积。
3.5 声明式配置在流水线中的价值
在 K8s 发布流水线中,声明式配置提供了以下关键能力:
- 版本化配置:所有 YAML 文件存储在 Git 仓库中,支持审计、回滚和协作。
- 自动漂移修复:控制器持续运行,确保集群始终与 Git 中的期望状态一致。
- 幂等部署:重复执行
kubectl apply不会产生副作用,适合自动化流水线。 - 渐进式交付:结合 Deployment 的滚动更新策略,实现零停机发布。
核心结论: 声明式配置 + 控制器循环 = K8s 自愈能力的基石。在流水线中,我们只需维护 Git 仓库中的期望状态,K8s 会自动处理所有差异修复与状态收敛。
3.6 本章小结
- K8s 声明式 API 要求用户只定义期望状态,系统自动协调实际状态。
- 期望状态存储在
spec字段,实际状态由控制器更新到status字段。 - 控制器循环通过 Watch → Read → Diff → Act → Update Status → Re-queue 的闭环实现持续协调。
- 配置漂移是常态,控制器循环是自动修复的核心保障。
- 在 CI/CD 流水线中,声明式配置提供了版本化、幂等性和自愈能力,是自动化发布的基础。