持续集成之jenkins实践教程:基础篇(6): 在jenkins的容器中进行镜像的构建

这里写图片描述

作为持续集成的利器Jenkins已经得到了广泛地应用,仅仅作为一个工具,Jenkins已然有了自己的生态圈,支持其的plugin更是超过1300+。在实际中如何使用以及如何更好地使用jenkins,一直是大家在实践并讨论的。本系列文章将会从如何使用jenkins方面对一些细节进行总结和整理,这篇文章将会介绍如何在jenkins的容器中进行镜像的构建。

原因

镜像的构建docker build需要damon进程的支持,如果构建者自身本身就在容器之中,这个就是很久之前讨论的很多的docker in docker的情况。而是用更多的方式则是利用docker用于socket通信的socket文件,这篇文章将会详细的介绍这种方式。

准备

这种方式对目前常见的版本一般来说影响不大,这篇文章使用1.13.1的版本进行验证。

宿主机的docker版本:

[root@host154 tools]# docker version
Client:
 Version:      1.13.1
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   092cba3
 Built:        Wed Feb  8 08:47:51 2017
 OS/Arch:      linux/amd64

Server:
 Version:      1.13.1
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   092cba3
 Built:        Wed Feb  8 08:47:51 2017
 OS/Arch:      linux/amd64
 Experimental: false
[root@host154 tools]#

启动jenkins在镜像之中

直接使用docker run或者使用docker-compose或者其他方式,将jenkins启动在容器之中,比如:

[root@host154 tools]# docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED              STATUS              PORTS                     NAMES
46cc37b371cb        liumiaocn/jenkins:2.73.3   "run.sh"            About a minute ago   Up About a minute   0.0.0.0:38080->8080/tcp   tools_jenkins_1
[root@host154 tools]#

宿主机docker设定

宿主机docker的daemon进程需要设定如下两个选项:
-H tcp://0.0.0.0:4243
-H unix:///var/run/docker.sock

其实这个就是用于保证远程和本地两者都可以使用的方式。docker.sock这个文件,则是用于进程间通信用的,从其类型上的s可以清楚地看到这一点

[root@host154 tools]# ls -l /var/run/docker.sock
srw-rw----. 1 root root 0 Jan 12 06:26 /var/run/docker.sock
[root@host154 tools]# 

#

宿主机的docker build确认

由于镜像中的docker build最终还是借用于宿主机的docker build能力,所以在容器中构建镜像成功之前,最好先确认宿主机可以进行正常的docker build,比如我们将alpine镜像中加上时区设定的tzdata

[root@host154 tools]# cat Dockerfile 
FROM alpine

RUN apk update && apk add tzdata
[root@host154 tools]#

镜像构建

