2. Kubernetes 节点资源模型:CPU、内存、磁盘、网络、PID 的资源预留机制

在 Kubernetes 集群中,节点(Node)是承载 Pod 的物理或虚拟主机。节点资源模型定义了操作系统与 kubelet 如何划分、预留和调度 CPU、内存、磁盘、网络与 PID 等关键资源。合理的资源预留是保障节点稳定性、避免系统 OOM 或 Pod 驱逐的前提,也是容量规划与镜像拉取加速的基础。

2.1 节点资源预留的总体架构

Kubernetes 节点上的资源分为三层:系统预留(System Reserved)、kubelet 预留(Kubelet Reserved)和Pod 可用(Allocatable)。kubelet 在启动时根据配置计算 Allocatable 值,调度器据此判断节点能否容纳新 Pod。

核心公式:
Allocatable = Node Capacity - System Reserved - Kubelet Reserved - Eviction Thresholds
节点资源预留分层架构 节点资源预留分层架构 Node Capacity(节点总容量) System Reserved(系统预留) sshd、systemd、内核线程、监控代理等 OS 守护进程 Kubelet Reserved(kubelet 预留) kubelet、容器运行时、cAdvisor、CNI 插件 Eviction Thresholds(驱逐阈值) Allocatable(Pod 可用资源) --system-reserved --kubelet-reserved --eviction-hard

2.2 各资源维度的预留机制

不同资源在节点上的预留方式与参数各不相同。下表总结了 CPU、内存、磁盘、网络与 PID 的预留配置项与典型值。

资源维度 预留参数 默认值 驱逐阈值参数 典型配置建议
CPU --system-reserved=cpu=100m 0 无(CPU 不驱逐) 100m~500m(根据节点核数)
内存 --system-reserved=memory=512Mi 0 --eviction-hard=memory.available<100Mi 系统预留 512Mi~2Gi;驱逐阈值保留 100Mi~500Mi
磁盘(根分区) --system-reserved=ephemeral-storage=1Gi 0 --eviction-hard=nodefs.available<10% 预留 1Gi~10Gi;驱逐阈值 5%~10%
磁盘(镜像分区) 无直接预留参数 — --eviction-hard=imagefs.available<15% 镜像分区驱逐阈值 10%~15%
网络 无原生预留参数 — 无原生驱逐阈值 通过 CNI 带宽管理或 QoS 间接控制
PID --system-reserved=pid=1000 0 --eviction-hard=pids.available<10% 系统预留 500~2000;驱逐阈值 5%~10%

2.3 CPU 与内存预留详解

2.3.1 CPU 预留

CPU 预留通过 --system-reserved=cpu=... 和 --kubelet-reserved=cpu=... 设置。预留的 CPU 不会分配给 Pod,但 kubelet 仍会统计其使用量。CPU 是可压缩资源,不会触发驱逐,但过度预留会导致 Pod 可调度核数减少。

实践建议: 对于 8 核节点,建议系统预留 200m,kubelet 预留 100m,合计 300m(约 3.75%)。对于 64 核节点,预留比例可降至 2%~3%。

2.3.2 内存预留

内存是不可压缩资源,预留不足会导致系统 OOM Killer 杀死关键进程。kubelet 通过 --eviction-hard=memory.available<100Mi 设置硬驱逐阈值,当节点可用内存低于该值时开始驱逐 Pod。

避坑提示: 不要将 --system-reserved 与 --kubelet-reserved 之和设得过高,否则 Allocatable 会远小于实际可用内存,造成资源浪费。建议预留总量不超过节点内存的 15%。

2.4 磁盘与镜像存储预留

磁盘预留分为两个维度:节点文件系统(nodefs,即 / 分区)和镜像文件系统(imagefs,即容器镜像存储分区)。

  • nodefs 预留: 通过 --system-reserved=ephemeral-storage=... 设置,驱逐阈值使用 --eviction-hard=nodefs.available<10%。
  • imagefs 预留: 没有直接的预留参数,但可以通过 --eviction-hard=imagefs.available<15% 设置驱逐阈值,防止镜像存储写满导致拉取失败。
镜像拉取加速关联: 当 imagefs 可用空间低于驱逐阈值时,kubelet 会触发垃圾回收(GC)删除未使用的镜像层,导致后续 Pod 启动时需重新拉取镜像。合理设置 imagefs 驱逐阈值(如 15%~20%)可减少不必要的 GC 频率,间接加速镜像拉取。

