通过Jenkins容器构建镜像(1)
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
Jenkins是一个很受欢迎的开源的CI服务器。本篇我们将构建一个Jenkins容器,并在容器中安装docker及docker-compose,以便于通过此容器构建docker镜像。在容器内使用docker,可以通过两种方法实现:一种是将docker socket挂载到容器内部;另一种是使用Docker-in-Docker(DinD)。
我们将以官方的Jenkins镜像为基础,将Docker socket挂载到容器内部,并且在容器内部安装docker及docker-compose,从而可以在Jenkins容器内部构建镜像。本篇不使用DinD的方式。这两种方式的对比可以通过下图说明:
Docker-in-Docker(DinD)是在一个Docker容器内部再运行一个Docker。它需要一些配置。请参考https://github.com/jpetazzo/dind。
下面就来通过Dockerfile构建Jenkins容器。基本的思路就是选用官方的Jenkins基础镜像,然后安装Docker可执行程序以及docker-compose可执行程序。由于想在容器内部挂载宿主机上的docker socket,就需要容器内部的Jenkins用户有足够的访问权限,这是通过将jenkins用户加入无密码的sudo权限实现的。这里没有将其加入到Docker用户组,因为这可能会带来潜在的可移植性问题。这样,所有在容器内部执行的关于Docker的命令就需要通过sudo运行。Dockerfile如下:
|
|
上述文件中的第4行切换到了root用户,以便于后面安装docker和docker-compose。第5-19行主要就是安装docker和docker-compose的命令。第15行的作用是将jenkins用户加入sudo免密码权限,从而可以访问到宿主机的docker socket。最后几行命令的作用是切换回jenkins用户并且安装一些jenkins的插件。
下面通过阿里云的镜像仓库控制台来构建此镜像。由于镜像构建过程中需要从互联网下载各种软件包,国内的网络下载一些软件时速度过慢,而阿里云提供的“海外机器构建”选项可以大大提高软件的下载速度,从而节省大量时间。
构建完成后,可以测试一下是否可以在jenkins容器内部使用docker命令。
[yangdong@centos7 ~]$ docker pull registry.cn-beijing.aliyuncs.com/andyyoung01/jenkins-with-docker
[yangdong@centos7 ~]$ docker run -v /var/run/docker.sock:/var/run/docker.sock \
> registry.cn-beijing.aliyuncs.com/andyyoung01/jenkins-with-docker \
> sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c6a9d18e6d6 registry.cn-beijing.aliyuncs.com/andyyoung01/jenkins-with-docker "/bin/tini -- /usr/lo" 29 seconds ago Up 11 seconds 8080/tcp, 50000/tcp pensive_nobel
可见,在容器内部可以运行docker命令,此命令查询到了宿主机或jenkins container内部正在运行的docker容器。上面是通过阿里云进行镜像构建。还可以通过docker官方的docker hub进行镜像构建,过程与阿里云类似,这里不再赘述。
本篇文章我们构建了一个jenkins容器,并在容器内部安装了docker和docker-compose,从而可以在运行完各种测试后,在容器内部通过docker命令自动构建测试完成后的代码的镜像,从而组成持续集成或持续交付pipeline的一部分。下篇通过一个实际的例子来看看怎样配置这个pipeline。