必须同时设置--memory和--memory-swap(如均为2g)以禁用swap并实现容器级oom快速止损,避免宿主机oom killer误杀关键进程;辅以--oom-score-adj调整优先级、--shm-size扩容/dev/shm、--memory-reservation设置软限制及docker stats监控,形成内存管控闭环。
核心是让容器在自己限额内运行,而不是等它撑爆宿主机内存才被系统级 oom killer 清理。宿主机 oom killer 启动,说明容器早该有硬限制却没设——这是配置缺失,不是应用问题。
必须设置硬内存限制
不设 --memory,等于把内存控制权完全交给应用,也等于默认允许它吃光宿主机所有内存。一旦触发宿主机 OOM Killer,整个系统都可能卡死或误杀其他关键进程。
- --memory=2g:明确划出物理内存上限,超限即进入容器级 OOM 判定(由内核对这个 cgroup 执行)
- --memory-swap=2g:禁用 swap,避免延迟掩盖真实压力;设为同值即彻底关闭交换
- 禁止使用 --memory=0 或完全不设,这在生产环境等同于埋雷
区分服务重要性,降低核心进程被杀概率
资源紧张时,不能靠“运气”活下来。通过 --oom-score-adj 主动影响内核评分逻辑,让数据库、API 网关这类服务更难被挑中。
- --oom-score-adj=-500:大幅降低被终止倾向,适用于 Redis、PostgreSQL、Jupyter 等核心组件
- --oom-score-adj=300:提高回收优先级,适合批处理、日志归档等非关键任务
- 验证是否生效:docker exec 容器名 cat /proc/1/oom_score_adj,应返回设定值
检查并扩容 /dev/shm,很多“OOM”其实是它撑爆的
Chrome Headless、PyTorch 推理、PostgreSQL 共享缓冲区都重度依赖 /dev/shm,而 Docker 默认只给 64MB。它占满会直接触发 OOM,但 docker stats 不显示这部分内存,极易误判。
- 进容器执行 df -h /dev/shm,若使用率 >90%,大概率就是真凶
- 启动时加 --shm-size=1g,图像处理、无头浏览器等场景建议直接设 1GB
- Kubernetes 中对应配置为 emptyDir: { medium: Memory, sizeLimit: 1Gi }
配合软限制与实时监控,提前干预而非被动救火
硬限制防崩溃,软限制助调度,监控提供决策依据。三者结合才能形成闭环。
- --memory-reservation=1.5g:提示运行时在内存紧张时主动压缩超出该值的部分,降低硬限触达概率
- 用 docker stats --no-stream 容器名 持续观察 MEM USAGE / LIMIT,接近 95% 就该预警
- 查退出码:docker inspect 容器名 --format='{{.State.ExitCode}}',返回 137 即确认是 OOM 被杀