2.5 网络与 PID 预留

2.5.1 网络预留

Kubernetes 原生没有网络预留参数。网络资源的隔离通常依赖 CNI 插件的带宽管理(如 kubernetes.io/egress-bandwidth 注解)或节点级别的 tc/iptables 策略。在容量规划中,建议为系统进程预留 10%~20% 的节点带宽,避免 Pod 流量挤占监控与日志上报通道。

2.5.2 PID 预留

PID 预留通过 --system-reserved=pid=1000 和 --eviction-hard=pids.available<10% 控制。当节点 PID 耗尽时,新进程(包括容器进程)无法创建,可能导致节点不可用。

节点规格 系统预留 PID kubelet 预留 PID 驱逐阈值 Pod 可用 PID
4 vCPU / 8GB 500 200 10% ~3000
16 vCPU / 64GB 1000 500 5% ~18000
64 vCPU / 256GB 2000 1000 5% ~57000

2.6 资源预留配置示例

以下是一个生产级 kubelet 配置片段(KubeletConfiguration YAML),展示了完整的资源预留参数:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
  memory.available: "100Mi"
  nodefs.available: "10%"
  nodefs.inodesFree: "5%"
  imagefs.available: "15%"
  pids.available: "10%"
evictionSoft:
  memory.available: "300Mi"
  nodefs.available: "15%"
evictionSoftGracePeriod:
  memory.available: "1m30s"
  nodefs.available: "2m"
kubeReserved:
  cpu: "200m"
  memory: "512Mi"
  ephemeral-storage: "1Gi"
  pid: "500"
systemReserved:
  cpu: "300m"
  memory: "1Gi"
  ephemeral-storage: "2Gi"
  pid: "1000"
kubeReservedCgroup: "/kubelet.slice"
systemReservedCgroup: "/system.slice"
enforceNodeAllocatable:
- pods
- system-reserved
- kubelet-reserved
关键说明: enforceNodeAllocatable 列表中的 system-reserved 和 kubelet-reserved 需要对应的 cgroup 路径存在且正确,否则 kubelet 会拒绝启动。

2.7 资源预留对镜像拉取加速的影响

资源预留直接影响镜像拉取加速的两个关键环节:

  • 磁盘预留不足 → 频繁 GC → 镜像层被删除 → 拉取延迟增加。 建议将 imagefs 驱逐阈值设为 15%~20%,并预留足够的 ephemeral-storage。
  • CPU/内存预留不足 → kubelet 或容器运行时被 OOM Kill → 镜像拉取中断。 确保 kubelet 和 containerd/CRI-O 有充足的内存预留。
资源预留与镜像拉取加速关联流程 资源预留 → 镜像拉取加速关联流程 资源预留配置 --system-reserved 节点稳定性提升 无 OOM / 无 PID 耗尽 GC 频率降低 镜像层保留更久 镜像拉取加速 减少远程拉取次数 核心结论:合理的资源预留 → 节点稳定 + 低 GC 频率 → 镜像层缓存命中率提升 → 拉取延迟降低 30%~60%

2.8 常见问题与避坑指南

  • 预留值设置过高: 导致 Allocatable 过小,Pod 调度失败。建议监控节点实际系统与 kubelet 资源占用,按峰值 + 20% 缓冲设置。
  • cgroup 路径不匹配: 设置 systemReservedCgroup 和 kubeReservedCgroup 后,必须确保 cgroup 树中存在对应路径,否则 kubelet 报错退出。
  • 忽略 imagefs 驱逐阈值: 默认 imagefs 驱逐阈值可能过低(如 5%),导致镜像 GC 过于激进。建议调高至 15%~20%。
  • 网络与 PID 预留被忽视: 高密度 Pod 场景下,PID 耗尽比内存耗尽更隐蔽。务必设置 pids.available 驱逐阈值。
容量规划检查清单:
✅ 确认 --system-reserved 覆盖 sshd、监控、日志等关键进程
✅ 确认 --kubelet-reserved 覆盖 kubelet + 容器运行时
✅ 设置合理的 imagefs 驱逐阈值(≥15%)
✅ 设置 PID 驱逐阈值(5%~10%)
✅ 验证 enforceNodeAllocatable 包含 pods、system-reserved、kubelet-reserved
✅ 监控 node_allocatable_* 指标,确保预留比例在预期范围内