docker+jenkins+git+registry构建持续集成环境

in docker with 0 comment

背景说明

Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

先来了解一下比较典型的java项目发布工作流程:
1.java项目开发 >> 2.提交项目代码到(git或svn) >> 3. 拉取项目代码(jenkins或手动) >> 4.编译项目代码(jenkins或手动) >> 5.发布java项目,并运行java项目 >> 6.测试
1.png

在来看看用docker+jenkins+git发布java项目流程又是怎样的呢:
1.java项目开发 >> 2.提交项目代码git容器 >> 3.jenkins容器拉取项目代码 >> 4.maven编译构建项目 >> 5.jenkins发布项目到tomcat容器 >> 6.测试
2.png
看到上面的流程后,在没有jenkins的情况下这些步骤都是手工完成的,有了Jenkins的帮助,在这6步中,除了第1步,后续的5步都是自动化完成的。当你完成了提交,Jenkins会自动运行你的编译脚本,编译成功后,再运行你的测试脚本,这一步成功后,接着它会帮你把新程序发布出去,特别的,在最后一步,你可以选择手动发布,或自动发布。

环境介绍

服务器主机名主机IP运行服务
jenkinsjenkins192.168.1.21安装docker、Jenkins容器、git客户端、jdk、maven
dockerdocker192.168.1.22安装docker、创建镜像运行java项目:tale
Gitgit_registry192.168.1.23安装docker、git服务、运行registry私有仓库容器

说明:

名称版本软件包说明
服务器系统Centos 7.3linux系统
docker17.12.1-ceyum安装docker引擎服务
jdkjdk1.8.0_161jdk-8u161-linux-x64.tar.gz运行jenkins需要的JDK环境
maven3.5.3apache-maven-3.5.3-bin.tar.gz构建java项目需要的工具
jenkins2.60.3docker hub下载最新jenkins镜像持续集成工具
registrygit-1.8.3.1docker hub下载最新jenkins镜像docker私有仓库

部署环境

[root@git_registry ~]# yum -y install git
[root@git_registry ~]# useradd git
[root@git_registry ~]# passwd git
[root@git_registry ~]# su - git
创建app.git仓库,仓库名自定义,这一步需要切换刚才创建的git用户操作
[git@git_registry ~]$ cd /hoem/git/
[git@git_registry ~]$ mkdit app.git/ && cd app.git
[git@git_registry app.git]$ git --bare init
初始化空的 Git 版本库于 /home/git/app.git/
[git@git_registry app.git]$ ls
branches  config  description  HEAD  hooks  info  objects  refs
[root@jenkins ~]# yum install -y git
[root@jenkins ~]# mkdir /tale
[root@jenkins ~]# git  clone  https://github.com/otale/tale.git
[root@jenkins tale]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
c6:71:dd:63:13:39:e9:6c:4e:d2:c6:51:03:9f:ed:8b root@jenkins
The key's randomart image is:
+--[ RSA 2048]----+
|             .o=.|
|           . .*.+|
|        . . .===.|
|       . o  ..O+ |
|        S    *  .|
|       .      o .|
|             E . |
|                 |
|                 |
+-----------------+
# 把公钥拷贝到git服务器,注意用刚才的git用户
[root@jenkins tale]# ssh-copy-id git@192.168.1.23
The authenticity of host '192.168.1.23 (192.168.1.23)' can't be established.
ECDSA key fingerprint is 48:e6:b6:7a:a4:fe:14:d6:38:ba:51:b0:42:cd:56:03.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
git@192.168.1.23's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'git@192.168.1.23'"
and check to make sure that only the key(s) you wanted were added.
[root@jenkins tale]# mkdir /git
[root@jenkins tale]# cd /git/
[root@jenkins git]# git config --global user.email "test@qq.com"
[root@jenkins git]# git config --global user.name "test"
[root@jenkins git]# git clone git@192.168.1.23:/home/git/app.git
Cloning into 'app'...
warning: You appear to have cloned an empty repository.
[root@jenkins git]# mv /tale/tale/* /git/app/
[root@jenkins app]# ls
bin  LICENSE  package.xml  pom.xml  README.md  README_ZH.md  src
[root@jenkins app]# git add .
[root@jenkins app]# git commit  -m "add project tale"

