通过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的方式。这两种方式的对比可以通过下图说明:
“DinD vs Socket mounting”

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如下:

Dockerfilelink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM jenkins:2.19.2
MAINTAINER Yang Dong "andyyoung01@gmail.com"
USER root
RUN echo "deb http://apt.dockerproject.org/repo debian-jessie main" \
> /etc/apt/sources.list.d/docker.list \
&& apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 \
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D \
&& apt-get update \
&& apt-get install -y apt-transport-https \
&& apt-get install -y sudo \
&& apt-get install -y docker-engine \
&& rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN curl -L https://github.com/docker/compose/releases/download/1.8.0/\
docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose; \
chmod +x /usr/local/bin/docker-compose
USER jenkins
RUN /usr/local/bin/install-plugins.sh scm-api git-client git greenballs

上述文件中的第4行切换到了root用户,以便于后面安装docker和docker-compose。第5-19行主要就是安装docker和docker-compose的命令。第15行的作用是将jenkins用户加入sudo免密码权限,从而可以访问到宿主机的docker socket。最后几行命令的作用是切换回jenkins用户并且安装一些jenkins的插件。

下面通过阿里云的镜像仓库控制台来构建此镜像。由于镜像构建过程中需要从互联网下载各种软件包,国内的网络下载一些软件时速度过慢,而阿里云提供的“海外机器构建”选项可以大大提高软件的下载速度,从而节省大量时间。
2.png
3.png
4.png
5.png
6.png
构建完成后,可以测试一下是否可以在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。