2. 节点资源管理:Node资源模型、可分配资源计算、资源预留策略

在Kubernetes集群中,每个Node都是一个资源池。调度器在将Pod绑定到节点时,必须确保节点有足够的资源满足Pod的请求。然而,节点上的资源并非全部可供Pod使用——操作系统、kubelet、容器运行时以及系统守护进程都会消耗一部分资源。理解Node的资源模型、掌握可分配资源的计算方法,并合理配置资源预留策略,是保障集群稳定性和调度准确性的基础。

2.1 Node资源模型:Capacity、Allocatable与Requests/Limits

Kubernetes对节点资源的描述分为三个层次:Node Capacity(节点容量)、Node Allocatable(节点可分配资源)和Pod Requests/Limits(Pod请求/限制)。三者之间的关系决定了Pod能否被调度到节点上。

资源层次 定义 数据来源 用途
Node Capacity 节点硬件报告的总资源量(CPU核数、内存大小、磁盘容量等) 操作系统 / 云厂商API 节点规格标识,调度器不直接使用
Node Allocatable 节点上可供Kubernetes Pod使用的资源量 Capacity - 系统预留 - kubelet预留 - eviction阈值 调度器判断Pod能否调度到该节点的依据
Pod Requests Pod声明的最小资源保证量 Pod Spec中 containers[].resources.requests 调度时比较 Allocatable 与所有Pod Requests之和
Pod Limits Pod允许使用的资源上限 Pod Spec中 containers[].resources.limits 运行时cgroup限制,不影响调度决策
关键原则:调度器只检查 Node Allocatable 与所有已调度Pod的 Requests 之和。即使Pod设置了很高的Limits,只要Requests较低,调度器仍可能将多个Pod堆叠到同一节点,导致资源争抢。

2.2 可分配资源计算:从Capacity到Allocatable的减法

节点可分配资源的计算公式如下:

Allocatable = Capacity - Reserved - EvictionThreshold

其中:
Reserved = SystemReserved + KubeletReserved

各组成部分的含义与配置方式:

  • SystemReserved:为操作系统守护进程(sshd、systemd、内核等)预留的资源。通过kubelet参数 --system-reserved 配置,例如 --system-reserved=cpu=500m,memory=1Gi。
  • KubeletReserved:为kubelet、容器运行时(containerd/docker)、CNI插件等Kubernetes系统组件预留的资源。通过 --kubelet-reserved 配置。
  • EvictionThreshold:节点压力驱逐的硬阈值或软阈值。当节点剩余资源低于此阈值时,kubelet开始驱逐Pod。常见配置如 --eviction-hard=memory.available<100Mi。
生产建议:在节点总内存小于8GB时,建议将SystemReserved + KubeletReserved的总和控制在20%~25%;内存大于32GB的节点,预留比例可降至10%~15%。CPU预留通常不超过节点总核数的10%。

以下SVG图展示了从Node Capacity到Allocatable的完整计算链路:

节点可分配资源计算链路 Node Capacity (硬件报告总量:CPU / Memory / Ephemeral Storage) - SystemReserved OS守护进程 KubeletReserved kubelet / 容器运行时 - EvictionThreshold 硬/软驱逐阈值 = Node Allocatable

2.3 资源预留策略:三种模式与配置实践

Kubernetes支持三种资源预留模式,分别对应不同的运维场景:

预留模式 配置参数 适用场景 注意事项
静态预留 --system-reserved
--kubelet-reserved
节点规格固定、负载模式稳定的生产集群 预留值需根据节点实际监控数据调整,过大浪费资源,过小导致系统不稳定
动态预留(QoS预留) --reserved-cpus 对CPU延迟敏感的实时工作负载(如电信、金融交易) 将特定物理CPU核心专用于系统进程,避免Pod争用;需配合CPU Manager Policy
驱逐阈值预留 --eviction-hard
--eviction-soft
所有集群,作为资源耗尽时的最后防线 硬驱逐立即杀死Pod,软驱逐配合eviction-soft-grace-period提供缓冲时间
常见陷阱:如果同时设置了 --system-reserved 和 --kubelet-reserved,但忘记设置 --eviction-hard,当节点内存实际使用接近Capacity时,kubelet可能不会及时驱逐Pod,导致系统OOM。建议始终配置至少一个硬驱逐阈值。

2.4 验证可分配资源:kubectl describe node

通过以下命令可以查看节点的实际可分配资源:

kubectl describe node <node-name>

# 输出片段示例:
Capacity:
  cpu:                8
  memory:             32948212Ki
  ephemeral-storage:  102350Mi
Allocatable:
  cpu:                7500m
  memory:             30848212Ki
  ephemeral-storage:  98235123Ki

对比Capacity与Allocatable的差值,即可反推出当前节点的资源预留总量。如果发现Allocatable过低(例如CPU预留超过20%),应检查kubelet启动参数中的预留配置是否合理。

2.5 资源预留策略的典型配置模板

以下是一个适用于通用生产环境的kubelet预留配置示例(kubelet配置文件方式):

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
  memory.available: "300Mi"
  nodefs.available: "10%"
kubeletReserved:
  cpu: "200m"
  memory: "512Mi"
systemReserved:
  cpu: "500m"
  memory: "1Gi"
evictionPressureTransitionPeriod: 5m
调优建议:对于内存密集型节点(如运行Java应用的节点),建议将 evictionHard.memory.available 设置为节点总内存的5%~10%;对于CPU密集型节点,systemReserved.cpu 可适当降低至300m。每季度根据节点监控指标(如Node Exporter数据)重新校准预留值。

以下SVG图展示了不同预留策略在节点资源分配中的占比关系:

资源预留策略占比示意(以32GB内存节点为例) 无预留策略 Allocatable ≈ 32GB (系统与Pod争抢资源) 风险:系统OOM、kubelet不稳定 合理预留 Allocatable ≈ 27GB 预留 ≈ 5GB 稳定:系统与Pod资源隔离 过度预留 Allocatable ≈ 20GB 预留 ≈ 12GB 浪费:大量资源无法被Pod使用

2.6 实战检查清单

在配置节点资源预留时,建议按以下步骤逐一验证:

  1. 确认节点Capacity:通过 kubectl describe node 或节点监控面板获取硬件规格。
  2. 计算合理预留值:根据节点用途(通用计算/内存密集/CPU密集)确定SystemReserved和KubeletReserved。
  3. 配置驱逐阈值:至少设置 memory.available 和 nodefs.available 的硬驱逐。
  4. 验证Allocatable:部署测试Pod,确认调度器正确使用Allocatable而非Capacity。
  5. 持续监控:使用Prometheus + Grafana监控节点实际资源使用率,每季度调整预留参数。
核心结论:节点资源管理的本质是“为系统预留足够的安全垫,同时最大化Pod可用资源”。合理的预留策略能让集群在负载波动时保持稳定,避免因资源争抢导致的Pod驱逐或节点故障。下一节将深入Pod资源QoS模型,探讨如何通过Pod级别的资源限制进一步优化调度行为。