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