3. K8s节点资源模型:CPU、内存、磁盘、网络、PID的资源抽象与Kubernetes资源管理模型
3.1 资源抽象的五维模型
Kubernetes 将物理节点抽象为五个独立的资源维度,每个维度在调度、隔离和监控层面具有不同的语义。理解这五类资源的本质差异,是进行容量规划的前提。
| 资源维度 | 可压缩性 | 回收机制 | 过量使用(Overcommit) | 监控关键指标 |
|---|---|---|---|---|
| CPU | 可压缩 | CFS 配额/限流 | 支持(时间片竞争) | cpu/usage_rate, throttling |
| Memory | 不可压缩 | OOM Killer | 不支持(严格限制) | memory/usage, working_set |
| Ephemeral Storage | 不可压缩 | Pod 驱逐 | 不支持(节点级保护) | node_filesystem_avail |
| Network Bandwidth | 可压缩 | TC/带宽限速 | 支持(共享带宽池) | node_network_transmit_bytes |
| PID | 可压缩 | Pod 创建失败 | 有限支持 | node_processes_state |
3.2 CPU 资源模型:时间片与配额
Kubernetes 将 CPU 视为可压缩资源,通过 CFS(Completely Fair Scheduler)实现配额管理。CPU 的抽象单位是 core(核),支持小数精度(如 0.5 = 500m)。
- requests:调度时保证的最小 CPU 时间片,对应 CFS
cpu.shares。 - limits:Pod 可使用的 CPU 上限,对应 CFS
cpu.cfs_quota_us。 - throttling:当 Pod 超过 limits 时,内核强制限流,表现为 CPU 节流。
# 查看节点 CPU 分配情况
kubectl describe node <node-name> | grep -A5 "Capacity"
# 输出示例:
# cpu: 8
# memory: 32948212Ki
# Allocated resources:
# Resource Requests Limits
# cpu 3500m (43%) 6800m (85%)
3.3 内存资源模型:不可压缩的硬约束
内存是 Kubernetes 中最关键的不可压缩资源。Pod 的内存使用超过 limits 时,内核 OOM Killer 会直接终止进程。Kubernetes 通过 cgroup 的 memory.limit_in_bytes 实现硬限制。
| 内存指标 | 含义 | 容量规划用途 |
|---|---|---|
| memory.usage_bytes | 当前 RSS + Cache | 实时使用量 |
| memory.working_set_bytes | usage - 非活跃文件缓存 | 调度决策依据 |
| memory.available_bytes | 节点可用内存 | 节点压力判断 |
| container_memory_rss | 常驻内存(不含缓存) | 应用真实内存占用 |
memory.usage_bytes 作为 Pod 内存上限的规划依据。Linux 内核会积极使用空闲内存做文件缓存,导致 usage 偏高。应使用 working_set 或 rss 作为基准。
3.4 磁盘与网络:容易被忽略的容量瓶颈
磁盘和网络在 Kubernetes 资源模型中属于 可扩展资源,但它们的耗尽同样会导致节点不可用。
3.4.1 临时存储(Ephemeral Storage)
每个 Pod 在节点上消耗临时存储(日志、容器层、emptyDir)。Kubelet 通过 nodefs.available 和 imagefs.available 监控磁盘水位,触发驱逐阈值。
# kubelet 驱逐阈值配置示例(kubelet 启动参数)
--eviction-hard=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%
--eviction-soft=memory.available<300Mi,nodefs.available<15%
--eviction-soft-grace-period=memory.available=1m30s,nodefs.available=1m30s
3.4.2 网络带宽
Kubernetes 原生不提供网络带宽的 QoS 保证,但 CNI 插件(如 Calico、Cilium)和流量整形工具(TC)可以实现带宽限制。容量规划时需关注:
- 节点总带宽:物理网卡或云厂商实例带宽上限。
- Pod 带宽:通过
kubernetes.io/egress-bandwidth注解设置。 - 网络丢包与重传:
node_network_drop和node_network_retransmit指标。
3.5 PID 资源:节点级保护的最后一道防线
Linux 内核的 PID 上限是节点级资源。当节点上所有进程(包括系统进程)的 PID 数量达到 kernel.pid_max(默认 32768)时,新进程创建失败。Kubernetes 1.14+ 引入 PodPidsLimit 特性,通过 --pod-max-pids 限制每个 Pod 的 PID 数量。
# 查看节点 PID 使用情况
cat /proc/sys/kernel/pid_max
# 输出:32768
# 查看当前 PID 分配数
ps -eLf | wc -l
3.6 Kubernetes 资源管理模型:Request/Limit 与 QoS
Kubernetes 通过 Request/Limit 机制和 QoS Class 实现资源管理。这是容量规划的核心抽象层。
3.7 资源抽象与 Prometheus 指标的映射
Prometheus 采集的指标与 Kubernetes 资源模型存在直接对应关系。理解这个映射是后续容量规划计算的基础。
| K8s 资源抽象 | Prometheus 指标 | 聚合方式 | 容量规划用途 |
|---|---|---|---|
| CPU Request | kube_pod_resource_request{resource="cpu"} |
SUM by(node) | 计算节点 CPU 分配率 |
| CPU Limit | kube_pod_resource_limit{resource="cpu"} |
SUM by(node) | 计算 CPU 超卖比 |
| CPU 实际使用 | node_cpu_seconds_total{mode!="idle"} |
rate() | 计算 CPU 利用率 |
| Memory Request | kube_pod_resource_request{resource="memory"} |
SUM by(node) | 计算内存分配率 |
| Memory 实际使用 | container_memory_working_set_bytes |
SUM by(node) | 计算内存真实占用 |
| 磁盘使用 | node_filesystem_avail_bytes{mountpoint="/"} |
avg by(node) | 计算磁盘剩余容量 |
| PID 使用 | node_processes_state{state="running"} |
count by(node) | 计算 PID 使用率 |
3.8 资源抽象在容量规划中的综合应用
将五维资源模型与 Kubernetes 资源管理模型结合,形成容量规划的完整视图:
- 节点容量天花板:节点 Capacity = 物理资源总量(CPU 核数、内存大小、磁盘空间、网络带宽、PID 上限)。
- 已分配容量:所有 Pod 的 Request 总和,决定调度器能否将新 Pod 调度到该节点。
- 实际使用容量:Prometheus 采集的实时使用量,决定节点是否处于过载状态。
- 可超卖容量:Capacity - 已分配 Request 总量,这部分资源可以被 Burstable Pod 在空闲时使用。
- 安全阈值:针对不可压缩资源(内存、磁盘),建议预留 15%~20% 的容量作为安全缓冲。
# 容量规划核心计算公式(以 CPU 为例)
CPU_Allocatable = Node_Capacity - kube_reserved - system_reserved
CPU_Request_Total = SUM(kube_pod_resource_request{resource="cpu"})
CPU_Overcommit_Ratio = CPU_Request_Total / CPU_Allocatable
CPU_Utilization = rate(node_cpu_seconds_total{mode!="idle"}[5m])
# 安全判定条件
CPU_Overcommit_Ratio < 0.85 # 调度安全
CPU_Utilization < 0.75 # 运行安全