判定思路
容器被内核因内存超限杀掉时,Docker 会把 State.OOMKilled 置为 true,退出码通常是 137。反过来并不成立:137 也可能来自停止超时后的强制杀,或其他直接收到该信号的场景。因此判定要组合多条证据:inspect 的字段、docker events 的 oom 事件、宿主 dmesg 里的记录,以及容器当时的内存限额。
基本信息
| 判定关键字 | docker inspect 的 State.OOMKilled |
|---|---|
| 联动证据 | ExitCode 137 与 docker events 的 oom 事件 |
| 宿主证据 | dmesg 中的 killed process 与内存统计 |
| 限额字段 | HostConfig.Memory,为 0 表示未设置上限 |
| 适用平台 | Linux 宿主上的 Docker Engine |
典型使用场景
- 服务周期性退出且日志没有异常堆栈,怀疑被内核杀掉
- 调整内存限额后验证问题是否消失
- 排查退出码 137 到底是内存超限还是停止超时
- 结合内存曲线定位是谁在持续涨内存
- 把 OOM 事件接入告警,缩短发现时间
取证命令
取证命令
docker inspect -f 'oom={{.State.OOMKilled}} exit={{.State.ExitCode}} mem={{.HostConfig.Memory}}' web
docker events --since 2h --filter event=oom # 事件流里的 oom 记录
dmesg -T | grep -i -E 'killed process|oom' | tail -10 # 宿主内核日志
docker stats --no-stream web # 当前内存占用与限额对照证据逐项读法
| 字段 / 命令 | 含义 | 判读 |
|---|---|---|
| State.OOMKilled | 是否因内存超限被杀 | true 是直接证据 |
| State.ExitCode | 容器退出码 | 137 常见但不唯一,需交叉验证 |
| HostConfig.Memory | 内存限额 | 0 表示没有设置上限 |
| events 中的 oom | 事件流记录 | 时间点可与应用日志对齐 |
| dmesg 输出 | 内核层面记录 | 包含被杀进程与内存统计 |
容器 OOM 是结果不是原因:要结合内存曲线、容器内进程与请求量变化,找出是谁在持续涨内存。
没有设置内存上限时,容器可能被宿主级内存压力波及,此时容器侧字段未必置位,需要结合 dmesg 与宿主日志判断。
限额单位容易写错:--memory=512m 表示 512MiB,写成 512 会被当成很小的字节量,与预期相差极大。