Back
Featured image of post Docker 挂载 cgroups 失败的排查及解决方案

Docker 挂载 cgroups 失败的排查及解决方案

Docker 全挂,这是为什么呢?

起因

时间回到 2021/8,正值 Debian 11 bullseye 发布之际,我立即添加更新包的链接到 sources.list,顺便更新内核至 Linux 5.10。在 apt upgrade 成功之后,我很自然地重启了系统。然后,所有的 Docker 容器全挂了。

docker_container_empty

经过

首次尝试

docker ps -a 查看所有容器均为无法启动状态,退出代码多为 1280

尝试 docker restart 容器得到报错

cannot restart container nginx: oci runtime create failed

删除容器再次创建

recreate_error

提示找不到挂载点,ls /sys/fs/cgroup/ 后果然没有 Docker 文件夹

此时问题已经很明显了,cgroup 并没有正确挂载 Docker,打开老朋友谷歌,第一条果然是类似问题 cgroups: cannot found cgroup mount destination: unknown · Issue #219 · docker/for-linux (github.com)。好家伙,2018 年的 Issue 还挂着 open 状态。

下方建议

最终找到一个临时的 workaround:

$ sudo mkdir /sys/fs/cgroup/systemd
$ sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

手动挂载 systemd 后,问题解决了,之后我就再没关心这个问题。

再次复现

又是一次 apt upgrade,在我进行完例常的更新之后,重启系统,所有的 Docker 容器又挂了,依然是熟悉的 cgroups 报错。按着上面的临时方法再次挂载,容器又能跑了,但再次重启后依旧挂载不上。

一直手动挂载总不是什么好办法,于是先从 Docker 的 containerd 开始排查

$ sudo journalctl -xe -f -b -u containerd

发现

containerd[552]: time="2021-08-15T20:17:39.019467716+08:00" 
  level=warning msg="runtime v1 is deprecated since containerd v1.4, consider using runtime v2"

containerd 的运行时是 systemd,在 systemd 仓库中的 Issues 查找发现 Missing cgroup mounts or v2 only

* systemd now defaults to the "unified" cgroup hierarchy setup during
          build-time, i.e. -Ddefault-hierarchy=unified is now the build-time
          default. Previously, -Ddefault-hierarchy=hybrid was the default. This
          change reflects the fact that cgroupsv2 support has matured
          substantially in both systemd and in the kernel, and is clearly the
          way forward. Downstream production distributions might want to
          continue to use -Ddefault-hierarchy=hybrid (or even =legacy) for
          their builds as unfortunately the popular container managers have not
          caught up with the kernel API changes.

遂查看 cgroup 版本: mount | grep cgroup ,发现已经升级到 cgroups v2 了。

现在的问题很明确了,Docker 似乎并不支持 cgroups v2,但 apt-get upgrade 始终显示 Docker 是最新版本 v19,但官网明确写明现在已经是 v20 了。

查看 /etc/apt/sources.list.d/docker.list,发现:

deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian   stretch stable

stretch 更换为 目前系统版本 bullseyeapt-get update && apt-get upgrade 后成功升级 v20,重启后容器正常运行,问题解决。

小结

  • 如果你是从低版本 Debian 且使用 Docker -=19.x 更新,更新 Debian 后记得顺带更新 sources.list 中的系统版本代码。

  • 或者像 Missing cgroup mounts or v2 only 中提供的解决方案一样,手动关闭 unified_cgroup_hierarchy

    $ sudo sh -c 'echo "GRUB_CMDLINE_LINUX=systemd.unified_cgroup_hierarchy=false" > /etc/default/grub.d/cgroup.cfg'
    $ sudo update-grub
comments powered by Disqus