容器退出码 137 排查实录:不是 OOM,是宿主机偷偷重启(SIGKILL 信号分析)

背景

一台生产服务器上的容器服务最近隔三差五退出,退出码清一色 137。团队第一反应是内存溢出(OOM),准备扩内存。

我没急着动手,先把退出码拆开看了看。

退出码 137 是什么

Linux 的退出码规范:进程退出码大于 128 时,实际含义是 128 + 信号编号

137 = 128 + 9

9 号信号是 SIGKILL,即进程被强制杀死。

能对容器发 SIGKILL 的,主要有三类:

  1. 内核 OOM killer(内存不足时主动杀进程)
  2. docker stop / systemctl stop(人为或脚本停止)
  3. 宿主机重启(关机流程向所有进程广播)

所以"退出 137"和"内存溢出"之间,还隔着两个完全不同的可能。直接按 OOM 扩内存,方向可能是错的。

排查过程

1. 排除 OOM

查内核日志:

dmesg | grep -iE "out of memory|killed process"

干净,没有任何 OOM kill 记录。OOM 假设存疑。

2. 对齐时间线

查宿主机重启记录,和容器退出时间做交叉对比:

last reboot
uptime
journalctl --list-boots

结果:容器每次退出,时间都精确落在宿主机某次重启的时刻。

3. 定位重启来源

宿主机重启分两类:软重启(reboot/shutdown,日志里有正常关机流程)和硬重启(断电/硬件复位,日志突然中断)。查系统日志确认是硬重启后,进一步翻了硬件层的 IPMI SEL 日志定位到硬件告警触发。

根因

宿主机硬件异常触发重启,重启过程广播 SIGKILL 杀掉所有容器。和容器内存没有关系——如果当时扩了内存,问题照旧,钱白花。

经验总结

  1. 退出码 ≠ 根因。看到 137 先想"谁发的 SIGKILL",而不是"内存不够"。
  2. 时间线交叉验证是第一排查手段。容器退出时间 ↔ 宿主机重启时间 ↔ 硬件事件日志,三线一对,根因往往自己冒出来。
  3. 附一个退出码速查,方便以后对照:
退出码 计算 信号 优先排查方向
137 128+9 SIGKILL dmesg 有无 OOM;last reboot 对齐
143 128+15 SIGTERM 谁发的 stop(docker stop/脚本/systemd)
139 128+11 SIGSEGV 应用自身段错误,查 coredump
1~127 应用自己退出,看应用日志

关于我

Linux 运维工程师,主做服务器部署、线上排障、安全加固、自动化运维。

平时接服务器代运维和故障救火的活,这类"表面一个原因、实际另一个原因"的排障见得多。有类似问题欢迎留言或私信,先描述现象,我判断能不能帮上忙,搞不定不收费。

posted @ 2026-08-31 15:47  王纸  阅读(86)  评论(0)    收藏  举报