4. 节点资源概述:CPU、内存、磁盘、网络、PID、inode 等关键资源
当 Deployment 镜像拉取失败时,节点资源耗尽往往是“隐形杀手”。Kubernetes 节点是一个共享资源池,任何一项关键资源达到上限,都会导致 kubelet 无法正常创建容器、拉取镜像或写入文件。本节系统梳理节点上六类核心资源,帮助你在排查时快速定位瓶颈。
4.1 资源全景与排查优先级
节点资源并非孤立存在,它们通过操作系统内核和容器运行时紧密耦合。以下表格按排查优先级列出各类资源及其典型故障表现:
| 资源类型 | 排查优先级 | 镜像拉取失败时的典型表现 | 关键指标 |
|---|---|---|---|
| CPU | 中 | 容器启动超时、kubelet 响应缓慢 | 使用率、负载、节流时间 |
| 内存 | 高 | OOM Kill、容器退出、kubelet 被驱逐 | 可用内存、Swap 使用、OOM 计数 |
| 磁盘 | 最高 | 镜像层写入失败、容器运行时无响应 | 磁盘使用率、inode 使用率、IO 等待 |
| 网络 | 高 | 镜像仓库连接超时、DNS 解析失败 | 带宽、连接数、丢包率 |
| PID | 中 | 容器创建失败、进程 fork 被拒绝 | PID 使用率、线程数 |
| inode | 高 | 文件创建失败、镜像层解压报错 | inode 使用率、文件系统元数据 |
4.2 节点资源架构关系
下图展示了 Kubernetes 节点上各类资源与容器运行时的交互关系,以及镜像拉取路径上的关键资源依赖点:
4.3 关键资源详解
4.3.1 CPU 资源
CPU 是计算核心,Kubernetes 通过 CPU requests 和 limits 进行调度与限制。镜像拉取过程中,CPU 主要用于镜像层解压缩(gzip/zstd)和校验。当 CPU 使用率持续超过 90% 或负载(load average)超过核心数 2 倍时,容器启动时间会显著延长。
- 排查命令:
top、htop、cat /proc/loadavg - 关键指标:CPU 使用率、load average、CPU 节流时间(throttled time)
- 镜像拉取影响:解压速度下降,可能导致 kubelet 超时重试
4.3.2 内存资源
内存不足会触发 OOM Killer,直接杀死容器或 kubelet 进程。镜像拉取时,容器运行时需要内存缓存镜像层数据,内存压力过大会导致 swap 频繁交换,进一步降低 IO 性能。
- 排查命令:
free -h、cat /proc/meminfo、dmesg | grep -i oom - 关键指标:可用内存、Swap 使用量、OOM 事件计数
- 镜像拉取影响:容器运行时进程被 OOM Kill,拉取中断
4.3.3 磁盘资源
磁盘是镜像拉取失败最常见的资源瓶颈。容器运行时需要将镜像层写入 /var/lib/containerd 或 /var/lib/docker 目录。磁盘使用率超过 85% 时,写入性能急剧下降;超过 95% 时,写入直接失败。
- 排查命令:
df -h、iostat -x 1、du -sh /var/lib/containerd - 关键指标:磁盘使用率、IO 等待时间、读写延迟
- 镜像拉取影响:层数据无法写入,kubelet 报错
ImagePullBackOff
4.3.4 网络资源
网络影响镜像拉取的远程连接阶段。带宽不足、连接数耗尽、DNS 解析失败都会导致拉取超时。节点上 conntrack 表满会导致新连接被丢弃,这是生产环境常见问题。
- 排查命令:
ss -s、cat /proc/net/nf_conntrack、ping、nslookup - 关键指标:连接数、conntrack 使用率、丢包率、DNS 解析时间
- 镜像拉取影响:仓库连接超时,拉取进度卡在 0%
4.3.5 PID 资源
每个进程和线程都占用一个 PID。Kubernetes 节点上运行大量容器,每个容器内部又有多个进程。当 PID 使用率达到上限(默认 kernel.pid_max 通常为 32768),新进程无法创建,容器启动失败。
- 排查命令:
cat /proc/sys/kernel/pid_max、ps aux | wc -l - 关键指标:当前 PID 数量、PID 使用率、线程数
- 镜像拉取影响:容器运行时无法 fork 新进程处理镜像拉取
4.3.6 inode 资源
inode 是文件系统的元数据索引。即使磁盘空间充足,inode 耗尽也会导致无法创建新文件。镜像层包含大量小文件(如二进制、配置文件),解压时需消耗大量 inode。
- 排查命令:
df -i、find /var -xdev -printf '%h\n' | sort | uniq -c | sort -k1 -rn | head - 关键指标:inode 使用率、文件系统类型(ext4/xfs 的 inode 限制不同)
- 镜像拉取影响:镜像层解压时报错
no space left on device,但df -h显示空间充足
df -h),忽略了 inode 使用率(df -i)。当镜像包含大量小文件(如 Node.js 的 node_modules)时,inode 可能先于磁盘空间耗尽。建议将 inode 检查纳入日常巡检脚本。
4.4 资源排查命令速查表
| 资源类型 | 核心命令 | 关键输出字段 | 告警阈值 |
|---|---|---|---|
| CPU | top -bn1 | head -5 |
%Cpu(s), load average | 使用率 > 80%, 负载 > 核心数×2 |
| 内存 | free -h |
available, swap used | 可用 < 10%, swap > 0 |
| 磁盘 | df -h /var/lib/containerd |
Use% | Use% > 85% |
| inode | df -i /var/lib/containerd |
IUse% | IUse% > 90% |
| 网络 | ss -s |
TCP estab, conntrack count | 连接数 > 10000 |
| PID | cat /proc/sys/kernel/pid_max |
当前 PID 数 | 使用率 > 90% |
4.5 资源耗尽时的典型错误日志
当节点资源不足时,kubelet 和容器运行时会输出特定错误日志。以下是最常见的几种:
# 磁盘空间不足
failed to create containerd task: failed to create shim task: OCI runtime create failed: ...
write /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs: no space left on device
# inode 耗尽
failed to extract layer sha256:...: write /var/lib/containerd/...: no space left on device
# 注意:此时 df -h 可能显示仍有空间,但 df -i 显示 100%
# 内存 OOM
Memory cgroup out of memory: Killed process 12345 (containerd)
# 或 kubelet 日志中出现
Evicted pod "xxx" due to memory pressure
# PID 耗尽
fork: retry: Resource temporarily unavailable
# 容器运行时无法创建新进程
ImagePullBackOff 且镜像仓库连接正常时,立即执行 df -h 和 df -i 检查磁盘与 inode。同时使用 dmesg -T | tail -20 查看内核日志,OOM 和 PID 耗尽都会在这里留下记录。
4.6 资源监控与预防
资源排查不应是事后补救,而应建立主动监控体系。以下是一个简单的节点资源巡检脚本片段:
#!/bin/bash
# 节点资源健康检查脚本
NODE_NAME=$(hostname)
ALERT_THRESHOLD_DISK=85
ALERT_THRESHOLD_INODE=90
ALERT_THRESHOLD_MEM=90
# 磁盘检查
DISK_USAGE=$(df -h /var/lib/containerd | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt "$ALERT_THRESHOLD_DISK" ]; then
echo "[WARN] $NODE_NAME 磁盘使用率: $DISK_USAGE% (阈值: $ALERT_THRESHOLD_DISK%)"
fi
# inode 检查
INODE_USAGE=$(df -i /var/lib/containerd | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$INODE_USAGE" -gt "$ALERT_THRESHOLD_INODE" ]; then
echo "[WARN] $NODE_NAME inode 使用率: $INODE_USAGE% (阈值: $ALERT_THRESHOLD_INODE%)"
fi
# 内存检查
MEM_AVAILABLE=$(free | awk '/^Mem:/ {print $7}')
MEM_TOTAL=$(free | awk '/^Mem:/ {print $2}')
MEM_USAGE=$(( (MEM_TOTAL - MEM_AVAILABLE) * 100 / MEM_TOTAL ))
if [ "$MEM_USAGE" -gt "$ALERT_THRESHOLD_MEM" ]; then
echo "[WARN] $NODE_NAME 内存使用率: $MEM_USAGE% (阈值: $ALERT_THRESHOLD_MEM%)"
fi
将上述脚本加入 cron 定时任务(每 5 分钟执行一次),可有效提前发现资源瓶颈,避免镜像拉取失败扩散为大规模故障。