3. Kubernetes 节点资源模型
在 Kubernetes 集群中,每个节点都是一台物理机或虚拟机,其核心资源——CPU、内存、磁盘与网络——被抽象为可调度、可隔离、可监控的量化模型。理解节点资源模型是水位监控与调优的基础:只有准确掌握节点“有多少资源”、“Pod 如何申请资源”、“剩余可分配资源是多少”,才能判断 eBPF 采集到的指标是否处于健康水位。
3.1 节点资源抽象:四类核心资源
Kubernetes 将节点资源分为四大类,每类都有独立的计量单位与调度语义:
| 资源类型 | 计量单位 | 调度语义 | 典型监控指标 |
|---|---|---|---|
| CPU | cores(核) 100m = 0.1 core |
可压缩资源:超卖时仅限流,不杀死 Pod | cpu/usage_rate, cpu/throttled_seconds |
| Memory | bytes(Ki, Mi, Gi) | 不可压缩资源:超卖时触发 OOM Kill | memory/usage, memory/working_set, oom_count |
| Ephemeral Storage | bytes(Mi, Gi) | 不可压缩资源:超卖时触发 Pod Eviction | ephemeral_storage/usage, image_filesystem/usage |
| Network | 带宽 bps, PPS, 连接数 | 非原生调度资源(由 CNI 插件管理) | network/rx_bytes, tx_bytes, drop_count |
关键认知:CPU 是可压缩资源,超限时仅被限流(throttle),Pod 仍存活;内存与磁盘是不可压缩资源,超限直接导致 Pod 被杀死或驱逐。eBPF 水位监控应优先关注不可压缩资源的剩余水位。
3.2 Pod 资源请求与限制
每个 Pod 中的容器都可以声明两类资源参数:
- requests:调度时保证的最小资源量,kube-scheduler 依据所有 Pod 的 requests 总和判断节点是否可调度。
- limits:容器运行时不能超过的资源上限,由 kubelet 配合 cgroups 强制约束。
以下是一个典型 Pod 的资源声明示例:
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "500m" # 0.5 核
memory: "256Mi" # 256 MiB
ephemeral-storage: "1Gi"
limits:
cpu: "1000m" # 1 核
memory: "512Mi" # 512 MiB
ephemeral-storage: "2Gi"
requests 与 limits 的四种组合模式:
| 模式 | requests | limits | 调度与运行行为 |
|---|---|---|---|
| Guaranteed | 等于 limits | 等于 requests | 最高 QoS 等级,优先保证,不被驱逐 |
| Burstable | 小于 limits | 大于 requests | 中等 QoS,允许突发使用空闲资源 |
| BestEffort | 未设置 | 未设置 | 最低 QoS,资源完全弹性,优先被驱逐 |
| 仅设置 limits | 默认等于 limits | 显式设置 | 实际等同于 Guaranteed(隐式继承) |
水位调优陷阱:大量 Burstable Pod 的 requests 设置过低而 limits 过高,会导致节点“调度时看似空闲,运行时实际超卖严重”。eBPF 应同时监控
requests 总和 与 实际使用量 两条水位线。
3.3 节点可分配资源计算
节点可分配资源(Allocatable)是 kubelet 向调度器报告的实际可用资源量,其计算公式为:
Allocatable = Node Capacity
- Reserved (系统预留)
- Eviction Threshold (驱逐阈值)
- kube-reserved (Kubernetes 组件预留)
各组成部分说明:
| 资源项 | 默认值 / 配置方式 | 说明 |
|---|---|---|
| Node Capacity | 节点物理总量 | 由 kubelet 自动检测(如 nproc、/proc/meminfo) |
| kube-reserved | --kube-reserved 参数 | 为 kubelet、kube-proxy、容器运行时预留 |
| system-reserved | --system-reserved 参数 | 为 sshd、systemd 等 OS 守护进程预留 |
| Eviction Threshold | --eviction-hard 默认值 | 内存 100Mi、磁盘 10% 等硬驱逐线 |
| Allocatable | 自动计算 | 调度器只参考此值,而非 Node Capacity |
查看节点可分配资源的命令:
# 查看节点完整资源状态
kubectl describe node <node-name>
# 输出片段示例:
# Capacity:
# cpu: 8
# memory: 32947712Ki
# ephemeral-storage: 102350412Ki
# Allocatable:
# cpu: 7820m
# memory: 30847712Ki
# ephemeral-storage: 94350123123
eBPF 水位监控关键公式:
节点剩余可分配资源 = Allocatable - (所有 Pod 实际使用量) - (系统预留已使用量)
当剩余可分配资源接近 Eviction Threshold 时,节点进入“内存压力”或“磁盘压力”状态,触发 Pod 驱逐。
节点剩余可分配资源 = Allocatable - (所有 Pod 实际使用量) - (系统预留已使用量)
当剩余可分配资源接近 Eviction Threshold 时,节点进入“内存压力”或“磁盘压力”状态,触发 Pod 驱逐。
3.4 节点资源水位与 eBPF 监控切入点
基于上述资源模型,eBPF 在节点水位监控中的三个核心切入点:
- CPU 水位:通过 tracepoint/sched/sched_switch 或 kprobe 采集每个 cgroup 的 CPU 使用时间,计算 throttled 比例。
- 内存水位:通过 cgroup 内存控制器的
memory.current与memory.working_set文件,结合 eBPF 的 cgroup 路径遍历,实时计算 Pod 级内存使用量。 - 磁盘与网络水位:通过 tracepoint/block/block_rq_complete 和 tracepoint/net/netif_receive_skb,统计每个 Pod 的磁盘 I/O 与网络吞吐。
实战建议:在 eBPF 程序中同时采集
Allocatable - sum(Pod requests)(调度水位)和 Allocatable - sum(Pod actual usage)(运行水位),两条水位线的差值就是节点“超卖弹性空间”。当运行水位持续高于调度水位 20% 以上时,说明存在大量 Burstable Pod 在突发使用资源,需要调整 requests 或引入 Pod 水平自动扩缩。