4. 节点资源拓扑:Node Allocatable、Capacity、Reserved、Eviction Thresholds 的计算模型

在 Kubernetes 集群中,一个节点的资源并非全部可供 Pod 使用。操作系统、kubelet 以及系统守护进程(如 sshd、systemd)需要预留一部分资源来保证节点自身的稳定运行。理解 Node Allocatable、Capacity、Reserved 和 Eviction Thresholds 之间的计算关系,是进行资源碎片治理和准入控制策略设计的基础。

4.1 核心概念定义

下表清晰定义了节点资源拓扑中的四个关键概念,它们共同构成了节点资源的完整视图。

概念 英文名称 定义与来源 对 Pod 的影响
节点容量 Node Capacity 节点硬件报告的总资源量(CPU、内存、磁盘等)。由 kubelet 从操作系统读取。 所有资源计算的起点,Pod 无法使用超过此值的资源。
系统预留 System Reserved 为操作系统守护进程(如 systemd、sshd、内核)预留的资源。通过 kubelet 参数 --system-reserved 配置。 从 Capacity 中扣除,Pod 不可见。
kubelet 预留 Kubelet Reserved 为 kubelet 自身及容器运行时(如 containerd)预留的资源。通过 --kube-reserved 配置。 从 Capacity 中扣除,Pod 不可见。
节点可分配 Node Allocatable 经过预留后,真正可供集群中 Pod 调度和使用的资源总量。 调度器(Scheduler)和 kubelet 以此值为上限进行 Pod 准入。
驱逐阈值 Eviction Thresholds kubelet 主动驱逐 Pod 的触发线。当节点实际使用量低于 Allocatable 的某个百分比或值时触发。 定义了节点资源使用的“硬边界”,防止节点资源耗尽。
关键认知: 许多资源碎片问题源于对 Allocatable 的误解。Pod 的 requests 和 limits 是在 Allocatable 的范围内进行竞争,而非 Capacity。预留设置不当会直接导致节点有效资源减少,加剧碎片化。

4.2 计算模型与公式

节点资源拓扑的计算遵循一个严格的减法模型。理解这个模型是配置节点预留和驱逐策略的前提。

核心计算公式:

Node Allocatable = Node Capacity - System Reserved - Kubelet Reserved - (Eviction Thresholds 的硬性扣除部分)

详细计算步骤:

  1. 起点: 获取 Node Capacity(例如:CPU 8 核,内存 32 Gi)。
  2. 扣除系统预留: 减去 --system-reserved 配置值(例如:CPU 500m,内存 1Gi)。
  3. 扣除 kubelet 预留: 减去 --kube-reserved 配置值(例如:CPU 200m,内存 512Mi)。
  4. 扣除驱逐阈值硬边界: 减去 --eviction-hard 中定义的值(例如:memory.available<500Mi)。
  5. 结果: 得到 Node Allocatable,该值会作为 status.allocatable 字段上报给 API Server。
实践注意: 如果未显式配置 --system-reserved 和 --kube-reserved,kubelet 会使用默认值(通常为 0 或基于机器规格的自动计算值)。在生产环境中,必须显式配置这些值,否则节点稳定性无法保证。

4.3 驱逐阈值(Eviction Thresholds)的角色

驱逐阈值是节点资源拓扑中的“安全阀”。它定义了 kubelet 在资源紧张时开始驱逐 Pod 的触发条件。驱逐阈值分为 硬驱逐(Hard Eviction) 和 软驱逐(Soft Eviction)。

类型 触发条件 行为 对 Allocatable 的影响
硬驱逐 立即触发,无宽限期。 kubelet 立即终止 Pod。 硬驱逐阈值中的值部分(如 memory.available<500Mi)会从 Capacity 中扣除,减少 Allocatable。
软驱逐 触发后,等待 eviction-soft-grace-period 指定的宽限期。 宽限期后仍未恢复,则驱逐 Pod。 软驱逐阈值通常不直接减少 Allocatable,但会影响调度决策(通过节点条件)。

4.4 资源拓扑计算模型 SVG 图

下图直观展示了从 Node Capacity 到 Node Allocatable 的完整计算流程,以及驱逐阈值在其中的位置。

节点资源拓扑计算模型 Node Capacity 硬件报告的总资源(CPU / 内存) - System Reserved 操作系统守护进程预留(--system-reserved) - Kubelet Reserved kubelet 与容器运行时预留(--kube-reserved) - Eviction Thresholds (Hard) 硬驱逐阈值值(如 memory.available < 500Mi) Node Allocatable Pod 可调度与使用的资源上限 计算模型说明 Allocatable = Capacity - System Reserved - Kubelet Reserved - Eviction Hard Thresholds

4.5 实践中的配置示例

以下是一个典型的 kubelet 配置片段,展示了如何通过命令行参数或配置文件来定义这些预留值。

# kubelet 命令行参数示例
--system-reserved=cpu=500m,memory=1Gi,ephemeral-storage=10Gi
--kube-reserved=cpu=200m,memory=512Mi,ephemeral-storage=5Gi
--eviction-hard=memory.available<500Mi,nodefs.available<10%
--eviction-soft=memory.available<1Gi
--eviction-soft-grace-period=memory.available=1m30s
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi
配置要点:
  • 预留值总和: 建议 System Reserved + Kubelet Reserved 的总和不超过节点总资源的 20%,否则会导致严重的资源浪费。
  • 驱逐阈值与 Allocatable: 硬驱逐阈值中的值(如 memory.available<500Mi)会直接减少 Allocatable。这意味着节点会保留 500Mi 内存作为“安全缓冲区”,Pod 无法使用。
  • 碎片治理关联: 如果预留值设置过大,Allocatable 会显著小于 Capacity,导致节点看起来“资源不足”,加剧碎片化。反之,预留过小则节点稳定性差。

4.6 资源拓扑与准入控制的关系

在准入控制阶段(如使用 NodeResourcesFit 插件),调度器会检查 Pod 的 requests 是否小于等于节点的 Allocatable。如果节点上已分配的资源(Allocated)加上新 Pod 的请求超过了 Allocatable,则 Pod 无法调度到该节点。

关键公式:

调度准入条件:Pod.Requests + Node.Allocated <= Node.Allocatable

因此,Allocatable 是资源碎片治理的“天花板”。任何碎片治理策略(如资源画像、动态调整 requests)都必须在这个天花板之下进行优化。