4. 资源状态(ResourceStatus):Pod Phase、Container State、Node Condition 等状态机设计

在 Kubernetes 资源模型中,状态(Status)是控制面与数据面之间同步的核心契约。Pod、Container、Node 三大资源各自拥有独立但相互关联的状态机,这些状态机驱动着调度、生命周期管理、故障恢复等关键控制逻辑。本章深入剖析这三类状态机的设计原理、转换规则及其在 CRI 集成中的实现映射。

4.1 Pod Phase:高层级生命周期状态机

Pod Phase 是 Pod 对象最宏观的状态,由 kubelet 基于 Pod 内所有容器的状态综合计算得出。它定义了 Pod 从创建到终止的五个阶段:

Phase 含义 典型触发条件
Pending Pod 已被 API Server 接受,但尚未完成调度或镜像拉取 调度器未绑定节点;镜像拉取中;Init 容器未完成
Running Pod 已绑定到节点,至少一个容器处于 Running 或 Waiting 状态 所有 Init 容器成功退出;主容器启动成功
Succeeded Pod 内所有容器均已正常退出(退出码 0) Job/CronJob 容器执行完毕;RestartPolicy 为 Never/OnFailure
Failed Pod 内至少一个容器以非零退出码终止 容器崩溃;健康检查失败且达到重启上限
Unknown kubelet 无法与 API Server 通信,状态丢失 节点网络分区;kubelet 进程异常退出
设计要点:Pod Phase 并非严格的状态机——它允许从 Running 直接跳转到 Failed,无需经过中间状态。这种设计简化了控制面逻辑,但要求下层容器状态机提供更精细的转换约束。

4.2 Container State:细粒度运行时状态机

Container State 是 CRI 接口直接暴露的运行时状态,由容器运行时(如 containerd、CRI-O)维护。Kubernetes 将其抽象为三种主要状态:Waiting、Running、Terminated。每个状态附带一个原因(Reason)和消息(Message),用于调试和告警。

状态转换规则:
  • Waiting → Running:镜像拉取完成,容器启动成功。
  • Running → Terminated:容器进程退出(正常或异常)。
  • Waiting → Terminated:镜像拉取失败或容器创建失败(如 OOM、配置错误)。
  • Terminated → Waiting:仅当 RestartPolicy 允许重启时发生,kubelet 重新创建容器。

以下 SVG 展示了 Container State 的完整状态机,包含 CRI 事件驱动的转换路径:

容器状态机与 CRI 事件驱动转换 容器状态机与 CRI 事件驱动转换 Waiting 镜像拉取 / 创建中 Running 进程运行中 Terminated 进程已退出 ContainerCreated ContainerExited ContainerCreateFailed / ImagePullFailed RestartPolicy 触发重建 CRI 事件 → Kubernetes 状态映射 • ContainerCreated → 状态变为 Running,Reason: "" • ContainerExited (exit=0) → 状态变为 Terminated,Reason: "Completed" • ContainerExited (exit≠0) → 状态变为 Terminated,Reason: "Error" • ImagePullFailed → 状态变为 Waiting,Reason: "ImagePullBackOff"

4.3 Node Condition:节点级状态聚合

Node Condition 是 kubelet 对节点整体健康度的评估结果,通过一组布尔型条件(Condition)表达。每个 Condition 包含 Type、Status(True/False/Unknown)、LastHeartbeatTime、LastTransitionTime、Reason 和 Message 字段。

Condition Type True 含义 False 含义 检测机制
Ready 节点健康,可调度 Pod 节点不健康,Pod 被驱逐 kubelet 定期上报心跳;NodeLifecycleController 检查
DiskPressure 磁盘空间不足 磁盘空间充足 kubelet 监控 /var/lib/kubelet 和 /var/log
MemoryPressure 节点内存紧张 内存正常 kubelet 基于 cgroup memory.usage_in_bytes 判断
PIDPressure PID 资源耗尽 PID 充足 kubelet 监控 /proc/sys/kernel/pid_max
NetworkUnavailable 网络插件未就绪 网络正常 kubelet 检查 CNI 插件状态
关键约束:Node Condition 的转换由 kubelet 的 nodeStatusUpdateFrequency(默认 10s)控制。当 kubelet 停止上报心跳时,NodeLifecycleController 会在 node-monitor-grace-period(默认 40s)后将 Ready 条件置为 Unknown,并在 pod-eviction-timeout(默认 5m)后驱逐 Pod。

4.4 状态机之间的联动关系

Pod Phase、Container State、Node Condition 并非孤立存在,它们通过 kubelet 的状态聚合逻辑形成层级依赖:

  • Container State → Pod Phase:kubelet 遍历 Pod 内所有容器状态,按优先级计算 Phase。例如,只要有一个容器处于 Running,Pod Phase 即为 Running;所有容器 Terminated 且退出码为 0 时,Phase 为 Succeeded。
  • Node Condition → Pod Phase:当 Node Condition.Ready == False 或 Unknown 时,kubelet 将 Pod 的 Ready 条件置为 False,但 Pod Phase 本身不受直接影响——Pod 仍可处于 Running 状态,只是无法对外提供服务。
  • CRI 事件 → 状态更新:容器运行时通过 CRI 的 ContainerStatus 和 PodSandboxStatus 接口返回状态,kubelet 将其转换为 Kubernetes 内部状态对象,再写入 etcd。

以下 SVG 展示了三层状态机的联动架构:

Pod / Container / Node 状态机联动架构 Pod / Container / Node 状态机联动架构 Node Condition Ready / DiskPressure / MemoryPressure Pod Phase Pending / Running / Succeeded / Failed Container A Waiting/Running/Terminated Container B Waiting/Running/Terminated Container C Waiting/Running/Terminated 影响 Pod Ready 条件 聚合计算 聚合计算 聚合计算 kubelet 每 10s 执行一次状态聚合:收集所有 Container State → 计算 Pod Phase → 结合 Node Condition 更新 Pod Ready 条件

4.5 CRI 集成中的状态同步关键点

在 CRI 集成场景下,状态机的正确性依赖于以下三个关键机制:

  1. 状态缓存与去重:kubelet 维护一个 PodStatusCache,避免每次 SyncPod 都调用 CRI 接口。缓存过期时间由 --node-status-update-frequency 控制。
  2. 状态转换的幂等性:CRI 的 ContainerStatus 返回的是运行时快照,kubelet 需要将其与本地缓存对比,只将状态变化写入 etcd,减少 API Server 压力。
  3. 异常状态的处理策略:当 CRI 返回 ContainerState_UNKNOWN 时,kubelet 会保留上次已知状态,并触发重试。连续失败超过 --runtime-request-timeout(默认 2m)后,kubelet 将容器状态置为 Terminated,Reason 为 "Unknown"。
生产环境建议:
  • 监控 kubelet_pod_status_phase{phase="Unknown"} 指标,及时发现状态同步异常。
  • 设置 --node-status-update-frequency=5s 缩短状态延迟,但需评估 etcd 写入压力。
  • 在容器运行时侧实现 ContainerStatus 的快速响应(< 100ms),避免 kubelet 超时导致状态抖动。