从docker里面运行docker可以吗?

Is it ok to run docker from inside docker?

我在 Docker 容器中 运行 Jenkins。我想知道 Jenkins 容器是否也可以作为 Docker 主机?我正在考虑的是从 Jenkins 内部为每个集成测试构建启动一个新的 docker 容器(以启动数据库、消息代理等)。因此,应该在集成测试完成后关闭容器。是否有理由以这种方式从另一个 docker 容器中避免 运行 docker 容器?

我之前在 how to run a Docker container inside Docker 上回答过类似的问题。

To run docker inside docker is definitely possible. The main thing is that you run the outer container with extra privileges (starting with --privileged=true) and then install docker in that container.

Check this blog post for more info: Docker-in-Docker.

One potential use case for this is described in this entry. The blog describes how to build docker containers within a Jenkins docker container.

However, Docker inside Docker it is not the recommended approach to solve this type of problems. Instead, the recommended approach is to create "sibling" containers as described in this post

因此,Docker 中的 运行 Docker 被许多人认为是解决此类问题的好方法。现在,趋势是改用“兄弟”容器。有关详细信息,请参阅 the answer by @predmijat on this page

运行 Docker inside Docker (a.k.a. dind),虽然可能,但应该避免,如果一切皆有可能。 (下面提供了来源。)相反,您想为主容器设置一种方式来生成 sibling 容器并与之通信。

Jérôme Petazzoni — the author of the feature that made it possible for Docker to run inside a Docker container — actually wrote a blog post saying not to do it。他描述的用例与 OP 的 CI Docker 容器的确切用例相匹配,该容器需要 运行 其他 Docker 容器中的作业。

Petazzoni 列举了 dind 麻烦的两个原因:

  1. 它不能很好地与 Linux 安全模块 (LSM) 配合。
  2. 它在文件系统中造成不匹配,从而给在父容器内创建的容器带来问题。

从该博客 post,他描述了以下替代方案,

[The] simplest way is to just expose the Docker socket to your CI container, by bind-mounting it with the -v flag.

Simply put, when you start your CI container (Jenkins or other), instead of hacking something together with Docker-in-Docker, start it with:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

Now this container will have access to the Docker socket, and will therefore be able to start containers. Except that instead of starting "child" containers, it will start "sibling" containers.

运行 Docker-in-Docker (DinD) 没关系,事实上 Docker(公司)对此有一个 official DinD image .

但需要注意的是,它需要一个特权容器,根据您的安全需求,这可能不是一个可行的替代方案。

运行ning Docker 使用兄弟容器(又名 Docker-out-of-Docker 或 DooD)的替代解决方案不需要特权容器,但有一些缺点源于这样一个事实,即您从与 运行ning 所在的上下文不同的上下文中启动容器(即,您从容器中启动容器,但它是 运行在主机级别,而不是在容器内)。

我写了一篇博客,描述 pros/cons DinD 与 DooD here

话虽如此,Nestybox(我刚刚成立的一家初创公司)正在研究一种 运行 正确 Docker-in-Docker 安全的解决方案(不使用特权容器) .您可以在 www.nestybox.com 查看。

是的,我们可以在 docker 中 运行 docker,我们需要连接 docker 守护程序侦听的 unix 套接字 /var/run/docker.sock默认情况下,使用 -v /var/run/docker.sock:/var/run/docker.sock 作为父级 docker 的音量。 有时,docker 守护程序套接字可能会出现权限问题,您可以为其编写 sudo chmod 757 /var/run/docker.sock.

而且它还需要在特权模式下 运行 docker,所以命令是:

sudo chmod 757 /var/run/docker.sock

docker run --privileged=true -v /var/run/docker.sock:/var/run/docker.sock -it ...