DinD模式下通过容器构建镜像-方案
文章目录
持续集成时,构建镜像后,通常会产生一些临时镜像
很不docker,一点也不绿色
使用DinD的方案可以解决该问题
1. 手动构建的流程
- 代码提交到git仓库中
- 在宿主机git pull最新代码
- 通过docker build 使用Dockerfile进行多阶段构建
- 编译(*.java -> .class -> jar包, *.go -> 可执行文件)
- 使用上一步生成的文件构建镜像
- 将构建好的镜像推送到镜像私服
- 在服务器上将容器替换成最新镜像运行
在采用多阶段构建时,会产生中间镜像,一个tag为none的镜像。
而N个构建任务则导致N个tag为none的镜像 另外from的镜像通常也占磁盘空间
使用docker image
可看到这些无用的镜像
容器的一个特色就是能绿色的运行软件
既然用了docker 自然希望构建的步骤也在容器中执行
2. 容器内构建镜像-两种方式
docker是一个c/s架构的程序
- docker-daemon 类似于mysql-server
- docker-client 类似于mysql-client
DinD (Docker in Docker)
在该容器内的cmd-docker类似普通的容器服务
运行 docker images 显示空 就好像一个全新的系统
docker run --privileged --name some-docker -d docker:stable-dind
DooD (Docker-outside-of-Docker)
在该容器内的cmd(docker ...)调用的是宿主机的docker-daemon
如运行 docker images 显示的就是宿主机的镜像列表
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
采用DooD的方案较简单
缺点:
由于docker build
实际上还是连的宿主机的 docker-daemon
宿主机最终还是会有这些tag为none的镜像 并没有达到绿色的目的
此时考虑下DinD则比较绿色
使用DinD
缺点:
由于每次都是启动一个新的容器去构建镜像 , 新的容器意味着其环境下没有任何的镜像
如果有N个任务都是from amazoncorretto:8u212
这一镜像 则每次任务都是重新拉取镜像
这种情况下的确绿色了,但重复下载镜像很浪费时间
3. 更好的方案
单独创建一个容器运行 docker-deamon 开放2375端口 所有的构建任务执行docker命令(docker ps, docker pull…)时都会被发送到此容器内执行 这样既可以绿色运行,也能使用镜像的缓存
|
|
每次执行构建任务时,依然是在一个新的容器(taskN)中进行构建镜像
只不过容器task-N中运行的docker build
命令,会被发送到docker-deamon容器中执行
3.1. 要点
- 给docker-deamon配置镜像加速器
- 给docker-deamon开放2375端口 以提供外部访问服务
- 执行构建任务的容器(task) 的docker需要配置
export DOCKER_HOST="tcp://192.168.6.7:2375"
以让其连接docker-deamon容器 - 如果docker-deamon部署在k8s上, 还可考虑设置多个pod 应对并发的构建任务
文章作者 duansheli
上次更新 2019-12-25 (325c7b3)