4. 节点资源模型:Allocatable、Reserved、Capacity 的关系

在 Kubernetes 集群中,一个节点的物理资源(CPU、内存、磁盘、PID 等)并非全部可供 Pod 使用。操作系统内核、系统守护进程(sshd、systemd、kubelet 等)以及 Kubernetes 组件(kubelet、容器运行时)都需要占用一部分资源。为了准确描述“节点到底有多少资源可以分配给 Pod”,K8s 定义了三个核心概念:节点容量(Capacity)、资源预留(Reserved) 和 节点可分配资源(Allocatable)。

理解这三者的关系,是进行调度器参数调优和节点资源分配均衡的基础。错误的预留配置会导致节点资源利用率低下或 Pod 调度失败。

4.1 核心概念定义

概念 英文 定义 来源
节点容量 Capacity 节点上硬件资源的总量,例如 4 核 CPU、16 GB 内存。这是节点资源的上限。 kubelet 自动检测(如 /proc/cpuinfo、/proc/meminfo)
资源预留 Reserved 为系统守护进程和 Kubernetes 组件预留的资源,Pod 不可使用。包括 --system-reserved 和 --kube-reserved。 kubelet 启动参数配置
节点可分配资源 Allocatable 节点上真正可以分配给 Pod 使用的资源量。调度器基于此值判断 Pod 是否能调度到该节点。 Capacity - Reserved - (Hard Eviction Threshold)
关键公式:
Allocatable = Capacity - Reserved - HardEvictionThreshold
其中 Reserved = system-reserved + kube-reserved。硬驱逐阈值(Hard Eviction Threshold)通常为内存和磁盘预留一小部分空间,防止节点资源耗尽时无法驱逐 Pod。

4.2 三层资源模型关系图

下图展示了从物理硬件到 Pod 可用资源的完整链路。调度器只关心最内层的 Allocatable 区域。

节点资源模型:Capacity、Reserved、Allocatable 关系 节点容量(Capacity) 资源预留(Reserved) system-reserved sshd, systemd, 内核, 日志 kube-reserved kubelet, 容器运行时, cAdvisor 节点可分配资源(Allocatable) Pod 可用资源 Pod A Pod B Pod C 空闲 硬驱逐阈值(Hard Eviction Threshold) 减去 减去 调度器只检查 Allocatable,不关心 Capacity 和 Reserved 的具体值

4.3 预留配置参数详解

kubelet 通过以下启动参数控制资源预留。这些参数通常在节点初始化时配置,或在 kubelet 配置文件中设置。

参数 作用域 示例值 说明
--system-reserved 操作系统守护进程 cpu=500m,memory=1Gi 为 sshd、systemd、内核、日志等预留
--kube-reserved Kubernetes 组件 cpu=200m,memory=512Mi 为 kubelet、容器运行时、cAdvisor 预留
--eviction-hard 硬驱逐阈值 memory.available<100Mi 当节点内存低于此值时,kubelet 开始驱逐 Pod
--eviction-soft 软驱逐阈值 memory.available<200Mi 配合 eviction-soft-grace-period 使用,给予 Pod 优雅退出时间
常见误区:
  • 预留过多:导致 Allocatable 过小,Pod 调度受限,节点资源利用率低。
  • 预留过少:系统组件资源不足,导致节点不稳定,kubelet 被 OOM Kill。
  • 忽略硬驱逐阈值:Allocatable 计算时默认会减去硬驱逐阈值,如果手动配置不当,可能导致节点内存耗尽时无法触发驱逐。

4.4 调度器如何感知 Allocatable

调度器通过 Node 对象的 Status 字段 获取节点的 Allocatable 信息。当调度器为 Pod 选择节点时,会执行以下检查:

  1. 获取节点 Allocatable:从 node.Status.Allocatable 读取 CPU、内存等资源量。
  2. 计算已分配资源:统计该节点上所有已调度 Pod 的 requests 总和。
  3. 判断剩余资源:如果 Allocatable - 已分配资源 >= Pod 的 requests,则节点满足调度条件。

以下是一个 Node 对象的 Allocatable 示例(通过 kubectl describe node 查看):

Capacity:
  cpu:                4
  memory:             16384688Ki
  ephemeral-storage:  102350Mi
Allocatable:
  cpu:                3
  memory:             15284688Ki
  ephemeral-storage:  98230Mi

在这个例子中,系统预留了 1 个 CPU 和约 1 GB 内存(Capacity - Allocatable)。调度器只会看到 Allocatable.cpu = 3,因此最多只能调度 requests 总和不超过 3 个 CPU 的 Pod。

4.5 预留配置最佳实践

节点类型 推荐预留比例(CPU) 推荐预留比例(内存) 说明
小型节点(<= 4 核) 10% - 15% 10% - 15% 系统组件占比相对较大,预留比例应偏高
中型节点(8 - 16 核) 6% - 10% 5% - 10% 平衡资源利用率与系统稳定性
大型节点(32 核以上) 3% - 6% 3% - 5% 系统组件开销相对较小,预留比例可降低
调优建议:
  • 使用 kubectl describe node 定期检查 Allocatable 与 Capacity 的差值,确认预留是否合理。
  • 对于内存密集型工作负载,适当提高 --eviction-hard 阈值(如 memory.available<200Mi),避免 OOM 时无响应。
  • 在集群初始化阶段,通过 kubelet-config.yaml 统一管理预留参数,避免节点间配置不一致。

4.6 小结