容器因oom被杀需三步确认:先查docker ps -a中exited (137)状态,再验docker inspect中"state.oomkilled": true,最后用dmesg -t | grep "killed process"坐实内核oom killer介入。

确认容器是否真因 OOM 被杀
先看最直接的证据:运行 docker ps -a,找到状态为 Exited (137) 的容器;再执行 docker inspect
定位对应 cgroup 内存限制配置
OOM 的起点永远是 cgroup 的硬性边界。用 crictl inspect --output yaml /sys/fs/cgroup/kubepods/burstable/pod-xxx/.../memory.max: 104857600,即表示该容器内存上限为 100MiB。这个值就是触发链的“红线”。
捕获内核级实时事件轨迹
要还原完整触发链,不能只看结果,得录下内核当时在做什么。推荐用 perf trace 绑定容器主进程 PID:
- 先通过 ps auxf | grep
或 cat /proc/ /cgroup 找到主进程 PID - 运行:perf trace -e 'mm:mem_cgroup_charge,mm:oom_kill_event,syscalls:sys_enter_mmap' -C
-o perf-oom.trace - 复现内存增长场景(如触发服务请求、加载数据),直到容器被杀
- 用 perf script -F comm,pid,tid,time,event | grep oom_kill_event 查看 OOM 事件发生时刻,并向前追溯 mem_cgroup_charge 活跃峰值——两者时间差能判断是缓慢泄漏还是瞬时爆冲
理解内核三阶段递进式响应逻辑
现代 Linux(cgroup v2)对内存超限不是“一刀切”,而是分三级响应:
- memory.low 被突破:仅触发内核优先回收该 cgroup 的匿名页,不影响运行(对应 Docker --memory-reservation)
- memory.high 被持续超过:内核开始主动压制,频繁调用 mem_cgroup_handle_over_high 进行轻量回收,容器可能变慢但不死
- memory.max 被突破且无法回收:进入 OOM 判定路径,最终调用 mem_cgroup_out_of_memory,选中并杀死进程——这就是你看到的 OOMKilled
这三个阈值共同构成一条压力传导链,而非单一开关。忽略 high 和 low 的设置,等于放弃了缓冲带,让容器直面 max 的死亡线。











