我在一个Docker容器里调查詹金斯。我想知道Jenkins容器也可以作为Docker宿主吗?我正在考虑的是从Jenkins内部为每个集成测试构建启动一个新的docker容器(以启动数据库、消息代理等)。因此,应该在集成测试完成后关闭容器。是否有理由避免以这种方式在另一个docker容器中运行docker容器?
我之前在如何在Docker内部运行Docker容器上回答过一个类似的问题。
在docker内部运行docker是绝对可能的。主要的事情是你用额外的特权 run外部容器(从--privileged=true开始),然后在该容器中安装docker。 查看这篇博客文章以获取更多信息:Docker-in-Docker。 这个条目中描述了一个潜在的用例。这篇博客描述了如何在Jenkins docker容器中构建docker容器。 然而,Docker内部的Docker并不是解决这类问题的推荐方法。相反,推荐的方法是创建“兄弟”;容器为本帖所述
在docker内部运行docker是绝对可能的。主要的事情是你用额外的特权 run外部容器(从--privileged=true开始),然后在该容器中安装docker。
run
--privileged=true
查看这篇博客文章以获取更多信息:Docker-in-Docker。
这个条目中描述了一个潜在的用例。这篇博客描述了如何在Jenkins docker容器中构建docker容器。
然而,Docker内部的Docker并不是解决这类问题的推荐方法。相反,推荐的方法是创建“兄弟”;容器为本帖所述
因此,在Docker内部运行Docker被许多人认为是解决这类问题的一种很好的解决方案。现在的流行趋势是用“sibling”;容器代替。更多信息请参见来自本页@predmijat的答案。
在Docker (a.k.a. dind)内部运行Docker,如果可能的话,应该尽量避免。(资料来源如下。)相反,你想要为你的主容器设置一种生成兄弟姐妹容器并与之通信的方式。
杰罗姆Petazzoni——这个特性的作者使得Docker可以在Docker容器中运行——实际上写了一篇博文说不要这么做。他描述的用例与OP中需要在其他Docker容器中运行作业的CI Docker容器的确切用例相匹配。
Petazzoni列出了dind麻烦的两个原因:
在那篇博文中,他描述了以下替代方案,
最简单的方法是将Docker套接字暴露给CI容器,通过-v标志绑定挂载它。 简单地说,当你启动你的CI容器(Jenkins或其他)时,不要用Docker-in-Docker来破解一些东西,而是用: docker run -v /var/run/docker.sock:/var/run/docker.sock ... 现在这个容器可以访问Docker套接字,因此可以启动容器。只是它将启动“兄弟”容器,而不是启动“子”容器。
最简单的方法是将Docker套接字暴露给CI容器,通过-v标志绑定挂载它。
-v
简单地说,当你启动你的CI容器(Jenkins或其他)时,不要用Docker-in-Docker来破解一些东西,而是用:
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
现在这个容器可以访问Docker套接字,因此可以启动容器。只是它将启动“兄弟”容器,而不是启动“子”容器。
运行Docker-in-Docker (DinD)是可以的,事实上Docker(该公司)对此有DinD官方图片。
但需要注意的是,它需要一个特权容器,这取决于您的安全需求,可能不是一个可行的替代方案。
使用兄弟容器运行Docker的替代解决方案(又名Docker-out- Docker或dod)不需要特权容器,但有一些缺点,因为你从一个不同于它运行的上下文中启动容器(即,你从容器内部启动容器,但它运行在主机级别,而不是容器内部)。
我写了一篇博客,描述了DinD和dod 在这里的利弊。
说到这里,Nestybox(我刚刚创立的一家初创公司)正在研究一种解决方案,能够安全地运行真正的docker中docker(不使用特权容器)。你可以在www.nestybox.com上查看它。
是的,我们可以在docker中运行docker,我们需要使用-v /var/run/docker.sock:/var/run/docker.sock将unix套接字/var/run/docker.sock附加到父docker上,docker守护进程默认在该套接字上监听卷。 有时候,docker守护进程套接字可能会出现权限问题,你可以为其编写sudo chmod 757 /var/run/docker.sock.
-v /var/run/docker.sock:/var/run/docker.sock
/var/run/docker.sock
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 ...
在过去的几天里,我也像你一样在容器中运行容器。浪费了很多时间。到目前为止,大多数人建议我做一些事情,比如使用docker的DIND镜像,这并不适用于我的情况,因为我需要主容器是Ubuntu OS,或者运行一些特权命令并将守护socket映射到容器中。(这对我来说从来都不管用)
我找到的解决方案是在我的Ubuntu 20.04系统上使用Nestybox,效果最好。它的执行也非常简单,只要你的本地系统是ubuntu(他们最支持ubuntu),因为容器运行时是专门为这样的应用程序设计的。它也有最灵活的选择。截至2022年11月,Nestybox的免费版可能是最好的方法。强烈建议您尝试它,而不需要其他人建议的所有繁琐的设置。他们有许多预先构建的解决方案,可以通过简单的命令行解决这些特定需求。
执行sysbox的一个简单的常用命令:
dock run --runtime=sysbox-runc -it any_image
快速链接到如何部署简单的sysbox运行时环境容器的说明:https://github.com/nestybox/sysbox/blob/master/docs/quickstart/README.md