关于jenkins的文章比较多,笔者决定写一篇比较详细的利用容器来构建jenkins+git+registry的文章来和你们共同讨论。文章比较长,须要有点耐心慢慢看完,若是你们在实验的过程当中遇到问题,能够留言一块儿讨论或者加我QQ一块儿讨论都行。html
本文重点介绍jenkins以及jenkins如何在docker容器中运行,jenkins和docker私有仓库又是怎么玩的。docker说明、安装和git说明、安装在本文中不会特别详细的介绍。java
而且,在本文中不着重介绍原理性的东西,好比不会介绍什么是持续集成、持续构建等等。本文的重点是实战为主。对持续集成、持续交付、持续部署等概念不太了解的朋友能够参考这篇文章了解一下:https://www.zhihu.com/question/23444990python
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工做,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。linux
先来了解一下比较典型的java项目发布工做流程:
1.java项目开发 >> 2.提交项目代码到(git或svn) >> 3. 拉取项目代码(jenkins或手动) >> 4.编译项目代码(jenkins或手动) >> 5.发布java项目,并运行java项目 >> 6.测试nginx
在来看看用docker+jenkins+git发布java项目流程又是怎样的呢:
1.java项目开发 >> 2.提交项目代码git容器 >> 3.jenkins容器拉取项目代码 >> 4.maven编译构建项目 >> 5.jenkins发布项目到tomcat容器 >> 6.测试git
看到上面的流程后,在没有jenkins的状况下这些步骤都是手工完成的,有了Jenkins的帮助,在这6步中,除了第1步,后续的5步都是自动化完成的。当你完成了提交,Jenkins会自动运行你的编译脚本,编译成功后,再运行你的测试脚本,这一步成功后,接着它会帮你把新程序发布出去,特别的,在最后一步,你能够选择手动发布,或自动发布。github
一、服务器部署信息docker
服务器 | 主机名 | IP | 运行服务 |
---|---|---|---|
jenkins服务器 | jenkins | 172.18.18.32 | 安装docker、 运行jenkins容器、git客户端、jdk、maven |
docker服务器 | docker | 172.18.18.33 | 安装docker、建立镜像运行java项目:tale |
Git和私有仓库服务器 | git_registry | 172.18.18.34 | 安装docker、git服务、运行registry私有仓库容器 |
说明:shell
二、版本信息apache
名称 | 版本 | 软件包 | 说明 |
---|---|---|---|
服务器 | Centos 7.4 | 无 | linux系统 |
docker | 17.12.0-ce | yum安装 | docker引擎服务 |
jdk | 1.8.0_45 | jdk-8u45-linux-x64.tar.gz | 运行jenkins须要的JDK环境 |
maven | 3.5.0 | apache-maven-3.5.0-bin.tar.gz | 构建java项目须要的工具 |
jenkins | 最新版本 | docker hub下载最新jenkins镜像 | 持续集成工具 |
registry | 最新版本 | docker hub下载最新registry镜像 | docker私有仓库 |
jdk官方下载地址:http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html
maven官方下载地址:https://maven.apache.org/download.cgi
jenkins官方镜像地址:https://hub.docker.com/_/jenkins/
registry官方镜像地址:https://hub.docker.com/_/registry/
注意:这个步骤在 git_registry 服务器上操做
一、安装git
[root@git_registry ~]# yum -y install git
二、建立git用户
[root@git_registry ~]# useradd git [root@git_registry ~]# passwd git Changing password for user git. New password: BAD PASSWORD: The password is shorter than 8 characters Retype new password: passwd: all authentication tokens updated successfully. #记得切换建立的git用户操做: [root@git_registry ~]#su - git
三、建立仓库
建立app.git仓库,仓库名自定义,这一步须要切换刚才建立的git用户操做
[git@git_registry root]$ cd /home/git/ [git@git_registry ~]$ cd app.git/ [git@git_registry app.git]$ git --bare init Initialized empty Git repository in /home/git/app.git/ #而后用ls查看一下app.git仓库初始化完成了: [git@git_registry app.git]$ ls branches config description HEAD hooks info objects refs
注意:这个步骤在 jenkins 服务器上操做
正常来讲,开发用本身的电脑把写好的代码push到git仓库就算完成验证,在本文中去github里下载一个java项目(tale)来验证,咱们就用jenkins这台服务器作为git客户端吧:
一、下载git客户端
[root@jenkins ~]# yum -y install git
二、下载tale项目包
#先建立个目录来存放tale包,随便放在哪一个空目录下都行,后面咱们还须要把它移走 [root@jenkins ~]# mkdir /tale [root@jenkins ~]# git clone https://github.com/otale/tale.git #在查看下载好的tale项目 [root@jenkins tale]# ls bin LICENSE package.xml pom.xml README.md README_ZH.md src
三、生成公钥,拷贝到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): 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: SHA256:S6qxaVNuJ5inLxGDdrqqlpNsG4AsmcXH88dXckHdIOI root@jenkins The key's randomart image is: +---[RSA 2048]----+ | ..+..o | | . . . . o. .| | o.+ E o | |o+o.+o . + | |*o o o. S . | |o . . .+ o | |..o..*. . | | Bo *== . | |*oo.=B.o | +----[SHA256]-----+ #把公钥拷贝到git服务器,注意用刚才的git用户 [root@jenkins tale]# ssh-copy-id git@172.18.18.34 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /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@172.18.18.34's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'git@172.18.18.34'" and check to make sure that only the key(s) you wanted were added.
四、用git clone验证
#先建立个目录,目录名随便定义,用于拉取git服务器上建立的app.git仓库 [root@jenkins tale]# mkdir /git [root@jenkins tale]# cd /git/ #配置下git客户端的用户信息 [root@jenkins git]# git config --global user.email "test@qq.com" [root@jenkins git]# git config --global user.name "test" #在来git clone,因为app.git仓库是空的,因此会很快 [root@jenkins git]# git clone git@172.18.18.34:/home/git/app.git Cloning into 'app'... warning: You appear to have cloned an empty repository.
五、把以前下载的tale项目push到app.git仓库中
#先移动至刚才/git目录下 [root@jenkins git]# mv /tale/* /git/app/ [root@jenkins git]# cd /git/app/ [root@jenkins app]# ls bin LICENSE package.xml pom.xml README.md README_ZH.md src #而后提交到git仓库 [root@jenkins app]# git add . [root@jenkins app]# git commit -m "add project tale" [root@jenkins app]# git push origin master Counting objects: 297, done. Delta compression using up to 4 threads. 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@172.18.18.34:/home/git/app.git * [new branch] master -> master
注意:这个步骤在 git_registry 服务器上操做
咱们仍是用官方的镜像来建立docker私有仓库:
[root@git_registry /]# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name rregistry registry
查看一下私有仓库已经起来了:
[root@git_registry /]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4ac357e4b6dd registry "/entrypoint.sh /etc…" 7 seconds ago Up 7 seconds 0.0.0.0:5000->5000/tcp rregistry
对registry私有仓库不太了解的朋友能够参考笔者的这篇文章 《docker:用registry快速搭建私有镜像仓库》
注意:这个步骤在 docker服务器上操做
这台服务器就是在docker中运行刚才的tale 这个java项目的服务器,因此咱们要在这台服各器上安装下docker。
一、安装Docker
[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 docker-ce
二、配置镜像源为国内官方源
[root@docker ~]# vim /etc/docker/daemon.json { "registry-mirrors": [ "https://registry.docker-cn.com"], "insecure-registries": [ "172.18.18.34:5000"] }
注意书写格式为json格式,有严格的书写要求;
第1行是国内镜像源,第2行是docker私有仓库地址;
172.18.18.34就是docker私有仓库的地址,添加后链接docker私有仓库就是用http协议了。
三、启动dokcer服务
[root@docker ~]# systemctl restart docker
四、部署JDK
因为后面运行java容器须要jdk环境,jdk若是放在容器中运行容器又至关重,因此就在宿主机上部署jdk,后面建立java容器的时候把宿主机的jdk路径挂载到容器就去。部署jdk很简单,解压就行:
[root@docker ~]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/
咱们把它解压在docker这台宿主机的/usr/local目录中。
五、构建tale开源博客的基础镜像
其实,这个镜像随便在哪台服务器上构建都行,在本文中就直接在这台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项目。下面来看下supervisord.conf配置。
[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
上面的配置都是基础配置,分别是经过java -jar启动tale-least:jar包,nginx -g 启动nginx服务。
而后,构建镜像:
[root@docker dockerfile_tale]#docker build -t tale:base . [root@docker dockerfile_tale]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tale base b6d5028ecc3b 2 seconds ago 372MB centos 7 2d194b392dd1 6 days ago 195MB
对tale:base镜像打tag,并上传到registry私有仓库:
[root@docker /]#docker tag tale:base 172.18.18.34:5000/tale:base [root@docker /]#docker push 172.18.18.34:5000/tale:base
注意:这个步骤在 jenkins 服务器上操做
一、部署JDK
因为jenkins须要jdk环境,jdk若是放在容器中运行容器又至关重,因此就在宿主机上部署jdk,后面建立jekins容器的时候把宿主机的jdk路径挂载到容器就去。部署jdk很简单,解压就行:
[root@jenkins /]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/
咱们把它解压在宿主机的/usr/local目录中。
二、部署maven
因为本文后期是经过jenkins运行java项目,因此咱们还须要maven工具,maven也和jdk部署同样,也不想在容器中运行maven,因此也是部署在宿主机上而后挂载到容器中。也是直接解压:
[root@jenkins local]# tar -zxvf apache-maven-3.5.0-bin.tar.gz -C /usr/local/
查看一下这两个源码软件是否解压:
三、生成jenkins镜像
在本文中咱们引用docker hub中的官方镜像来编写个Dockerfile文件:
#说明:下面我建立个目录来放置jenkins的Dockerfile文件,这个文件随便放在哪一个目录都行 [root@jenkins /]# mkdir /Dockerfile_jenkins [root@jenkins /]# cd 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说明:
四、构建jenkins镜像
[root@jenkins Dockerfile_jenkins]# docker build -t jenkins:v1 .
查看一下构建的镜像:
五、建立jenkins镜像
[root@jenkins / ]#docker run -d \ --name jenkins \ -p 8080:8080 \ -v /var/jenkins_home/:/var/jenkins_home \ -v /usr/local/apache-maven-3.5.0:/usr/local/maven \ -v /usr/local/jdk1.8.0_45:/usr/local/jdk \ -v ~/.ssh:/root/.ssh \ jenkins:v1
参数说明,上面的参数都是最经常使用的,都比较很简单很好理解
-d:在后台运行容器;
-p:映射端口;
-v:宿主机的目录挂载到容器;/var/jenkins_home 这个目录在宿主机中空的,这是把容器中的jenkinis主目录绑定到宿主机中来,其它的两个目录是以前解压的工具;
来查看jenkins运行状态:
[root@jenkins Dockerfile_jenkins]# docker top jenkins UID PID PPID C STIME TTY TIME CMD root 25304 25289 0 10:10 ? 00:00:00 /bin/tini -- /usr/local/bin/jenkins.sh root 25335 25304 1 10:10 ? 00:00:17 java -jar /usr/share/jenkins/jenkins.war
[root@jenkins Dockerfile_jenkins]# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0c10bec5812e jenkins:v1 "/bin/tini -- /usr/l…" 18 minutes ago Up 18 minutes 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins
上面的两个状态显示jenkins容器运行都是OK的!!!
经过http://ip:8080 来访问jenkins服务;
从上图给出的提示,须要从/var/jenkins_home/secrets/initialAdminPassword获取密码
[root@jenkins /]# cat /var/jenkins_home/secrets/initialAdminPassword dff1d41be2254f87ad80a65eac621cb8
进入“系统管理” -- “系统设置”,主要是把docker这台服务器经过ssh的形式添加进来,后期部署dokcer容器,以下图:
参数说明:
Name:172.18.18.33-docker
Hostname:172.18.18.33
Username:root
Remote Directory:/data 这个意思是把代码发布到172.18.18.83 /data目录中,须要手动建立个目录
Use password authentication, or use a different key:勾选它
Passphrase / Password:输入172.18.18.83这台docker服务器的密码
一、jdk配置
进“系统管理” -- "Global Tool Configuration",添加jdk安装,以下图:
参数说明:
别名:自定义就行;
JAVA_HOME:这个是你jenkins容器里的JDK路径,不是宿主机的JDK路径;
二、maven配置
进“系统管理” -- "Global Tool Configuration",添加maven安装,以下图:
参数说明:和jdk同样,MAVEN_HOME 的路径也是指向jenkins容器里的maven路径;
三、git配置
这里我没有动git的配置,让它为默认配置,以下图:
一、构建maven项目
点击“新建” -- “构建一个maven项目,项目名称定为java-tale,以下图:
二、源码管理
在“源码管理”项中选择Git,只须要配置git仓库的地址 “Repository URL”,以前咱们在jenkins服务器上把公钥传输到了git服务器上了,因此不须要作认证,以下图:
三、构建触发器
在“构建触发器”选项中,选上“Poll SCM”,日程表 * ,每分钟都去捡查代码,这个和linux crontab是同样的含义。这一项你也能够不用测试,以下图:
四、build配置
在“Build”选项中,Goals and options输入:clean package。以下图:
五、构建后的配置
在“Post Steps”选项中,配置以下操做:
配置说明:
Nmae:选择须要部署的docker服务器,前面咱们SSH增长了一台,因此这里能够直接选择;
source files:须要部署到目标服务的打包成果路径
Remove prefilx: “Source files”配置的路径中要移除的前缀
Remote directory:成果要发送到的远程目标服务目录路径,这个路径与第一步配置中的Remote Directory对应。
Exec command:成果发送完成后,须要执行的命令,具体以下
docker rm -f tale-test docker rmi -f 172.18.18.34:5000/tale:base docker run -itd \ --name tale-test \ -p 80:80 \ -v /usr/local/jdk1.8.0_45:/usr/local/jdk \ -v /data/tale:/tale \ 172.18.18.34:5000/tale:base
在Exec command执行中的命令都是在构建代码完成后的操做,会在172.18.18.33-docker这台服务器上执行。
第1/2条命令:其实这两步你先能够不用加上,到了下一次构建的时候你测试一下不加这两条命令会有什么结果。若是构建失败,你在加上这两条命令,其实这两条命令是事先删除容器和镜像文件,而后经过第3条命令运行全新的容器。
第3条命令:就是经过docker run来运行tale-test容器了,并把172.18.18.33-docker这台服务器的jdk和tale目录挂载到容器中。
六、测试
配置上以后,构建此项目:
查看控制台输出日志:
看到最上面完成的状态,就能够进行测试了,若是是第一次构建时间会比较久,它须要下载maven相关的依赖包。
而后登陆docker服务器查看一下运行的容器:
[root@docker /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 83b29455b2c5 172.18.18.34:5000/tale:base "/usr/bin/supervisord" 6 minutes ago Up 6 minutes 0.0.0.0:80->80/tcp tale-test [root@docker /]#docker top tale-test UID PID PPID C STIME TTY TIME CMD root 815 797 0 20:03 pts/0 00:00:00 /usr/bin/python /usr/bin/supervisord root 862 815 0 20:03 pts/0 00:00:02 /usr/local/jdk/bin/java -jar /tale/tale-least.jar root 863 815 0 20:03 pts/0 00:00:00 nginx: master process /usr/sbin/nginx -g daemon off; polkitd 869 863 0 20:03 pts/0 00:00:00 nginx: worker process polkitd 870 863 0 20:03 pts/0 00:00:00 nginx: worker process polkitd 871 863 0 20:03 pts/0 00:00:00 nginx: worker process polkitd 872 863 0 20:03 pts/0 00:00:00 nginx: worker process root 962 797 0 20:04 ? 00:00:00 bash
最后,经过用浏览器来访问一下这个用java写的tale开源博客项目:
从上面能够看到,我是经过docker那个服务器IP来访问的,访问是OK的。到此,实战docker+jenkins+git构建持续集成环境就结束了。
一、首先要对整个流程熟悉,思路不能乱,规划好服务器数量和部署的应用服务。
二、本文中用的jar包来测试的,通常jar包直接用jar命令运行、也能够部署在tomcat容器中。jar包不依赖tomcat,因此本文在基础镜像172.18.18.34:5000/tale:base中只是安装了nginx,并无安装tomcat。若是你们用war包,那么这个基础镜像就要从新制做了。
三、在4.4步的第5小步中“构建后的操做”,是否是有一堆命令,其实也能够把它写成一个shell脚本,直接调用一执行,看我的操做习惯。
四、还有就是用Dockferfile构建基础镜像中,这些服务都是经过yum来安装的,咱们也能够把它换成源码安装,你们能够自行测试一下。
五、遇到错误的时候本身先排错,不要急于百度或问别人答案,容器这一块的错误经过docker logs 容器、docker ps 、docker top 容器等命令能够很好的定位错误。而且能够很方便的用“docker exec -it 容器 bash ”进入容器直接排查错误。
喜欢个人文章,请点击最上方右角处的《关注》支持一下!