持續整合之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中如何構建映象。