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 事件驱动的转换路径:
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 展示了三层状态机的联动架构:
4.5 CRI 集成中的状态同步关键点
在 CRI 集成场景下,状态机的正确性依赖于以下三个关键机制:
- 状态缓存与去重:kubelet 维护一个
PodStatusCache,避免每次SyncPod都调用 CRI 接口。缓存过期时间由--node-status-update-frequency控制。 - 状态转换的幂等性:CRI 的
ContainerStatus返回的是运行时快照,kubelet 需要将其与本地缓存对比,只将状态变化写入 etcd,减少 API Server 压力。 - 异常状态的处理策略:当 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 超时导致状态抖动。