容器故障导致宿主机资源耗尽的本质是隔离失效,需通过docker stats、docker inspect和cgroup三层验证资源限制是否生效,三者数值不一致说明约束未真正起作用。

容器故障引发宿主机资源耗尽,本质是隔离失效——容器本该被限制的资源使用突破了边界,反向拖垮整台机器。排查关键不在于“找哪个容器在作怪”,而在于确认“哪层隔离机制失灵了”。
看容器是否真被限住了
资源限制没生效,是宿主机被拖垮的最常见原因。三个命令交叉验证:
- docker stats :实时看它现在用了多少 CPU、内存、网络IO
-
docker inspect | grep -A 5 Memory:查它当初启动时设的内存上限是多少(比如
"Memory": 536870912就是 512MB) - cat /sys/fs/cgroup/memory/docker//memory.limit_in_bytes:直接读内核 cgroup 层面的实际限制值,必须和 inspect 结果一致
三者数值对不上?说明容器不是“跑飞了”,而是根本没按预期被约束——可能是启动时漏加 --memory 参数,也可能是镜像或运行时绕过了限制。
查谁在偷偷吃光磁盘
/var/lib/docker 目录占满,会让 Docker 命令卡死、新容器无法创建,甚至触发 kubelet 异常。重点盯两块:
- 执行 docker system df -v:看清哪些镜像、容器、卷占空间最多;特别注意 悬空镜像(dangling images) 和 未命名容器(
) - 执行 du -sh /var/lib/docker/* | sort -hr | head -5:定位到子目录层级,比如
overlay2或containers下某个 ID 占了上百 GB,大概率是日志疯长或应用缓存没清理
若发现某容器日志文件异常庞大(如 /var/lib/docker/containers/<id>/<id>-json.log</id></id> 超过 10GB),说明它没配日志轮转,得立刻用 docker update --log-opt max-size=10m --log-opt max-file=3 补救。
抓正在杀进程的 OOM Killer
宿主机内存告急时,Linux 内核会主动杀进程保系统——被杀的往往不是那个最耗内存的容器,而是它里面某个子进程。线索很明确:
- 运行 dmesg -T | grep -i "killed process":输出里会带时间戳、被杀进程名、内存用量(如
anon-rss:482000kB),直接锁定肇事容器 - 检查该容器退出码:docker inspect | grep -E "(ExitCode|OOMKilled)":若
ExitCode是 137 且OOMKilled为 true,100% 是内存超限被杀 - 进容器内部看 Java 或 Node.js 应用日志:docker logs --tail 50 | grep -i "heap\|outofmemory\|gc overhead":确认是不是应用自身内存泄漏导致反复冲限
验网络和 PID 是否失控扩散
有些故障不体现在 CPU 或内存数字上,而是通过连接数或进程数压垮系统:
- 查连接风暴:ss -s 看全机 socket 总数,再用 nsenter -t -n ss -tn | wc -l 进单个容器查它的 ESTABLISHED 连接数,超 1 万就要警惕
- 查僵尸进程泛滥:ps aux | awk '$8 ~ /Z/ {print}',如果大量 Z 状态进程集中在某个容器 PID 域下,说明它没正确回收子进程
- 查线程爆炸:cat /proc//status | grep Threads,Java 应用线程数长期超 500,容易触发内核 task 数量限制
这类问题往往伴随 fork: Cannot allocate memory 错误,不是真缺内存,而是达到了 /proc/sys/kernel/pid_max 或 RLIMIT_NPROC 上限。










