Docker daemon被OOM Killer终止是因宿主机内存枯竭,需通过systemctl和dmesg验证,立即执行oom_score_adj=-1000降低其优先级,并配置cgroup v2内存限额、严格限制业务容器内存及部署水位监控来根治。

这个问题本质不是“Docker Daemon 被 OOMScore 杀”,而是 containerd 或 dockerd 进程因宿主机整体内存严重不足,被内核 OOM Killer 选中终止,进而导致所有容器瞬间失联、服务大面积离线。OOMScore(即 /proc/[pid]/oom_score_adj)只是内核选择杀谁的参考指标之一,真正触发的是系统级内存枯竭。
确认是不是 daemon 层面被杀
别凭现象猜测,先验证:
- 执行
systemctl status docker和systemctl status containerd,看是否处于inactive (dead) - 查内核日志:
sudo dmesg -T | grep -i "killed process" | grep -E "(dockerd|containerd)"—— 若出现类似Killed process 12345 (dockerd) ...,就坐实了 - 检查 systemd 日志:
sudo journalctl -u docker --since "1 hour ago" | grep -i -E "(oom|killed|segfault|out of memory)"
立即止血:防止二次崩溃
重启 Docker 服务只是临时恢复,若不干预,几小时内可能重演。关键动作是:
-
立刻释放宿主机内存:杀掉非核心进程、清空 pagecache(
sync; echo 3 > /proc/sys/vm/drop_caches)、停止非必要容器 -
禁止 OOM Killer 对 dockerd/containerd 下手:运行以下命令降低其被杀优先级(值越小越安全,-1000 表示永不杀):
echo -1000 | sudo tee /proc/$(pgrep dockerd)/oom_score_adjecho -1000 | sudo tee /proc/$(pgrep containerd)/oom_score_adj -
持久化该设置:在
/etc/systemd/system/docker.service.d/override.conf中添加:[Service]OOMScoreAdjust=-1000
根治方案:隔离 + 预控 + 监控
单纯调 oom_score_adj 是权宜之计。必须从资源边界和调度逻辑上做硬隔离:
-
为 dockerd 和 containerd 单独划出 cgroup v2 内存限额(推荐 Docker 20.10+):
编辑/etc/docker/daemon.json,启用 cgroup v2 并配置资源预留:{"features": {"cgroupv2": true}, "default-ulimits": {"memlock": {"Name": "memlock", "Hard": -1, "Soft": -1}}}
再通过 systemd 限制 dockerd 自身内存上限:sudo systemctl set-property docker.service MemoryMax=2G -
严格限制业务容器内存,避免“池塘效应”:每个
docker run必须带-m,每个docker-compose.yml的 service 必须配deploy.resources.limits.memory。没限制的容器就是定时炸弹。 -
部署轻量级内存水位监控:用
docker stats --no-stream或curl http://localhost:2375/metrics(Docker 27+ 原生暴露)采集container_memory_usage_bytes和memory_events_total{event="oom"},当宿主机 free 内存低于 10% 时自动告警并驱逐低优先级容器。
补充提醒:别踩这些坑
很多“大面积离线”其实是连锁反应,而非单纯 daemon 被杀:
- 容器未配置
--restart unless-stopped,daemon 重启后它们不会自启 - 使用
bridge网络且未清理残留 iptables 规则,docker restart 后网络不通,误判为容器挂了 - 镜像层过大或磁盘满(
df -h /var/lib/docker),导致新容器拉取失败、旧容器无法 checkpoint


















