Jenkins是一個開源項目,提供了一種易於使用的持續集成系統,使開發者從繁雜的集成中解脫出來,專一於更爲重要的業務邏輯實現上。同時Jenkins能實施監控集成中存在的錯誤,提供詳細的日誌文件和提醒功能,還能用圖表的形式形象地展現項目構建的趨勢和穩定性。而且Jenkins提供了大量的插件,可以完成各類任務。java
今天我須要使用Jenkins構建一個Docker鏡像,而後自動push到docker registry中。到了docker registry中,後面測試人員就能夠把鏡像發佈到測試環境,測試若是沒有問題就能夠發佈到線上環境,大概流程以下圖:node
上圖就是我生產使用方式,其中Jenkins master使用docker的好處就是方便後面遷移,而Jenkins slave不適用docker的緣由就是在docker中再次安裝docker進行鏡像構建太麻煩了,索性直接使用主機。而registry部分有兩個節點,他們之間的數據使用DRBD同步,外借助於haproxy+keepalived實現registry的高可用。nginx
下面先介紹Jenkins構建docker鏡像,在使用Jenkins構建Docker鏡像以前,最好先看一下Docker:使用Dockerfile構建Nginx鏡像。更有助於理解。git
1. 添加Jenkins的源(repository)github
1
2
|
$ sudo wget -O /etc/yum.repos.d/jenkins.repo http://jenkins-ci.org/redhat/jenkins.repo
$ sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
|
2. 安裝JDKweb
1
|
$ yum install java-1.8.0-openjdk -y
|
1
2
3
4
|
$ java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-b15)
OpenJDK 64-Bit Server VM (build 25.111-b15, mixed mode)
|
3. 安裝Jenkinsdocker
1
|
$ yum install jenkins -y
|
1
2
|
$ rpm -qi jenkins | grep Version
Version : 2.38
|
到此,Jenkins就安裝完成了。而後就能夠啓動Jenkins。shell
1
|
$ systemctl start jenkins
|
Jenkins默認監控端口8080。bash
1
2
3
4
|
$ netstat -nplt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 22047/java
|
啓動若是出現錯誤:」Starting Jenkins -bash: /usr/bin/Java: No such file or directory」,表示Jenkins找不到java。這時就須要編譯配置文件/etc/init.d/jenkins,把java路徑加上便可。less
/usr/lib/jenkins/:jenkins安裝目錄,WAR包會放在這裏。
1
2
3
|
$ ll /usr/lib/jenkins/
total 66980
-rw-r--r-- 1 root root 68586722 Dec 26 00:56 jenkins.war
|
/etc/sysconfig/jenkins:jenkins配置文件,其」端口」,」JENKINS_HOME」等均可以在這裏配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$ grep -v "^#" /etc/sysconfig/jenkins | grep -v "^$"
JENKINS_HOME="/var/lib/jenkins"
JENKINS_JAVA_CMD=""
JENKINS_USER="jenkins"
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
JENKINS_PORT="8080"
JENKINS_LISTEN_ADDRESS=""
JENKINS_HTTPS_PORT=""
JENKINS_HTTPS_KEYSTORE=""
JENKINS_HTTPS_KEYSTORE_PASSWORD=""
JENKINS_HTTPS_LISTEN_ADDRESS=""
JENKINS_DEBUG_LEVEL="5"
JENKINS_ENABLE_ACCESS_LOG="no"
JENKINS_HANDLER_MAX="100"
JENKINS_HANDLER_IDLE="20"
JENKINS_ARGS=""
|
/var/lib/jenkins/:默認的JENKINS_HOME。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$ ll /var/lib/jenkins/
total 32
-rw-r--r-- 1 jenkins jenkins 1575 Dec 27 20:09 config.xml
-rw-r--r-- 1 jenkins jenkins 159 Dec 27 20:09 hudson.model.UpdateCenter.xml
-rw------- 1 jenkins jenkins 1712 Dec 27 20:09 identity.key.enc
-rw-r--r-- 1 jenkins jenkins 4 Dec 27 20:09 jenkins.install.UpgradeWizard.state
drwxr-xr-x 2 jenkins jenkins 6 Dec 27 20:08 jobs
drwxr-xr-x 3 jenkins jenkins 18 Dec 27 20:09 logs
-rw-r--r-- 1 jenkins jenkins 907 Dec 27 20:09 nodeMonitors.xml
drwxr-xr-x 2 jenkins jenkins 6 Dec 27 20:09 nodes
drwxr-xr-x 2 jenkins jenkins 6 Dec 27 20:08 plugins
-rw-r--r-- 1 jenkins jenkins 129 Dec 27 20:08 queue.xml.bak
-rw-r--r-- 1 jenkins jenkins 64 Dec 27 20:08 secret.key
-rw-r--r-- 1 jenkins jenkins 0 Dec 27 20:08 secret.key.not-so-secret
drwx------ 4 jenkins jenkins 4096 Dec 27 20:09 secrets
drwxr-xr-x 2 jenkins jenkins 97 Dec 27 20:09 updates
drwxr-xr-x 2 jenkins jenkins 23 Dec 27 20:09 userContent
drwxr-xr-x 3 jenkins jenkins 18 Dec 27 20:09 users
|
/var/lib/jenkins/jobs/${project_name}/workspace/:Jenkins項目的工做空間,存儲從Git或SVN下載的內容,${project_name}就是其項目名稱。
/var/log/jenkins/jenkins.log:Jenkins日誌文件。
若是沒有特別配置端口,使用http://<ip address>:8080/登陸Jenkins,並進行相關配置(插件安裝、權限配置、View/Job建立等等)。
第一次登錄Jenkins時須要解鎖,把以下祕鑰填寫進去便可。
1
2
|
$ cat /var/lib/jenkins/secrets/initialAdminPassword
a737ebbbfece4e6991cf70d45a299ed5
|
而後設置一下用戶密碼,就正式進入到了Jenkins配置界面。
首先,須要安裝一些必要的插件SCM Sync Configuration Plugin ,GitHub plugin ,GIT plugin ,GIT client plugin,在系統管理->插件管理裏面安裝,安裝結束後重啓jenkins便可。
而後建立一個項目爲nginx。
而後配置一下源碼管理,Git地址:https://github.com/dongwenpeng/nginx
就下面幾個文件,主要是dockerfile,而後提供了一些nginx配置文件以及web文件。
1
2
3
4
5
|
-rw-r--r-- 1 jenkins jenkins 744 Dec 27 20:22 default.conf
-rw-r--r-- 1 jenkins jenkins 338 Dec 27 20:22 dockerfile
-rw-r--r-- 1 jenkins jenkins 593 Dec 27 20:22 nginx.conf
drwxr-xr-x 3 jenkins jenkins 16 Dec 27 20:22 web
-rw-r--r-- 1 jenkins jenkins 644118 Dec 27 20:22 web.zip
|
以下配置,也能夠使用你本地的Git倉庫:
主要就是構建腳本了。
腳本內容
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/bin/sh
#
DATE=`date +%m%d%H%M `
DIR="/var/lib/jenkins/jobs/nginx/workspace"
sudo /bin/docker build -t nginx_$DATE $DIR | tee $DIR/Docker_build_result.log
RESULT=$(cat $DIR/Docker_build_result.log | tail -n 1)
if [["$RESULT" != *Successfully*]];then
exit -1
fi
|
配置結束後,保存。
此時還不能當即構建,由於jenkins觸發腳本並非root用戶,所以須要將jenkins免密碼,並將用戶加入到docker組。
1
2
3
|
$ cat /etc/sudoers.d/jenkins
Defaults:jenkins !requiretty
jenkins ALL=(ALL) NOPASSWD: ALL
|
第一行表示僅jenkins用戶不須要控制終端,否則在Jenkins腳本中沒法使用sudo。
1
|
$ usermod -G docker jenkins
|
在jenkins的build記錄中能夠看到輸出,因爲jenkins會自動把github上的文件給下載下來放在workspace目錄中。所以,觸發腳本後,直接開始構建nginx鏡像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
Started by user admin
Building in workspace /var/lib/jenkins/jobs/nginx/workspace
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url https://github.com/dongwenpeng/nginx # timeout=10
Fetching upstream changes from https://github.com/dongwenpeng/nginx
> git --version # timeout=10
> git fetch --tags --progress https://github.com/dongwenpeng/nginx +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision c0148c6714be8a64710d87e2ebc3395573dfcb0f (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f c0148c6714be8a64710d87e2ebc3395573dfcb0f
> git rev-list c0148c6714be8a64710d87e2ebc3395573dfcb0f # timeout=10
[workspace] $ /bin/sh /tmp/hudson3618361245563383297.sh
Sending build context to Docker daemon 557.1 kB
Sending build context to Docker daemon 1.114 MB
Sending build context to Docker daemon 1.671 MB
Sending build context to Docker daemon 2.228 MB
Sending build context to Docker daemon 2.785 MB
Sending build context to Docker daemon 3.273 MB
Step 1 : FROM nginx
latest: Pulling from library/nginx
Digest: sha256:2a07a07e5bbf62e7b583cbb5257357c7e0ba1a8e9650e8fa76d999a60968530f
Status: Downloaded newer image for nginx:latest
---> 19146d5729dc
Step 2 : MAINTAINER dkey
---> Using cache
---> 715cd864289f
Step 3 : ENV RUN_USER nginx
---> Using cache
---> 919de987c861
Step 4 : ENV RUN_GROUP nginx
---> Using cache
---> 12bb383d0cdc
Step 5 : ENV DATA_DIR /data/web
---> Using cache
---> 69561736d70e
Step 6 : ENV LOG_DIR /data/log/nginx
---> Using cache
---> c9be367631c7
Step 7 : RUN mkdir /data/log/nginx -p
---> Using cache
---> 137c4decd554
Step 8 : RUN chown nginx.nginx -R /data/log/nginx
---> Using cache
---> 4262ffbc2a5c
Step 9 : ADD web /data/web
---> ac936a598dc4
Removing intermediate container 1efe9556276a
Step 10 : ADD nginx.conf /etc/nginx/nginx.conf
---> 2b6f7ab35d9f
Removing intermediate container 12b1066d8808
Step 11 : ADD default.conf /etc/nginx/conf.d/default.conf
---> 619fc14e58bf
Removing intermediate container 362067e9bbce
Step 12 : EXPOSE 80
---> Running in ace973e663f0
---> 7982205f27dd
Removing intermediate container ace973e663f0
Step 13 : ENTRYPOINT nginx -g "daemon off;"
---> Running in 892e45827ff4
---> 63375850b045
Removing intermediate container 892e45827ff4
Successfully built 63375850b045
Finished: SUCCESS
|
構建完成後,能夠去Jenkins主機看看鏡像是否完成。
1
2
3
4
|
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx_12272051 latest 63375850b045 58 minutes ago 182.7 MB
nginx latest 19146d5729dc 6 days ago 181.6 MB
|
能夠看到已經構建完成了,下面直接啓動此鏡像。
1
|
$ docker run --name nginx -p 80:80 -d nginx_12272051
|
1
2
3
|
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6ca642a3574 nginx_12272051 "/bin/sh -c 'nginx -g" 18 seconds ago Up 17 seconds 0.0.0.0:80->80/tcp, 443/tcp nginx
|
如今使用Jenkins構建Docker鏡像已經沒有問題了,下面就能夠把Jenkins構建完的鏡像直接推送到遠程的registry中。關於構建私有docker registry能夠看Docker:搭建私有倉庫(Registry 2.4)。
當遠程倉庫搞定後,其實Jenkins這邊作的並非太多,只須要把構建腳本修改一下,在構建完成後直接推送到遠程倉庫就OK了。