如何使用 supervisord 在 Docker 容器内启动 Docker 守护进程?

How to start Docker daemon inside a Docker container using supervisord?

我是 supervisord 和 Docker 1.5.0 在 Docker 容器中的用户(使用 debian jessie),但我不能 运行 来自 Docker容器:

$ docker run busybox bash
Unable to find image 'busybox:latest' locally
511136ea3c5a: Pull complete
df7546f9f060: Pull complete
ea13149945cb: Pull complete
4986bf8c1536: Pull complete
busybox:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Status: Downloaded newer image for busybox:latest
FATA[0006] Error response from daemon: Cannot start container df7d5f605f5c1b6750614c6a04889e34aa9b96a4de98dcfc91b8f38f9d445aad: failed to find the cgroup root

这个可能是一个bug(但人们似乎已经找到了解决方法)但我怀疑我可能需要在开始我的docker守护进程。建议的解决方法之一是安装 cgroup-lite 并在 Docker 守护程序之前启动它。但是我在 Jessie 中找不到 cgroup-lite 包。出于这个原因,我也尝试将我的容器基于 Ubuntu 图像 (14.04) 而不是(具有 cgroup-lite)但没有任何变化(我仍然得到相同的错误)。我开始怀疑这是因为 upstart 在启动容器时不是 运行ning 并且我必须从我的 supervisord 启动 cgroup-bincgroup-lite配置。我当前的 supervisord 配置如下所示:

[supervisord]
user=root
nodaemon=true

[program:docker]
user=root
autostart=true
autorestart=true
command=/usr/bin/docker -d
redirect_stderr=true
stdout_logfile=/var/log/docker/%(program_name)s.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10

[program:jenkins]
user=jenkins
autostart=true
autorestart=true
command=/usr/local/bin/jenkins.sh
redirect_stderr=true
stdout_logfile=/var/log/jenkins/%(program_name)s.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10
environment = JENKINS_HOME="/var/jenkins_home",HOME="/var/jenkins_home",USER="jenkins"

它是从 Docker CMD 开始的:

CMD sudo /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

所以我的问题本质上是,如何使用 supervisord 启动 Docker 守护程序并确保在启动 program:docker 之前加载它的所有依赖项(如果这实际上是问题)?

正如 Javier Cortejoso 指出的那样,有一个名为 DIND 的项目,其中包含一个名为 wrapdocker 的脚本,您可以使用该脚本在 Docker 中正确启动 Docker。它负责启动和安装 cgroups 等。

解决方案是简单地下载 wrapdocker 脚本并将其包含在我的 Dockerfile:

# Install the magic wrapper.
ADD ./wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/wrapdocker

然后在我的主管配置中,我将 [program:docker] 中的 command 更改为指向 wrapdocker 脚本,而不仅仅是 /usr/bin/docker -d:

[supervisord]
user=root
nodaemon=true

[program:docker]
user=root
autostart=true
autorestart=true
command=/usr/local/bin/wrapdocker
redirect_stderr=true
stdout_logfile=/var/log/docker/%(program_name)s.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10

[program:jenkins]
user=jenkins
autostart=true
autorestart=true
command=/usr/local/bin/jenkins.sh
redirect_stderr=true
stdout_logfile=/var/log/jenkins/%(program_name)s.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10
environment = JENKINS_HOME="/var/jenkins_home",HOME="/var/jenkins_home",USER="jenkins"