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 驱逐。
节点资源模型与可分配资源计算流程 Node Capacity(节点总容量) system-reserved OS 守护进程预留 sshd, systemd, 监控 Agent kube-reserved Kubernetes 组件预留 kubelet, kube-proxy, runtime Eviction Threshold 硬驱逐线 memory: 100Mi, disk: 10% Allocatable(可分配资源) = Node Capacity - system-reserved - kube-reserved - Eviction Threshold 调度器只参考此值,决定 Pod 是否可调度到该节点 Pod 实际使用量(requests + 运行时) 由 cgroups / eBPF 实时采集 剩余可分配资源 = Allocatable - Pod 实际使用量 当剩余可分配资源 ≤ Eviction Threshold → 节点进入压力状态 → 触发 Pod 驱逐

3.4 节点资源水位与 eBPF 监控切入点

基于上述资源模型,eBPF 在节点水位监控中的三个核心切入点:

  1. CPU 水位:通过 tracepoint/sched/sched_switch 或 kprobe 采集每个 cgroup 的 CPU 使用时间,计算 throttled 比例。
  2. 内存水位:通过 cgroup 内存控制器的 memory.current 与 memory.working_set 文件,结合 eBPF 的 cgroup 路径遍历,实时计算 Pod 级内存使用量。
  3. 磁盘与网络水位:通过 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 水平自动扩缩。