由于micros整个工程分成多个组来共同开发。为了便于各个组进行测试,进行如下设计:
1) 各个组在gitlab上创建一个或者多个branch,jenkins为各组的branch创建一个job,并为job创建对应的build策略。
2) docker registry(私有仓库)里面存储了各个组的镜像
3) 各组进行源码修改的时候,提交到gitlab,同时还要包括一个dockerfile,说明基于哪个image,在该image基础上做了什么修改
4) 各组提交代码后,jenkins拉取提交的branch代码,并在jenkins服务器本地执行dockerfile,完成image的升级或者更新,然后根据job的build策略,执行build操作,生成一个新的镜像
5) job对应的build策略中,包含了将新镜像push到docker registry的操作
6) 查看仓库中是否有该镜像,如果有,则说明成功
7) 各组继续开发,可以基于上一次更新的image。
前面几篇文章已经创建了gitlab,jenkins以及docker registry。本文基于上述基础。
这里,因为要构建docker镜像,而我们刚搭建jenkins还没有对应的docker可以使用。所以这里暂时用一个github上的项目作为构建docker的例子。将来我们自己的源码放到gitlab上之后,附上dockerfile,即可参考下述过程构建docker镜像。
然后创建一个自由风格的job为nginx。
然后配置一下源码管理,Git地址:https://github.com/dongwenpeng/nginx
打开git地址,发现里面有如下几个文件。有用的主要是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仓库:
主要就是构建脚本了,往下拉到build--add build step,选择执行shell,
添加如下内容:主要就是docker build所需要的参数,这里要注意docker所在的路径,可以先用whereis docker找一下。
#!/bin/sh
#
DATE=`date +%m%d%H%M `
#DIR="/var/lib/jenkins/jobs/nginx/workspace/"
DIR="."
sudo /usr/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组,否则获取不到容器ID.
nano/etc/sudoers
Defaults:jenkins !requiretty
# User privilege specification
root ALL=(ALL:ALL) ALL
jenkins ALL=(ALL:ALL) ALL
sudo usermod -G docker jenkins
在Jenkins的使用过程中,如果在脚本中使用到sudo命令,有可能出现如下所示的错误:
sudo: no tty present and no askpass program specified
这是因为Jenkins服务器在执行sudo命令时的上下文有误,导致这个命令执行的异常。
先设置不需要tty:
在设置免密码:
在Jenkins宿主服务器上运行如下命令
$ sudo visudo
修改jenkins权限
jenkins ALL=(ALL) NOPASSWD: ALL
然后重启jenkins
/etc/init.d/jenkins restart
在jenkins页面上对Nginx执行build。查看日志,由于jenkins会自动把github上的文件给下载下来放在workspace目录中。因此,触发脚本后,直接开始构建nginx镜像。
如果前面配置都正确的话,应该会出现如下日志:
Started by user Administrator
Building in workspace /var/lib/jenkins/workspace/nginx
> 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
Commit message: "docker images"
> git rev-list --no-walk c0148c6714be8a64710d87e2ebc3395573dfcb0f # timeout=10
[nginx] $ /bin/sh /tmp/jenkins5804040439588409846.sh
Sending build context to Docker daemon 3.273 MB
Step 1/13 : FROM nginx
---> 568c4670fa80
Step 2/13 : MAINTAINER dkey
---> Using cache
---> 60c5a8a4fb14
Step 3/13 : ENV RUN_USER nginx
---> Using cache
---> 738cd2e26361
Step 4/13 : ENV RUN_GROUP nginx
---> Using cache
---> fca704beccc4
Step 5/13 : ENV DATA_DIR /data/web
---> Using cache
---> 575a52d71bc0
Step 6/13 : ENV LOG_DIR /data/log/nginx
---> Using cache
---> 9e8839af5617
Step 7/13 : RUN mkdir /data/log/nginx -p
---> Using cache
---> 094ea8870679
Step 8/13 : RUN chown nginx.nginx -R /data/log/nginx
---> Using cache
---> 2349737938f7
Step 9/13 : ADD web /data/web
---> Using cache
---> 75c536901319
Step 10/13 : ADD nginx.conf /etc/nginx/nginx.conf
---> Using cache
---> f066c262603e
Step 11/13 : ADD default.conf /etc/nginx/conf.d/default.conf
---> Using cache
---> b4bffccbda9c
Step 12/13 : EXPOSE 80
---> Using cache
---> d7ce75f2e7ba
Step 13/13 : ENTRYPOINT nginx -g "daemon off;"
---> Using cache
---> af92f977e45b
Successfully built af92f977e45b
/tmp/jenkins5804040439588409846.sh: 10: /tmp/jenkins5804040439588409846.sh: [[Successfully built af92f977e45b: not found
Finished: SUCCESS
查看镜像是否创建成功:
现在使用Jenkins构建Docker镜像已经没有问题了,下面就可以把Jenkins构建完的镜像直接推送到远程的registry中
push image的时候如果出现下面的错误:
FATA[0000] Error: v1 ping attempt failed with error: Get https://192.168.8.40:5000/v1/_ping: dial tcp 192.168.8.40:5000: connection refused.
则需要在执行push命令的机器上配置docker:
查看私有仓库里的镜像(从公网看不到)
root@taiic:/var/lib# curl -X GET http://127.0.0.1:5000/v2/_catalog
{"repositories":["nginx_1"]}
这是在docker registry服务器上查看私有仓库里的镜像
micros@taiic:/etc/init.d$ curl -XGET http://192.168.8.40:5000/v2/_catalog
{"repositories":["centos-test","micros-env"]}
在远程机器上可以用这个命令查看私有仓库里有哪些镜像。
修改job的配置中的build中的shell脚本:
#!/bin/sh
#
DATE=`date +%m%d%H%M `
#DIR="/var/lib/jenkins/jobs/nginx/workspace/"
DIR="."
sudo /usr/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
#后面是打tag和push操作
echo '>>> Add tag to the new image'
sudo /usr/bin/docker tag nginx_$DATE 192.168.8.40:5000/nginx_$DATE
echo '>>> Start push new image'
sudo /usr/bin/docker push 192.168.8.40:5000/nginx_$DATE
日志如下:
Started by user Administrator
Building in workspace /var/lib/jenkins/workspace/nginx
> 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
Commit message: "docker images"
> git rev-list --no-walk c0148c6714be8a64710d87e2ebc3395573dfcb0f # timeout=10
[nginx] $ /bin/sh /tmp/jenkins6632556266194448186.sh
Sending build context to Docker daemon 3.273 MB
Step 1/13 : FROM nginx
---> 568c4670fa80
Step 2/13 : MAINTAINER dkey
---> Using cache
---> 60c5a8a4fb14
Step 3/13 : ENV RUN_USER nginx
---> Using cache
---> 738cd2e26361
Step 4/13 : ENV RUN_GROUP nginx
---> Using cache
---> fca704beccc4
Step 5/13 : ENV DATA_DIR /data/web
---> Using cache
---> 575a52d71bc0
Step 6/13 : ENV LOG_DIR /data/log/nginx
---> Using cache
---> 9e8839af5617
Step 7/13 : RUN mkdir /data/log/nginx -p
---> Using cache
---> 094ea8870679
Step 8/13 : RUN chown nginx.nginx -R /data/log/nginx
---> Using cache
---> 2349737938f7
Step 9/13 : ADD web /data/web
---> Using cache
---> 75c536901319
Step 10/13 : ADD nginx.conf /etc/nginx/nginx.conf
---> Using cache
---> f066c262603e
Step 11/13 : ADD default.conf /etc/nginx/conf.d/default.conf
---> Using cache
---> b4bffccbda9c
Step 12/13 : EXPOSE 80
---> Using cache
---> d7ce75f2e7ba
Step 13/13 : ENTRYPOINT nginx -g "daemon off;"
---> Using cache
---> af92f977e45b
Successfully built af92f977e45b
/tmp/jenkins6632556266194448186.sh: 11: /tmp/jenkins6632556266194448186.sh: [[Successfully built af92f977e45b: not found
>>> Add tag to the new image
>>> Start push new image
The push refers to a repository [192.168.8.40:5000/nginx_12200935]
4faf5dee2b80: Preparing
3b66c7dfdf1e: Preparing
111a6440378f: Preparing
5885cdf2cd45: Preparing
55a89fa43054: Preparing
ece4f9fdef59: Preparing
ad5345cbb119: Preparing
ef68f6734aa4: Preparing
ece4f9fdef59: Waiting
ef68f6734aa4: Waiting
55a89fa43054: Pushed
5885cdf2cd45: Pushed
3b66c7dfdf1e: Pushed
4faf5dee2b80: Pushed
ece4f9fdef59: Pushed
111a6440378f: Pushed
ad5345cbb119: Pushed
ef68f6734aa4: Pushed
latest: digest: sha256:744c3675dd95675e9b0a3c7bc24db13d8685878e3f74a14701596d1d16faeb94 size: 1986
Finished: SUCCESS
查看镜像:
查看仓库:
成功。至此使用jenkins构建docker镜像并自动上传到docker registry仓库的配置过程结束。
每次使用的时候要确保registry这个镜像已经运行起来了,否则相当于仓库没有开始营业,就无法push镜像到仓库。
附:dockerfile的内容:
FROM nginx
MAINTAINER dkey
ENV RUN_USER nginx
ENV RUN_GROUP nginx
ENV DATA_DIR /data/web
ENV LOG_DIR /data/log/nginx
RUN mkdir /data/log/nginx -p
RUN chown nginx.nginx -R /data/log/nginx
ADD web /data/web
ADD nginx.conf /etc/nginx/nginx.conf
ADD default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
ENTRYPOINT nginx -g "daemon off;"
其实就是根据一个基础镜像Nginx,执行一些操作,主要是将本地的一些文件复制到docker镜像里面,然后再build成一个新的镜像。