[root@host154 tools]# docker build -t alpine-tz:latest .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : RUN apk update && apk add tzdata
 ---> Running in 917d72bd3737
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
v3.7.0-50-gc8da5122a4 [http://dl-cdn.alpinelinux.org/alpine/v3.7/main]
v3.7.0-49-g06d6ae04c3 [http://dl-cdn.alpinelinux.org/alpine/v3.7/community]
OK: 9044 distinct packages available
(1/1) Installing tzdata (2017c-r0)
Executing busybox-1.27.2-r7.trigger
OK: 7 MiB in 12 packages
 ---> 42cd12f65952
Removing intermediate container 917d72bd3737
Successfully built 42cd12f65952
[root@host154 tools]# 

构建之后的确认

[root@host154 tools]# docker images |grep alpine
alpine-tz                              latest              42cd12f65952        4 minutes ago       6.69 MB
alpine                                 latest              3fd9065eaf02        2 days ago          4.14 MB
[root@host154 tools]#

至此说明宿主机的docker build是正常的,如果受困于内网/外网/代理等问题,可以将RUN的那句去掉,因为主要是为了验证能否进行docker build。

拷贝docker文件到镜像之中

为了使得在jenkins容器中能够正常地构建镜像,需要将docker文件先拷贝到镜像之中,使之用于作为客户端将指令传递给宿主机的docker守护进程,这可能是最方便的方法之一。

[root@host154 ~]# which docker
/usr/bin/docker
[root@host154 ~]# docker cp /usr/bin/docker tools_jenkins_1:/usr/bin/docker
[root@host154 ~]# 

结果确认

[root@host154 ~]# docker exec -it tools_jenkins_1 sh
/ # which docker
/usr/bin/docker
/ # docker version
Client:
 Version:      1.13.1
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   092cba3
 Built:        Wed Feb  8 08:47:51 2017
 OS/Arch:      linux/amd64
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
/ # 

镜像构建

事前准备

将确认成功的dockerfile拷贝到镜像之中

[root@host154 tools]# docker cp Dockerfile tools_jenkins_1:/tmp
[root@host154 tools]#

拷贝确认

[root@host154 tools]# docker exec -it tools_jenkins_1 sh
/ # cd /tmp
/tmp # ls Dockerfile
Dockerfile
/tmp # 

有很多种方法都可以构建成功,这里举出比较常用的两种方式:

构建:方法1

最清晰明了的方式是通过-H指定,可以做如下指定即可:

/tmp # docker -H tcp://192.168.163.154:4243 build -t alpine-tz-docker:latest .
Sending build context to Docker daemon 2.136 MB
Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : RUN apk update && apk add tzdata
 ---> Using cache
 ---> 42cd12f65952
Successfully built 42cd12f65952
/tmp # 

构建:方法2

如果因为各种原因,比如同一份代码,不同地方出现,而又不希望修改,总之不希望出现-H在命令之中,那可以使用DOCKER_HOST环境变量解决这个问题

/tmp # export DOCKER_HOST=tcp://192.168.163.154:4243
/tmp # docker build -t alpine-tz-docker:latest .
Sending build context to Docker daemon 2.136 MB
Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : RUN apk update && apk add tzdata
 ---> Using cache
 ---> 42cd12f65952
Successfully built 42cd12f65952
/tmp #

至此,在容器中构建镜像已经成功,接下来就比较简单了,只要保证jenkins能够使用这个能力即可,再有问题,基本就是jenkins的设定和使用方式的问题了。

Jenkins镜像构建方式

jenkins上需要安装docker的镜像,具体的集成方式在基础篇5中有了详细的说明,不再赘述。

Jenkinsfile

构建时最直接的方式可以使用pipeline创建一个stage,再其中直接使用sh来执行上述执行的docker build命令即可,比如

node {
    stage('镜像构建'){
     sh "cd /tmp/; docker -H tcp://192.168.163.154:4243 build -t alpine-tz-docker:latest ."
    }
}

构建结果

这里写图片描述

构建日志

从jenkins的构建日志中可以清楚地看到docker build的结果

Started by user root
[Pipeline] node
Running on Jenkins in /data/jenkins/workspace/docker-imagebuild
[Pipeline] {
[Pipeline] stage
[Pipeline] { (????)
[Pipeline] sh
[docker-imagebuild] Running shell script
+ cd /tmp/
+ docker -H tcp://192.168.163.154:4243 build -t alpine-tz-docker-1:latest .
Sending build context to Docker daemon 2.136 MB

Step 1/2 : FROM alpine
 ---> 3fd9065eaf02
Step 2/2 : RUN apk update && apk add tzdata
 ---> Using cache
 ---> 42cd12f65952
Successfully built 42cd12f65952
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

或者使用docker image也可以看到刚刚构建成功的镜像,日志中显示的????似乎是stage名称的中文支持不好,建议使用英文。

其他方式

除了设定DOCKER_HOST,还可以使用jenkins提供的docker-workflow,原理都是一样,设定方法不同而已,比如上述写法可以改成:

node {
    stage('镜像构建'){
        withDockerServer([uri: 'tcp://192.168.163.154:4243']) {  
        docker.build "alpine-tz-docker:latest","/tmp"
            }
    }
}

总结

这篇文章介绍了如何在容器中构建镜像以及jenkins中如何构建镜像。

淼叔 CSDN认证博客专家 神经网络 TensorFlow NLP
资深架构师,PMP、OCP、CSM、HPE University讲师,EXIN DevOps Professional与DevOps Master认证讲师,曾担任HPE GD China DevOps & Agile Leader,帮助企业级客户提供DevOps咨询培训以及实施指导。熟悉通信和金融领域,有超过十年金融外汇行业的架构设计、开发、维护经验,在十几年的IT从业生涯中拥有了软件开发设计领域接近全生命周期的经验和知识积累,著有企业级DevOps技术与工具实战。
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页