问题现象
在Docker 19及更高版本中,当系统内存使用过多导致 containerd 发生 OOM(Out of Memory)时,可能会导致 Docker 停止运行且不会自动重启。这个问题可以通过执行命令pkill -9 containerd;systemctl is-active dockerd containerd
来复现,此时,dockerd 会被 systemd 停止。
最严重的影响可能是普通节点在 OOM 后变为 NotReady 状态、独立集群的主节点发生问题后可能会引发雪崩效应。
问题分析
Docker 社区最初将 docker 和 containerd 的关系设定为 dockerd.service BindsTo containerd.service,这会导致当 containerd 被kill -9
命令强制终止时,systemd 会主动停止 dockerd,即使在 Docker 中设置了 Restart,也无法恢复。更多信息请参见:
增量修复
增量节点已于2023年4月20日进行了修复。
存量修复
对于存量节点,您可以通过以下脚本进行修复:
#!/bin/bash
insert_if_absent() {
line="${1}"
lead="$(echo "${line}" | cut -f1 -d=)""="
if ! grep "^${lead}" /usr/lib/systemd/system/containerd.service > /dev/null 2>&1; then
sed -i "/^ExecStart=/a${line}" /usr/lib/systemd/system/containerd.service
fi
}
insert_if_absent OOMScoreAdjust=-999
insert_if_absent RestartSec=5
insert_if_absent Restart=always
sed -i '/BindsTo/d' /usr/lib/systemd/system/dockerd.service
sed -i 's/^Wants.*/Wants\\=network-online.target containerd.service/' /usr/lib/systemd/system/dockerd.service
systemctl daemon-reload
您可以通过执行下述命令,验证是否成功修复了 containerd 被强制终止后 Docker 无法重启的问题。另外,您也可以通过执行docker run
命令进行进一步验证。
pkill -9 containerd;systemctl is-active dockerd containerd
本页内容是否解决了您的问题?