1. 程式人生 > >持續整合之jenkins實踐教程:基礎篇(6): 在jenkins的容器中進行映象的構建

持續整合之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]#

映象構建

[[email protected] 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
[[email protected] 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 ~]# 

結果確認

[[email protected] ~]# 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中如何構建映象。