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 会执行以下动作:
- 标记状态:将节点 Condition 置为
False或Unknown。 - 设置 Taint:自动添加
node.kubernetes.io/unreachable或node.kubernetes.io/not-ready污点。 - 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 调度的完整资源流转路径:
2.6 节点状态监控流程图
当节点出现异常时,Kubernetes 的监控与自愈流程如下:
2.7 最佳实践与避坑指南
- 始终为系统预留至少 5%~10% 的 CPU 和内存,避免系统进程被饿死。
- 使用
kubectl describe node定期审计 Allocatable 与 Capacity 的差值,确认预留是否合理。 - 结合 Prometheus + Grafana 监控节点资源使用趋势,动态调整预留参数。
- 对于延迟敏感型应用,使用
--reserved-cpus将特定核心隔离给系统进程。
- 将
Capacity误认为可用资源,导致 Pod 调度后节点过载。 - 忽略
ephemeral-storage预留,导致容器日志写满根分区。 - 未设置
--eviction-hard,节点在内存耗尽时直接 OOM Kill 系统进程。