在Docker(容器的系统中)中运行Docker
某些场景下我们需要在Docker中运行Docker,例如在Docker中部署Jenkins,在Jenkins的任务中对项目进行打包测试发布,而项目也是基于Docker的。
首先明确我们需要的是什么,Docker其实包含服务器(Docker Engine或者叫Docker Daemon)和客户端(Docker CLI),我们需要的是在容器内能够使用Docker客户端访问到Docker服务器,而Docker服务器其实不必运行在容器内,可以运行在宿主机上。
docker的客户端和服务器有一个参数决定了两者的通讯方式,默认情况下使用/var/run/docker.sock
进行通讯,这个文件表示一个Unix Socket,Unix Socket是一种类似我们熟知的TCP/UDP的进程间通讯方式,我们也可以通过增加-H tcp://0.0.0.0:2376
参数在启动时修改默认的通讯方式为TCP2376端口通讯。
1 | -H, --host=[unix:///var/run/docker.sock]: tcp://[host]:[port][path] |
方法一
我们可以通过在创建容器时指定-v /var/run/docker.sock:/var/run/docker.sock
把宿主机的Socket映射到容器内,容器内的Docket客户端就相当于直接连到了宿主机的Docker Engine。
这样容器内和容器外使用的是同一个engine可以相互操作对方创建的镜像有一定风险。
方法二
那么还有一个方法就是使用别人制作的特殊系统镜像,镜像名称通常包含dind
字样,表示支持Docker in Docker,例如gitlab/dind
,这种镜像启动时需要--privileged
参数,启动后容器内部预装了docker环境,容器内外的engine是独立不互通的,这种方法的问题是系统的版本是固定的,取决于dind镜像提供的什么版本。
方法三
替换docker运行时为sysbox
1 | docker run --runtime=sysbox-runc --name sysbox-dind -d docker:dind |
需要安装sysbox,参考sysbox/install-package.md at master · nestybox/sysbox (github.com)
因为安装前需要停止并删除所有容器,我并没有尝试过。