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 的硬性扣除部分)
详细计算步骤:
- 起点: 获取
Node Capacity(例如:CPU 8 核,内存 32 Gi)。 - 扣除系统预留: 减去
--system-reserved配置值(例如:CPU 500m,内存 1Gi)。 - 扣除 kubelet 预留: 减去
--kube-reserved配置值(例如:CPU 200m,内存 512Mi)。 - 扣除驱逐阈值硬边界: 减去
--eviction-hard中定义的值(例如:memory.available<500Mi)。 - 结果: 得到
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 的完整计算流程,以及驱逐阈值在其中的位置。
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)都必须在这个天花板之下进行优化。