Kubernetes 节点资源预留

FreeGuideOnline 最新 2026-07-13

Kubernetes 节点资源预留完全指南

为什么需要节点资源预留

Kubernetes 节点上除了运行业务 Pod,还运行着众多系统守护进程(如 sshdsystemd-journald)以及 Kubernetes 自身的组件(如 kubeletcontainer runtime)。如果不做任何限制,当业务 Pod 申请过多资源时,这些关键进程可能因资源不足而频繁中断,导致节点进入 Not Ready 状态,甚至整台机器失去响应。

节点资源预留的本质是 从节点总容量中划出一部分固定的资源(CPU、内存、存储)给系统和 Kubernetes 组件专用,Pod 最多只能使用剩余的资源。这能有效避免调度器无节制地将 Pod 调度到节点上,从而保护节点稳定性。

节点总资源模型

在配置预留前,先理解节点上不同资源的划分层次:

  • Node Capacity:节点的物理/虚拟总核数和总内存,由 kubectl describe node 中的 Capacity 字段展示。
  • Node Allocatable:节点上真正可供 Pod 使用的资源总量,即 Allocatable 字段。
  • 预留资源:Capacity - Allocatable 的差值,由以下三部分组成:
    • System Reserved:操作系统级别的守护进程保留资源。
    • Kube Reserved:Kubernetes 系统组件(kubeletcontainer runtime、kube-proxy 等)保留资源。
    • Eviction Thresholds:kubelet 用于触发 Pod 驱逐的内存阈值。

三者关系如下:

Allocatable = Node Capacity - System Reserved - Kube Reserved - Eviction Threshold

只有当 Pod 的 requests 总和 ≤ Node Allocatable,调度器才会把新的 Pod 分配到该节点。

配置资源预留(kubelet 参数指南)

资源预留通过 kubelet 启动参数配置,最终写入 /var/lib/kubelet/config.yaml 或启动命令行。常用参数有:

--system-reserved

为操作系统级守护进程保留资源,如 systemdjournaldcontainerd(如果不属于 Kubernetes 组件)等,格式为 resource=value 的逗号分隔值,例如:

--system-reserved=cpu=500m,memory=1Gi,ephemeral-storage=1Gi

注意ephemeral-storage 是临时存储,自 1.18 版本开始稳定支持。如果不想预留存储,可省略。

--kube-reserved

为 Kubernetes 相关组件保留资源,包括 kubeletcontainer runtime(如 containerd)、CNI 插件、kube-proxy 等,例如:

--kube-reserved=cpu=1000m,memory=2Gi,ephemeral-storage=2Gi

--eviction-hard

定义内存和磁盘的硬驱逐阈值,当可用资源低于该值时,kubelet 会立即驱逐 Pod。典型配置:

--eviction-hard=memory.available<1Gi,nodefs.available<10%,imagefs.available<15%

这里 memory.available 的计算公式为:

memory.available = Node Capacity.memory - system-reserved.memory - kube-reserved.memory - Sum(Pod内存usage)

也就是说,eviction threshold 取值是从 Allocatable 中再切掉一部分内存,形成一个“安全缓冲”。如果把 --eviction-hard 中的内存阈值算作预留的一部分,那么 Allocatable 会进一步缩小。

实战示例:配置一台 8C 16G 节点的预留

假设节点物理资源为 8 核 CPU、16 GiB 内存,我们希望预留合理的值,同时留给 Pod 尽可能多的资源。

1. 确定各组件资源消耗

通过监控工具(如 topsystemd-cgtop)或压力测试估算:

  • 操作系统守护进程大约需要 200m CPU、0.5 GiB 内存。
  • Kube 组件(kubelet 150m、containerd 300m、kube-proxy 100m + 网络插件)合计约 600m CPU、1 GiB 内存。
  • 为安全考虑,再额外预留一个内存驱逐阈值 1 GiB。

2. 创建 kubelet 配置文件

编辑 /var/lib/kubelet/config.yaml(若使用 kubeadm 安装,通常文件已存在,直接修改即可):

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
enforceNodeAllocatable:
- pods
systemReserved:
  cpu: "200m"
  memory: "512Mi"
kubeReserved:
  cpu: "600m"
  memory: "1Gi"
evictionHard:
  memory.available: "1Gi"
  nodefs.available: "10%"
  imagefs.available: "15%"

如果使用命令行参数,则传递:

--system-reserved=cpu=200m,memory=512Mi
--kube-reserved=cpu=600m,memory=1Gi
--eviction-hard=memory.available<1Gi,nodefs.available<10%,imagefs.available<15%

3. 重启 kubelet

systemctl restart kubelet
systemctl status kubelet

4. 验证 Allocatable 值

kubectl describe node <node-name> | grep -A 5 Allocatable

预期输出类似:

Allocatable:
  cpu:                7200m      # 8000 - 200 - 600
  memory:             14008384Ki # 16Gi - 512Mi - 1Gi - 1Gi(eviction) ≈ 13.5 GiB

此时 Pod 的总 requests 不能超过 7.2 核和约 13.5 GiB 内存,确保了系统和 Kubernetes 组件拥有充足的资源。

最佳实践与注意事项

  • 从实际出发,逐步调优:初始预留值可参考社区推荐(如 GKE 默认值为 CPU 60m + 额外每核 1.4m,内存 2.15 GiB + 额外每 GiB 5 Mi),但最好根据自身集群的监控数据调整。
  • 不要过度预留:过度预留会浪费节点资源,增加成本。尽量通过长期观察 node_memory_MemAvailable_bytesnode_cpu_seconds_total 等指标确定合理值。
  • 临时存储预留:如果节点上日志、容器层等消耗大量磁盘,务必配置 ephemeral-storage 的预留和驱逐阈值,否则磁盘写满会导致整个节点不可用。
  • 使用 --reserved-cpus 实现 CPU 独占:在需要极致性能的场景,可以通过 --reserved-cpus 指定预留的 CPU 核号(需搭配 CPU Manager 的 static 策略),将这些核完全从调度池中移除,系统进程和 Kubernetes 组件将运行在这些特定核上。
  • 版本差异:确保 kubelet 版本 ≥ 1.18(ephemeral-storage 支持更完善),且驱逐阈值的计算在 v1.22+ 略有变化,注意查阅对应版本文档。
  • 验证节点状态:配置完成后,检查 kubelet 日志 journalctl -u kubelet -f,确保没有因预留配置错误导致启动失败。

常见问题排查

节点 Allocatable 没有变化?

  • 确认 kubelet 是否正确重启,检查配置文件路径是否正确。
  • 如果使用 kubeadm 部署,修改 /var/lib/kubelet/config.yaml 后需执行 systemctl restart kubelet;某些版本可能还需更新 /etc/default/kubelet 中的参数引用。

Pod 因资源预留被驱逐,如何查看驱逐事件?

kubectl describe node <node-name> | grep -i 'eviction'

或者直接查看 kubelet 日志中 eviction 相关记录。

如何临时禁用资源预留?

systemReservedkubeReserved 设置为空或全部设为 0,并移除 evictionHard(不推荐生产环境使用)。

总结

节点资源预留是 Kubernetes 集群稳定性的基石之一。通过合理配置 --system-reserved--kube-reserved--eviction-hard,你可以清晰划分系统、Kubernetes 和业务 Pod 之间的资源界限,避免“挤占”导致的雪崩效应。记住:Allocatable 才是调度器看到的可用资源,在规划 Pod 资源请求时,务必着眼于此数值,而非简单的物理资源总量。

想要深入了解更多调度、资源管理话题,欢迎继续查看我们的其他免费教程。