设备或资源繁忙 - Docker

Device or resource busy - Docker

在使用 ubuntu:latest (Xenial) 映像的新 Ubuntu 14.04 机器上执行 apt-get -y upgrade 时,出现错误:

Setting up makedev (2.3.1-93ubuntu2~ubuntu16.04.1) ...
mv: cannot move 'console-' to 'console': Device or resource busy
makedev console c 5 1 root tty 0600: failed

我在 Ubuntu 14.04 上全新安装了 docker,使用这些命令:

sudo apt-get remove docker docker-engine
sudo apt-get update
sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
wget -qO- https://get.docker.com/ | sudo sh
su - $USER # To logout and login

Docker 对于 hello-world 运行正常:

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

当我创建一个空的 docker 容器时:

docker run -it ubuntu bash

和运行以下:

apt-get update
apt-get install -y debconf-utils
echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
apt-get update
apt-get -y upgrade

错误:

Setting up makedev (2.3.1-93ubuntu2~ubuntu16.04.1) ...
mv: cannot move 'console-' to 'console': Device or resource busy
makedev console c 5 1 root tty 0600: failed

在执行最后一个 apt-get -y upgrade

时引发

完整的 docker 日志已开启:https://gist.github.com/alvations/ebe7175b984213d6f64a3c779ba3249e

Docker 容器不是完整的虚拟机。它们与主机共享内核,因此一些低级操作(例如制作设备)会失败也就不足为奇了。但是,我确实注意到,尽管出现错误消息,命令并没有失败 - 命令 returns 0。我建议容器实际上按预期工作。

尽管如此,最好的答案就是不要 运行 apt-get upgrade。您正在使用 ubuntu:latest 图像,该图像由 Docker 与新版本保持同步。因此,与其执行 apt-get upgrade 以获得新版本,不如执行 docker pull ubuntu:latest

您可以在此处 https://github.com/docker-library/repo-info/blob/master/repos/ubuntu/remote/latest.md 查看 latest 图片的最后更新时间。在撰写本文时,最后一次更新是在 6 周前,因此它会缺少一些更新。虽然我对它不是最新的感到失望,但我仍然建议不要 运行ning upgrade,因为您可能会遇到问题并将更新的责任推给自己。如果缺少重要更新,请打开一个问题。

我确实注意到 debian 图像似乎保持更新,可能是因为它被用作许多官方图像的基础图像 - 如果可能,我建议使用它.

同意其他 answers/comments 的观点,即 apt-get -y upgrade 不如拉出 newer/updated 图像好。如果需要特定包但在映像中已过时,通常安装该特定包就足够了(因为依赖项将根据需要更新)。

但是,你真的没有理由不能使用 apt-get -y upgrade 事实上,我认为这是一个错误,类似于但不是完全一样:

https://bugs.launchpad.net/ubuntu/+source/makedev/+bug/1675163

失败的部分是在 postinst 脚本中对 MAKEDEV 的第一次调用,但这已被处理并且脚本继续。最终这意味着当前安装 makedev 没有问题。 但这可能并不总是正确的 所以可能需要用 Ubuntu 提出一个错误才能检测到 docker 容器(以某种方式)。

注意: 如果您担心 makedev 当前会破坏您的 docker /dev/ 目录,或者想确保您摆脱安装 makedev 时出现的任何错误情况,我链接到的错误的修复可以用来欺骗安装后脚本而不是 运行。脚本中的支票显示:

# don't stomp on LXC users
if grep -q container=lxc /proc/1/environ
then
    echo "LXC container detected, aborting due to LXC managed /dev."
    exit 0
fi

因此,如果您要添加名称以容器结尾且值为 lxc 的环境变量,则检查将被触发,并且不会安装新设备

docker run -ti -e "ImNotAnLXCcontainer=lxc" ubuntu

这将导致脚本退出,不会创建一大堆 /dev/ 条目,并输出消息:

Setting up makedev (2.3.1-93ubuntu2~ubuntu16.04.1) ...
LXC container detected, aborting due to LXC managed /dev.