docker outside of docker & jenkins

在敏捷开发中,一个CI系统是必不可少的,jenkins是当前最流行的CI系统,它通常运行在docker容器中,然后对项目进行编译 测试 打包,然后操作docker构建镜像,正常模式下,container 中的 jenkins是不能操作docker的。 如果想让jenkins能构建镜像并启动容器这里有三种方式。

  • docker in docker

这种方式是在容器中安装一个完整docker环境,是真正意义上的docker in docker,通过这种方式也可以实现 docker in docker in docker…..

  • docker outside of docker

这种方式与dind的区别在于,后者包含一个完整的docker环境,前者仅仅是使用宿主机的Docker,对于我们这种需求相对而言是比较适合并且简单的

  • Docker API

使用Docker的rest api操作Docker容器。

example:

Run a container in the background

$ curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" \
  -d '{"Image": "bfirsh/reticulate-splines"}' \
  -X POST http:/v1.24/containers/create
{"Id":"1c6594faf5","Warnings":null}

$ curl --unix-socket /var/run/docker.sock -X POST http:/v1.24/containers/1c6594faf5/start

这种方式通常会在自己的可视化监控docker系统中使用。

docker outside of docker

这种方式就比较适合我们,我们只需要将Docker套接字挂载到jenkins容器中就可以。用下面的命令启动一个容器

docker run --name jenkins  -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -p 8080:8080 -d -u root jenkins:2.60.2

然后我们进入容器中运行docker 命令,可能会出现下面的错误

docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory

出现这种情况我们只需要将宿主机的 libltdl.so.7 一并挂载到容器即可,这时候在运行命令,发现可以在容器中操作宿主机的docker了

优点

  • 不需要 privileged 模式

  • 更加简单,jenkins会使用宿主机的Docker

  • 能够从宿主机重新使用image cache

  • 对宿主机的Docker daemon 进行的任何设置都会应用到容器中的Docker

  • 更容易设置,只需要将主机的Docker可执行文件和守护程序套接字映射到容器上即可

  • 宿主机和容器会永远使用同一个版本的 Docker