2、节点资源管理:节点容量、可分配资源、资源预留策略、节点状态监控

在 Kubernetes 集群中,每个节点(Node)都是一个资源池。调度器在决定 Pod 运行位置时,必须准确知道每个节点“还剩多少资源”。如果节点资源管理不精确,轻则 Pod 调度失败,重则节点过载导致系统不稳定。本章深入剖析节点资源的四个核心维度:节点容量、可分配资源、资源预留策略和节点状态监控。

2.1 节点容量(Node Capacity)

节点容量是指节点上所有硬件资源的总和,包括 CPU、内存、临时存储(Ephemeral Storage)、PID 数量等。Kubelet 在启动时自动检测这些资源,并通过 Node.Status.Capacity 字段上报给 API Server。

资源类型 描述 常见单位
cpu 可分配的 CPU 核心数(逻辑核) 整数或小数(如 4、0.5)
memory 物理内存总量 Ki、Mi、Gi
ephemeral-storage 节点本地临时存储(根分区) Ki、Mi、Gi
hugepages-2Mi / hugepages-1Gi 大页内存 数量(pages)
pods 节点最大 Pod 数量 整数
查看节点容量命令:
kubectl get node <node-name> -o json | jq '.status.capacity'

2.2 可分配资源(Allocatable)

节点不能把所有容量都交给 Pod 使用。操作系统、Kubelet、容器运行时(如 containerd)以及系统守护进程(如 sshd、systemd)都需要占用一部分资源。Kubernetes 通过 资源预留(Reserved) 机制从容量中扣除这些开销,剩下的才是真正可供 Pod 调度的 Allocatable 资源。

计算公式如下:

Allocatable = Node Capacity - (System Reserved + Kubelet Reserved + Eviction Thresholds)
  • System Reserved:为操作系统守护进程预留的资源。
  • Kubelet Reserved:为 Kubelet 和容器运行时预留的资源。
  • Eviction Thresholds:节点压力驱逐的硬性阈值,保证节点在资源紧张时仍有缓冲。
关键认知:调度器只参考 Node.Status.Allocatable,而不是 Capacity。如果 Pod 的 Request 总和超过 Allocatable,调度器会拒绝将 Pod 调度到该节点。

2.3 资源预留策略

资源预留通过 Kubelet 启动参数或配置文件实现。常见的预留策略有三种:

2.3.1 静态预留(Static Reservation)

通过 --system-reserved 和 --kubelet-reserved 参数直接指定预留量。

--system-reserved=cpu=500m,memory=1Gi,ephemeral-storage=10Gi
--kubelet-reserved=cpu=200m,memory=512Mi,ephemeral-storage=5Gi
--eviction-hard=memory.available<500Mi,nodefs.available<10%

2.3.2 动态预留(Dynamic Reservation)

使用 --reserved-cpus 参数将特定物理 CPU 核心完全保留给系统进程,避免 Pod 抢占。

--reserved-cpus=0,1

2.3.3 预留策略对比

策略 配置方式 适用场景 优点 缺点
静态预留 --system-reserved / --kubelet-reserved 通用场景,资源规划明确 配置简单,兼容性好 预留量固定,无法自适应
动态预留 --reserved-cpus 低延迟、高性能计算 CPU 隔离彻底,无竞争 仅支持 CPU,不支持内存
混合策略 静态 + 动态组合 生产环境,兼顾通用与性能 灵活,可精细控制 配置复杂度高
常见陷阱:如果 --system-reserved 设置过大,会导致 Allocatable 过小,大量 Pod 无法调度;设置过小,则系统进程可能因资源不足而异常。建议通过监控工具(如 Prometheus + Node Exporter)观察系统进程实际资源消耗后,再确定预留值。

2.4 节点状态监控

节点状态是调度决策的实时依据。Kubernetes 通过 Node Controller 和 Kubelet 心跳 持续监控每个节点的健康情况。

2.4.1 节点状态字段

通过 kubectl get node -o wide 可以查看节点状态,主要包含以下维度:

  • Ready:节点是否正常,Kubelet 是否能够正常上报。
  • DiskPressure:节点磁盘空间是否不足。
  • MemoryPressure:节点内存是否接近耗尽。
  • PIDPressure:节点 PID 数量是否超过阈值。
  • NetworkUnavailable:节点网络是否配置正确。

2.4.2 节点状态转换与驱逐

当节点状态异常时,Node Controller 会执行以下动作:

  1. 标记状态:将节点 Condition 置为 False 或 Unknown。
  2. 设置 Taint:自动添加 node.kubernetes.io/unreachable 或 node.kubernetes.io/not-ready 污点。
  3. Pod 驱逐:如果节点在 --pod-eviction-timeout(默认 5 分钟)内未恢复,Node Controller 将驱逐该节点上的 Pod。
监控命令:
# 查看节点所有状态
kubectl describe node <node-name>

# 持续监控节点资源使用
kubectl top node

# 查看节点事件
kubectl get events --field-selector involvedObject.kind=Node

2.5 节点资源管理全景图

下图展示了从节点容量到 Pod 调度的完整资源流转路径:

节点资源管理全景图 节点容量 CPU / 内存 / 存储 / PID 系统预留 OS + 守护进程 Kubelet 预留 Kubelet + 容器运行时 驱逐阈值 内存 / 磁盘 / PID 硬限制 可分配资源 Allocatable Pod 调度 Request ≤ Allocatable 说明: Allocatable = 节点容量 - 系统预留 - Kubelet 预留 - 驱逐阈值。调度器只检查 Allocatable,不检查 Capacity。

2.6 节点状态监控流程图

当节点出现异常时,Kubernetes 的监控与自愈流程如下:

节点状态监控与驱逐流程 节点状态异常 Node Controller 检测 标记 Condition=False 添加 NoExecute Taint 等待 pod-eviction-timeout 驱逐节点上所有 Pod 调度器重新分配 Pod 关键参数: --pod-eviction-timeout=5m(默认),可通过 kube-controller-manager 启动参数调整。

2.7 最佳实践与避坑指南

生产环境建议:
  • 始终为系统预留至少 5%~10% 的 CPU 和内存,避免系统进程被饿死。
  • 使用 kubectl describe node 定期审计 Allocatable 与 Capacity 的差值,确认预留是否合理。
  • 结合 Prometheus + Grafana 监控节点资源使用趋势,动态调整预留参数。
  • 对于延迟敏感型应用,使用 --reserved-cpus 将特定核心隔离给系统进程。
常见错误:
  • 将 Capacity 误认为可用资源,导致 Pod 调度后节点过载。
  • 忽略 ephemeral-storage 预留,导致容器日志写满根分区。
  • 未设置 --eviction-hard,节点在内存耗尽时直接 OOM Kill 系统进程。