4. 节点资源概述:CPU、内存、磁盘、网络、PID、inode 等关键资源

当 Deployment 镜像拉取失败时,节点资源耗尽往往是“隐形杀手”。Kubernetes 节点是一个共享资源池,任何一项关键资源达到上限,都会导致 kubelet 无法正常创建容器、拉取镜像或写入文件。本节系统梳理节点上六类核心资源,帮助你在排查时快速定位瓶颈。

4.1 资源全景与排查优先级

节点资源并非孤立存在,它们通过操作系统内核和容器运行时紧密耦合。以下表格按排查优先级列出各类资源及其典型故障表现:

资源类型 排查优先级 镜像拉取失败时的典型表现 关键指标
CPU 中 容器启动超时、kubelet 响应缓慢 使用率、负载、节流时间
内存 高 OOM Kill、容器退出、kubelet 被驱逐 可用内存、Swap 使用、OOM 计数
磁盘 最高 镜像层写入失败、容器运行时无响应 磁盘使用率、inode 使用率、IO 等待
网络 高 镜像仓库连接超时、DNS 解析失败 带宽、连接数、丢包率
PID 中 容器创建失败、进程 fork 被拒绝 PID 使用率、线程数
inode 高 文件创建失败、镜像层解压报错 inode 使用率、文件系统元数据
排查经验:磁盘和 inode 是镜像拉取失败最直接的资源瓶颈。当节点磁盘使用率超过 85% 或 inode 使用率超过 90% 时,容器运行时(containerd/docker)将无法写入镜像层,直接导致拉取失败。建议优先检查这两项。

4.2 节点资源架构关系

下图展示了 Kubernetes 节点上各类资源与容器运行时的交互关系,以及镜像拉取路径上的关键资源依赖点:

节点资源与镜像拉取依赖关系 节点资源池 CPU 核心 内存 (RAM) 磁盘 (Disk) 网络 (Network) PID 限制 inode 限制 kubelet Pod 生命周期管理 资源驱逐决策 镜像拉取调度 容器运行时 containerd / docker 镜像层解压与写入 镜像拉取流程 ① 仓库连接 (网络) ② 镜像清单下载 ③ 层数据下载 (磁盘) ④ 层解压 (CPU/磁盘) ⑤ 写入存储 (inode)

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 分钟执行一次),可有效提前发现资源瓶颈,避免镜像拉取失败扩散为大规模故障。