4. 节点资源模型:Allocatable、Reserved、Capacity 的关系
在 Kubernetes 集群中,一个节点的物理资源(CPU、内存、磁盘、PID 等)并非全部可供 Pod 使用。操作系统内核、系统守护进程(sshd、systemd、kubelet 等)以及 Kubernetes 组件(kubelet、容器运行时)都需要占用一部分资源。为了准确描述“节点到底有多少资源可以分配给 Pod”,K8s 定义了三个核心概念:节点容量(Capacity)、资源预留(Reserved) 和 节点可分配资源(Allocatable)。
理解这三者的关系,是进行调度器参数调优和节点资源分配均衡的基础。错误的预留配置会导致节点资源利用率低下或 Pod 调度失败。
4.1 核心概念定义
| 概念 | 英文 | 定义 | 来源 |
|---|---|---|---|
| 节点容量 | Capacity | 节点上硬件资源的总量,例如 4 核 CPU、16 GB 内存。这是节点资源的上限。 | kubelet 自动检测(如 /proc/cpuinfo、/proc/meminfo) |
| 资源预留 | Reserved | 为系统守护进程和 Kubernetes 组件预留的资源,Pod 不可使用。包括 --system-reserved 和 --kube-reserved。 |
kubelet 启动参数配置 |
| 节点可分配资源 | Allocatable | 节点上真正可以分配给 Pod 使用的资源量。调度器基于此值判断 Pod 是否能调度到该节点。 | Capacity - Reserved - (Hard Eviction Threshold) |
关键公式:
其中
Allocatable = Capacity - Reserved - HardEvictionThreshold其中
Reserved = system-reserved + kube-reserved。硬驱逐阈值(Hard Eviction Threshold)通常为内存和磁盘预留一小部分空间,防止节点资源耗尽时无法驱逐 Pod。
4.2 三层资源模型关系图
下图展示了从物理硬件到 Pod 可用资源的完整链路。调度器只关心最内层的 Allocatable 区域。
4.3 预留配置参数详解
kubelet 通过以下启动参数控制资源预留。这些参数通常在节点初始化时配置,或在 kubelet 配置文件中设置。
| 参数 | 作用域 | 示例值 | 说明 |
|---|---|---|---|
--system-reserved |
操作系统守护进程 | cpu=500m,memory=1Gi |
为 sshd、systemd、内核、日志等预留 |
--kube-reserved |
Kubernetes 组件 | cpu=200m,memory=512Mi |
为 kubelet、容器运行时、cAdvisor 预留 |
--eviction-hard |
硬驱逐阈值 | memory.available<100Mi |
当节点内存低于此值时,kubelet 开始驱逐 Pod |
--eviction-soft |
软驱逐阈值 | memory.available<200Mi |
配合 eviction-soft-grace-period 使用,给予 Pod 优雅退出时间 |
常见误区:
- 预留过多:导致 Allocatable 过小,Pod 调度受限,节点资源利用率低。
- 预留过少:系统组件资源不足,导致节点不稳定,kubelet 被 OOM Kill。
- 忽略硬驱逐阈值:Allocatable 计算时默认会减去硬驱逐阈值,如果手动配置不当,可能导致节点内存耗尽时无法触发驱逐。
4.4 调度器如何感知 Allocatable
调度器通过 Node 对象的 Status 字段 获取节点的 Allocatable 信息。当调度器为 Pod 选择节点时,会执行以下检查:
- 获取节点 Allocatable:从
node.Status.Allocatable读取 CPU、内存等资源量。 - 计算已分配资源:统计该节点上所有已调度 Pod 的
requests总和。 - 判断剩余资源:如果
Allocatable - 已分配资源 >= Pod 的 requests,则节点满足调度条件。
以下是一个 Node 对象的 Allocatable 示例(通过 kubectl describe node 查看):
Capacity:
cpu: 4
memory: 16384688Ki
ephemeral-storage: 102350Mi
Allocatable:
cpu: 3
memory: 15284688Ki
ephemeral-storage: 98230Mi
在这个例子中,系统预留了 1 个 CPU 和约 1 GB 内存(Capacity - Allocatable)。调度器只会看到 Allocatable.cpu = 3,因此最多只能调度 requests 总和不超过 3 个 CPU 的 Pod。
4.5 预留配置最佳实践
| 节点类型 | 推荐预留比例(CPU) | 推荐预留比例(内存) | 说明 |
|---|---|---|---|
| 小型节点(<= 4 核) | 10% - 15% | 10% - 15% | 系统组件占比相对较大,预留比例应偏高 |
| 中型节点(8 - 16 核) | 6% - 10% | 5% - 10% | 平衡资源利用率与系统稳定性 |
| 大型节点(32 核以上) | 3% - 6% | 3% - 5% | 系统组件开销相对较小,预留比例可降低 |
调优建议:
- 使用
kubectl describe node定期检查 Allocatable 与 Capacity 的差值,确认预留是否合理。 - 对于内存密集型工作负载,适当提高
--eviction-hard阈值(如memory.available<200Mi),避免 OOM 时无响应。 - 在集群初始化阶段,通过
kubelet-config.yaml统一管理预留参数,避免节点间配置不一致。