3.png

[root@jenkins app]# git push origin master  
Counting objects: 297, done.
Compressing objects: 100% (255/255), done.
Writing objects: 100% (297/297), 6.35 MiB | 0 bytes/s, done.
Total 297 (delta 22), reused 0 (delta 0)
To git@192.168.1.23:/home/git/app.git
 * [new branch]      master -> master

我们还是用官方的镜像来创建docker私有仓库(git_registry主机操作)

[root@git_registry ~]# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name rregistry registry

4.png

[root@git_registry ~]# docker ps -l

5.png

[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
[root@docker ~]#  yum install -y docker-ce
[root@docker dockerfile_tale]# docker --version
Docker version 17.12.1-ce, build 7390fc6
[root@docker ~]# vim /etc/docker/daemon.json
{
  "registry-mirrors": [ "https://registry.docker-cn.com"],
  "insecure-registries": [ "192.168.1.23:5000"]
}

注意:书写格式为json格式,有严格的书写要求;
第1行是国内镜像源,第2行是docker私有仓库地址;
192.168.1.23就是docker私有仓库的地址,添加后连接docker私有仓库就是用http协议了。

[root@docker ~]# systemctl restart docker

由于后面运行java容器需要jdk环境,jdk如果放在容器中运行容器又相当重,所以就在宿主机上部署jdk,后面创建java容器的时候把宿主机的jdk路径挂载到容器就去。部署jdk很简单,解压就行:

[root@docker ~]# tar zxvf jdk-8u161-linux-x64.tar.gz -C /usr/local/

其实,这个镜像随便在哪台服务器上构建都行,在本文中就直接在这台docker服务器构建了

[root@docker /]# mkdir dockerfile_tale
[root@docker /]# cd dockerfile_tale/
[root@docker dockerfile_tale]# vim Dockerfile
FROM centos:7
RUN yum install epel-release -y
RUN yum install nginx supervisor -y && yum clean all
RUN sed -i '47a proxy_pass http://127.0.0.1:9000;' /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf
ENV PATH /usr/local/jdk/bin:$PATH
WORKDIR /tale
CMD ["/usr/bin/supervisord"]

说明:此Dockerfile以centos7为基础镜像,通过yum安装nginx、supervisor服务。定义jdk的环境变量,并通过supervisord来启动nginx和java项目。

[root@docker dockerfile_tale]# ls /dockerfile_tale/
Dockerfile  supervisord.conf
[root@docker dockerfile_tale]# cat supervisord.conf 
[supervisord]
nodaemon=true
[program:tale]
command=/usr/local/jdk/bin/java -jar /tale/tale-least.jar
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
[root@docker dockerfile_tale]# docker build -t tale:base .
[root@docker dockerfile_tale]# docker images

6.png

[root@docker dockerfile_tale]# docker push 192.168.1.23:5000/tale:base

7.png

由于jenkins需要jdk环境,jdk如果放在容器中运行容器又相当重,所以就在宿主机上部署jdk,后面创建jekins容器的时候把宿主机的jdk路径挂载到容器就去。部署jdk很简单,解压就行:

[root@jenkins ~]# tar zxvf jdk-8u161-linux-x64.tar.gz -C /usr/local/
[root@jenkins ~]# tar xf apache-maven-3.5.3-bin.tar.gz -C /usr/local/
下载地址:
http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.tar.gz

8.png

在本文中我们引用docker hub中的官方镜像来编写个Dockerfile文件:

[root@jenkins ~]# mkdir Dockerfile_jenkins
[root@jenkins Dockerfile_jenkins]# vim Dockerfile
FROM jenkins
USER root
RUN echo " > /etc/apt/sources.list.d/jessie-backports.list && \
wget http://mirrors.163.com/.help/sources.list.jessie -O /etc/apt/sources.list
RUN apt-get update && apt-get install -y git

Dockerfile说明:

[root@jenkins Dockerfile_jenkins]# docker build -t jenkins:v1 .

9.png

[root@jenkins Dockerfile_jenkins]# docker images

10.png

[root@jenkins Dockerfile_jenkins]# docker run -d \
--name jenkins \
-p 8080:8080 \
-v /var/jenkins_home/:/var/jenkins_home \
-v /usr/local/apache-maven-3.5.3:/usr/local/maven \
-v /usr/local/jdk1.8.0_161:/usr/local/jdk \
-v ~/.ssh:/root/.ssh \
jenkins:v1

11.png
参数说明,上面的参数都是最常用的,都比较很简单很好理解
-d:在后台运行容器;
-p:映射端口;
-v:宿主机的目录挂载到容器;/var/jenkins_home 这个目录在宿主机中空的,这是把容器中的jenkinis主目录绑定到宿主机中来,其它的两个目录是之前解压的工具;

[root@jenkins Dockerfile_jenkins]# docker top jenkins

12.png
13.png

通过http://192.168.1.21:8080 来访问Jenkins服务器,初始化配置
14.png

[root@jenkins Dockerfile_jenkins]# cat /var/jenkins_home/secrets/initialAdminPassword    
2b961c8fa167430da94d18b1170a8aa7

15.png

17.png

19.png

参数说明:
Name:192.168.1.22-docker
Hostname:192.168.1.22
Username:root
Remote Directory:/data 这个意思是把代码发布到192.168.1.22 /data目录中,需要手动创建个目录
Use password authentication, or use a different key:勾选它
Passphrase / Password:输入192.168.1.22这台docker服务器的密码

进“系统管理” -- "Global Tool Configuration",添加jdk安装,如下图:
20.png
参数说明:
别名:自定义就行;
JAVA_HOME:这个是你jenkins容器里的JDK路径,不是宿主机的JDK路径;

进“系统管理” -- "Global Tool Configuration",添加maven安装,如下图:
21.png
参数说明:和jdk一样,MAVEN_HOME 的路径也是指向jenkins容器里的maven路径;

这里我没有动git的配置,让它为默认配置,如下图:
22.png

点击"新建"--构建maven项目(如果没有maven选项,需要安装Maven Release Plug-in插件)
23.png

在“源码管理”项中选择Git,只需要配置git仓库的地址 “Repository URL”,之前我们在jenkins服务器上把公钥传输到了git服务器上了,所以不需要做认证,如下图:
24.png

在“构建触发器”选项中,选上“Poll SCM”,日程表 * ,每分钟都去捡查代码,这个和linux crontab是一样的含义。这一项你也可以不用测试,如下图:
25.png

在“Build”选项中,Goals and options输入:clean package。如下图:
26.png

在“Post Steps”选项中,配置如下操作:

docker rm -f tale-test
docker rmi -f 192.168.1.23:5000/tale:base
docker run -itd \
--name tale-test \
-p 80:80 \
-v /usr/local/jdk1.8.0_161:/usr/local/jdk \
-v /data/tale:/tale \
192.168.1.23:5000/tale:base

27.png

测试

配置上之后,构建此项目:
28.png

查看控制台输出日志:
29.png
30.png

看到最上面完成的状态,就可以进行测试了,如果是第一次构建时间会比较久,它需要下载maven相关的依赖包。

然后登录docker服务器查看一下运行的容器:

[root@docker dockerfile_tale]# docker ps -a

31.png

[root@docker dockerfile_tale]# docker top tale-test

32.png

最后通过浏览器来访问一下http://192.168.1.22,java写的tale开源博客项目:
33.png

总结

参照文章:
http://blog.51cto.com/ganbing/2085769

Responses