我在 Docker 容器中运行 Jenkins。我想知道 Jenkins 容器是否也可以作为 Docker 主机?我正在考虑的是从 Jenkins 内部为每个集成测试构建启动一个新的 docker 容器(启动数据库、消息代理等)。因此,在集成测试完成后应该关闭容器。是否有理由避免以这种方式从另一个 docker 容器中运行 docker 容器?
4 回答
如果可能的话,应该尽量避免在 Docker(又名dind )中运行 Docker。(下面提供了源代码。)相反,您希望为您的主容器设置一种方式来生成同级容器并与之通信。
Jérôme Petazzoni——使 Docker 可以在 Docker 容器内运行的特性的作者——实际上写了一篇博文说不要这样做。他描述的用例与 OP 的 CI Docker 容器的确切用例相匹配,该容器需要在其他 Docker 容器中运行作业。
Petazzoni 列出了 dind 麻烦的两个原因:
- 它不能很好地与 Linux 安全模块 (LSM) 配合使用。
- 它会在文件系统中造成不匹配,从而给在父容器中创建的容器带来问题。
从那篇博客文章中,他描述了以下替代方案,
-v
[最简单的方法是通过将 Docker 套接字与标志绑定挂载,将 Docker 套接字公开给您的 CI 容器。简而言之,当您启动 CI 容器(Jenkins 或其他)时,不要使用 Docker-in-Docker 来破解某些东西,而是从以下内容开始:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
现在这个容器将可以访问 Docker 套接字,因此能够启动容器。除了启动“子”容器之外,它将启动“兄弟”容器。
我之前回答了一个类似的问题,关于如何在 Docker 中运行 Docker 容器。
在 docker 中运行 docker 绝对是可能的。最主要的是你拥有额外权限
run
的外部容器(以 开头),然后在该容器中安装 docker。--privileged=true
查看此博客文章以获取更多信息:Docker-in-Docker。
此条目中描述了一个潜在的用例。该博客描述了如何在 Jenkins docker 容器中构建 docker 容器。
但是,Docker 里面的 Docker 并不是解决这类问题的推荐方法。相反,推荐的方法是创建本文所述的“兄弟”容器
因此,在 Docker 中运行 Docker 被许多人认为是解决此类问题的一种很好的解决方案。现在,趋势是改用“兄弟”容器。有关更多信息,请参阅此页面上@predmijat 的答案。
运行 Docker-in-Docker (DinD) 是可以的,事实上 Docker(公司)为此提供了官方的 DinD 映像。
但是需要注意的是,它需要一个特权容器,这取决于您的安全需求,这可能不是一个可行的选择。
使用同级容器(也称为 Docker-out-of-Docker 或 DooD)运行 Docker 的替代解决方案不需要特权容器,但存在一些缺点,这些缺点源于您从以下上下文中启动容器这一事实不同于它在其中运行的那个(即,您从容器内启动容器,但它在主机级别运行,而不是在容器内)。
我在这里写了一篇描述 DinD 与 DooD 的优缺点的博客。
话虽如此,Nestybox(我刚刚创立的一家初创公司)正在研究一种安全运行真正 Docker-in-Docker 的解决方案(不使用特权容器)。您可以在www.nestybox.com上查看。
是的,我们可以在 docker 中运行 docker,我们需要/var/run/docker.sock
使用-v /var/run/docker.sock:/var/run/docker.sock
. 有时,您可以为其编写的 docker daemon socket 可能会出现权限问题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 ...