一、介绍Jenkins
Jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上。同时Jenkins能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。并且Jenkins提供了大量的插件,能够完成各种任务。
今天我需要使用Jenkins构建一个Docker镜像,然后自动push到docker registry中。到了docker registry中,后面测试人员就可以把镜像发布到测试环境,测试如果没有问题就可以发布到线上环境,大概流程如下图:
上图就是我生产使用方式,其中Jenkins master使用docker的好处就是方便后面迁移,而Jenkins slave不适用docker的原因就是在docker中再次安装docker进行镜像构建太麻烦了,索性直接使用主机。而registry部分有两个节点,他们之间的数据使用DRBD同步,外借助于haproxy+keepalived实现registry的高可用。
下面先介绍Jenkins构建docker镜像,在使用Jenkins构建Docker镜像之前,最好先看一下Docker:使用Dockerfile构建Nginx镜像。更有助于理解。
二、安装Jenkins
1. 添加Jenkins的源(repository)
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. 安装JDK
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. 安装Jenkins
1
|
$
yum
install
jenkins
-
y
|
1
2
|
$
rpm
-
qi
jenkins
|
grep
Version
Version
:
2.38
|
到此,Jenkins就安装完成了。然后就可以启动Jenkins。
1
|
$
systemctl
start
jenkins
|
Jenkins默认监控端口8080。
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路径加上即可。
三、Jenkins文件说明
/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日志文件。
四、配置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用户
此时还不能立即构建,因为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了。