Docker 监控 OOM 事件

Docker 监控 OOM 事件

什么是容器 OOM

当容器内进程尝试分配超过 cgroup 内存限制的内存时,Linux OOM Killer 会介入,杀掉容器内的进程。这是容器最常见的异常退出原因之一。

监控 OOM 的方法

方法一:通过 dmesg 查看

dmesg | grep -i "oom"
dmesg | grep -i "killed process"

输出示例:

[12345.678901] Memory cgroup out of memory: Killed process 1234 (java) total-vm:2048576kB, anon-rss:1048576kB, file-rss:0kB, shmem-rss:0kB

方法二:查看容器退出状态码

docker inspect  --format '{{.State.ExitCode}}'
# OOM 退出码为 137(SIGKILL)
docker inspect  --format '{{.State.OOMKilled}}'
# true 表示因 OOM 被杀死

方法三:使用 /sys/fs/cgroup

cat /sys/fs/cgroup/memory/docker//memory.oom_control
# oom_kill_disable 0
# under_oom 0
# oom_kill 1

方法四:Prometheus 告警

groups:
  - name: docker_oom
    rules:
      - alert: ContainerOOMKilled
        expr: (time() - container_last_seen{state="exited"}) < 60
        annotations:
          summary: "容器因 OOM 被杀死"

Logging Driver 采集

配置 Docker daemon 使用 json-file 日志驱动,并结合 Loki 或 ELK 采集:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

最佳实践

  1. 设置合理的内存限制:不要设置过高也不宜过低,建议通过压测确定 baseline
  2. 预留 swap 空间--memory-swap 提供一定的 burst 能力
  3. 监控 trend:不仅看是否 OOM,还要关注内存使用趋势,提前扩容
  4. JVM 容器特别处理:Java 应用一定要设置 -XX:+UseContainerSupport-XX:MaxRAMPercentage

面试要点

  • OOM 退出码是 137(128+9,SIGKILL)
  • docker inspect 直接提供 OOMKilled 字段
  • cgroup v1 和 v2 的 OOM 检测路径不同
  • 区分容器 OOM 和宿主机 OOM

OOM 是容器化最常见的故障之一,面试官常会延伸问:你的应用 OOM 了怎么排查?怎么设计内存限制?

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容