Jenkins+Docker+Gitlab+Maven+Nexus+SonarQube

一、相关概念介绍:

持续(Continuous):不断地获取反馈、响应反馈

集成(Integration):编译、打包、测试

部署(Deployment):应用组件或基本设施的代码或配置变更在产品环境生效

发布(Release):具有业务影响的功能变化对最终用户可见

交付(Delivery):可以理解为从Deployment到Release之间的阶段,强调的是一种能力,开发有能力频繁部署,业务有能力随时发布

持续集成

持续集成(Continuous Integration简称CI)是利用一系列的工具、方法与规则,做到快速的构建代码,并自动的进行测试,从而提高代码的效率和质量.

大致的步骤如下:

开发人员通过IDE工具将代码推送到gitlab.

jenkins从gitlab中获取到源码,并使用maven编译、打包、自动构建镜像.

jenkins在构建脚本中调用docker命令将构建好的镜像push到本地Docker Registry.并启动相应的容器.

jenkins构建失败或者成功,可以及时将结果推送给相关人员,比如测试人员,安排测试.

运维人员只需获取相应的镜像就可以快速发布到生产环境.

Jenkins:开源的、可扩展的、基于Web界面的持续集成平台

Git:开源的分布式版本控制系统

GitLab:用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务

Maven:基于项目对象模型(POM)的项目管理及自动构建工具,用于编译源码并打包

Nexus:Maven私服

SonarQube:用于代码质量管理和检测的开源平台

环境搭建

本地开发环境为windows环境,开发工具为IntelliJ IDEA.

1.本地下载并安装配置git客户端Git-2.14.1-64-bit

2.在虚拟机上搭建gitlab服务

拉取gitlab镜像

[root@bogon/]# docker pull gitlab/gitlab-ceUsingdefaulttag:latestlatest

启动gitlab容器

[root@bogon/]# docker run--detach \>--hostname gitlab.william.com \>--publish8443:443--publish48080:80--publish8022:22\>--name gitlab \>--restart always \>--volume/opt/gitlab/config:/etc/gitlab \>--volume/opt/gitlab/logs:/var/log/gitlab \>--volume/opt/gitlab/data:/var/opt/gitlab \>gitlab/gitlab-ce:lateste19375a8f2b2a76e6dae2ecd5e7b0d5864c7a2e9975bfc4274cb166cd5091b7b

注意上面的docker run命令指定了域名为gitlab.william.com,必须通过该域名才能访问gitlab,所以在gitlab容器启动前要先在虚拟机和本地配置ip与域名的映射关系.

#在linux下: vi /etc/hosts #在windows下: cd C:\Windows\System32\drivers\etc\hosts

修改host文件在最下面添加

192.168.56.101 gitlab.william.com

另外我们指定了三个端口,22表示ssh端口,80表示http端口,443表示https端口,分别映射到宿主机上的8022、48080和8443端口,我们还通过--volume指定目录映射,其中

/etc/gitlab表示gitlab的配置目录,映射到宿主机的/opt/gitlab/config目录.

/var/log/gitlab表示gitlab的日志目录,映射到宿主机的/opt/gitlab/logs目录.

/var/opt/gitlab表示gitlab的数据目录,映射到宿主机的/opt/gitlab/data目录.

启动gitlab容器后打开浏览器输入地址http://gitlab.william.com:48080发现访问不了

先查看48080端口是否开启

[root@bogon/]# firewall-cmd--zone=public--query-port=48080/tcpno

很明显需要开启48080端口

[root@bogon/]# firewall-cmd--zone=public--add-port=48080/tcp--permanentsuccess[root@bogon/]# firewall-cmd--reloadsuccess

再次打开浏览器输入地址http://gitlab.william.com:48080后重定向进入修改管理员密码页面,我们将密码修改为12345678.

修改完密码后接着进入管理登录页面,输入登录用户名密码root/12345678登录进去.

接下来新建一个空的项目hello,其中hello为项目名称,可设置可见性级别:

Private表示私有项目,授予具体权限的用户才能访问.

Internal表示内部项目,可登陆的用户都能克隆项目.

Public表示公开项目,没有任何权限的用户都能克隆项目.

项目创建完毕之后,开始进入主页面:

接着我们需要做的就是将本地java代码推送至gitlab中.

在推送之前先全局设置git

[root@bogon /]# git config --global user.name"william.zhang"

[root@bogon /]# git config --global user.email"952408421@qq.com"

3.使用IntelliJ IDEA 将项目发布(提交)到GitLab

首先需要启用项目的版本管理功能,点击VCS 启用版本控制.

然后右击项目,选择Git->add,将项目中的文件加入到git add中等待本地提交,add 后的文件都会由橙色变成绿色.

下一步本地提交代码,右击项目选择Git->Commit Directory...这时本地提交成功,可以看见文件颜色从绿色变成了黑色.

最后就是将代码push到远程git仓库了,右击项目 Git->Repository ->Push

在Define Remote窗口里面的URL中填入http://gitlab.william.com:48080/root/hello.git

点击ok按钮弹出下面窗口

输入用户名密码:root/12345678

然后开始push...

push成功之后刷新http://gitlab.william.com:48080/root/hello可以看到本地代码已经推送至gitlab了.

4.安装jenkins

拉取jenkins镜像

[root@bogon~]# docker pull jenkinsci/jenkinsUsingdefaulttag:latestlatest:Pullingfromjenkinsci/jenkins

然后开启38080端口,并启动jenkins容器.

[root@bogon~]# docker run \>-d \>-p38080:8080\>-p50000:50000\>--name jenkins \>--link gitlab:gitlab.william.com \>-u root \>-v/opt/jenkins:/var/jenkins_home \>jenkinsci/jenkins:latestf7fa42d4e010833da5d9e5258855ac53d7d1c4855549e12992ceac236f3d583a

其中8080端口是jenkins的端口,38080是映射宿主机的端口,50000端口是master和slave通信端口.以root用户来启动容器,同时通过配置--link连接gitlab,因为要与gitlab容器通讯下载代码.

打开浏览器http://192.168.56.101:38080/访问跳转到解锁jenkins页面.

在服务器上以下执行命令查看密码

[root@bogon~]# cat/var/jenkins_home/secrets/initialAdminPasswordcat:/var/jenkins_home/secrets/initialAdminPassword:没有那个文件或目录

由于之前启动jenkins容器时我们做了目录映射 -v /opt/jenkins:/var/jenkins_home,所以要将执行命令改为:

[root@bogon~]# cat/opt/jenkins/secrets/initialAdminPasswordaa42541900b146f59007de7c0cdc4d3a[root@bogon~]#

在解锁页面上输入上述密码,继续进入以下页面:

建议选择安装推荐的插件,基本上一些常用的插件都会被安装,安装过程如图:

安装完后进入以下页面:

单击开始使用Jenkins按钮进入jenkins系统,点击左侧菜单中的系统管理进入Jenkins管理模块,查看系统设置:

主目录是存放Jenkins所有的文件的,工作空间根目录和构建记录目录默认都是在Jenkins主目录下,这个设置一般不用进行变更.

执行者数量:可以并发构建的数量.

标记:用来记录这个机器的名称(为了分配节点使用,后面子节点会详细介绍).

用法:设置这个节点的执行策略(包括尽可能使用这个节点和只允许绑定到这台机器的job.

生成前等待时间:这个时间为构建开始前的等待时间.

scm签出重试次数:使用svn或者git拉取代码失败重试的次数.

Restrict project naming:限制项目命名,勾选后可以看到具体设置,可以设置为默认或者使用正则表达式进行限制.

全局属性

environment variables:设置全局变量,在这里定义的全局变量可以在构建或者发送邮件时引用.

tool locations:设置全局工具,可以把需要的工具都在这里进行配置,比如maven,ant,jdk等.

设置时间格式

管理监控默认选中所有

jenkins location

jenkins url :设置jenkins的url(发送邮件引用jenkins的地址会取这个值,如果设错了,邮件的连接就会打不开)

系统管理员邮件地址:管理员的邮件地址(在构建需要发送邮件时,会用到这个邮件地址)

接着进入插件管理,选择可选插件板块,安装并配置maven插件,如果缺少Maven Integration Plugin插件,在创建job时,不会有新建一个maven项目选项.

接下来使用jenkins创建一个构建任务.

输入项目名称hello,选中构建一个maven项目点击确定按钮进入项目配置页面:

在源码管理板块中我们选择git并在repository url填写git仓库名称,但此时会报错:

从报错提示中发现jenkins访问gitlab.william.com时出现连接拒绝,可以断定是由于jenkins容器与gitlab容器无法通讯导致的.

解决方法是在启动jenkins容器时添加--link选项,并将其指定到需要连接的gitlab容器,重启jenkins容器后重新填写仓库URL出现另一个错误:

通过错误提示可知:我们所填入的URL是需要身份认证的,可单击Credentials下拉框右侧的Add按钮,并选择Jenkins选项,弹出身份认证信息对话框:

上面填写的是gitlab的用户名密码验证,添加完后需要选中它,这个时候可以看到已经不报错了.

紧接着我们在build板块中配置maven:

在Goals and options使用clean package -q可以加快maven构建速度.

添加构建后操作

点击增加构建后操作步骤,选择归档成品,在文本框中输入需要存档的文件路径:**/target/*.jar.

单击保存回到主界面

单击左侧菜单的立即构建并在控制台输出中查看构建日志:

由日志可看出构建过程报错了提示找不到pom文件,根据提示回到build板块中修改maven配置Root POM为hello/pom.xml,再重新手工构建即可.

构建完成后,回到jenkins主界面可以看到构建任务列表

小球图标表示构建状态,蓝色表示构建成功,但我们的目的是搭建一个持续集成的环境,在开发阶段我们会不断的推送代码到gitlab,所以我们需要利用jenkins来帮我们实现自动构建发布.

在Post step板块中填写shell脚本实现自动化发布.

#定义变量API_NAME="hello"API_VERSION="1.0.0"API_PORT=58080IMAGE_NAME="192.168.56.101:5000/hello/$API_NAME:$BUILD_NUMBER"CONTAINER_NAME=$API_NAME-$API_VERSION#进入target目录复制Dockerfile文件cd $WORKSPACE/$API_NAME/targetcp classes/Dockerfile .#构建docker镜像docker build -t $IMAGE_NAME .#推送docker镜像docker push $IMAGE_NAME#删除docker容器cid=$(docker ps | grep "$CONTAINER_NAME" | awk '{print $1}')if [ "$cid" != "" ]; then  docker rm -f $cidfi#启动docker容器docker run -d -p $API_PORT:8080 --name $CONTAINER_NAME $IMAGE_NAME#删除Dockerfile文件rm -f Dockerfile

再次点击立即构建按钮

出现构建失败错误docker not found,说明jenkins容器中无法执行docker命令,网上搜了一下,主要解决方案有以下几种:

1.不使用Jenkins镜像,直接在宿主机上安装Jenkins服务,可以调用宿主机上的docker命令.

2.使用dood方案:表示在docker容器中使用宿主机上的docker服务.

3.使用dind方案:在docker镜像中要再安装docker服务,此时在容器中的docker和宿主机的docker是两个不同的程序,相互没有关联.

4.使用https与docker后台程序通讯,通过https暴露socket,并且可以使用宿主的镜像,但因为打开了端口增加了攻击面,可以说是最不安全的.

下面我们使用第2种方案即dood来解决这个问题.

1.先删掉之前建好的jenkins容器和镜像,然后在虚拟机上创建一个空的Dockerfile文件.

[root@bogon jenkins-dood]# touch Dockerfile

2.编写Dockerfile脚本

[root@bogon jenkins-dood]# vi Dockerfile

FROM jenkins:latestUSER rootARG dockerGid=999RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/groupUSER jenkins

3.重新构建jenkins镜像

[root@bogon jenkins-dood]# docker build-t jenkins.

4.在启动Jenkins容器时,我们需要先创建一个Jenkins的配置目录,并且挂载到docker 里的Jenkins目录下.

[root@bogon/]# mkdir-p/opt/jenkins-dood

5.修改目录权限.

[root@bogon/]# chown-R1000/opt/jenkins-dood

6.开始运行jenkins容器

[root@bogon/]# docker run \>-d \>-p38080:8080\>-p50000:50000\>--name jenkins \>-v/var/run/docker.sock:/var/run/docker.sock \>-v $(which docker):/bin/docker \>-v/opt/jenkins-dood:/var/jenkins_home \>-u root \>--link gitlab:gitlab.william.com \>jenkins:latesta5904b8c7f50234b52c3772ab13cca4d61f02cb887e0524ff4f6cf53bb63b501

注意这两个-v参数(将jenkins容器内的docker命令指向了宿主机):

-v /var/run/docker.sock:/var/run/docker.sock

-v $(which docker):/bin/docker

之后直接在jenkins里面就可以使用docker命令了.同样的启动jenkins容器后找回管理员密码:

cat /opt/jenkins-dood/secrets/initialAdminPasswordd1291723c28848cda642d8ba8351e439

进去系统后先修改jenkins时间设置:打开【系统管理】->【脚本命令行】运行下面的命令:

System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')

其他的配置步骤跟我们之前配置的一样.编写完自动部署脚本之后,我们同样执行立即构建,这个时候报错了:

根据错误日志提示可知:找不到libltdl.so.7这个文件,网上搜了一下,在jenkins容器启动命令增加文件映射-v /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7.重新构建,这次报另一个错误:

原因是centos7上没有装libltdl.so.7这个library,我们通过下面这个命令来安装:

[root@bogon /]# yum install libltdl.so.7

安装完之后找到安装的位置:/usr/lib64/libltdl.so.7,接着再重启jenkins容器:

[root@bogon/]# docker run \>-d \>-p38080:8080\>-p50000:50000\>--name jenkins \>-v/var/run/docker.sock:/var/run/docker.sock \>-v $(which docker):/bin/docker \>-v/opt/jenkins-dood:/var/jenkins_home \>-v/usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7>-u root \>--link gitlab:gitlab.william.com \>jenkins:latest

再次执行jenkins构建,这回构建成功了,执行docker images查看一下jenkins自动部署的镜像.

[root@bogonbin]# docker imagesREPOSITORYTAGIMAGEIDCREATEDSIZE192.168.56.101:5000/hello/hello9231daf17317c18hours ago673MB192.168.56.101:5000/hello/hello7c9b2c721e7e118hours ago673MB192.168.56.101:5000/hello/hello629b676b8d27319hours ago673MB192.168.56.101:5000/hello/hello5f1bdfbf7977e20hours ago673MBjenkins                              latest              cfa26ddfdfaa24hours ago696MBgitlab/gitlab-ce                      latest              d87e1ba8aa5f7days ago1.46GB192.168.56.101:5000/hello/hello-api1.0.068bbcea2575f7days ago673MBnginx                                latest              c8252167658013days ago109MBjenkins<none>cd14cecfdb3a2weeks ago696MBregistry                              latest              b2b03e9146e14weeks ago33.3MBjava8d23bdf5b1b1b18months ago643MB

测试jenkins自动发布的容器是否正常运行

[root@bogonbin]# curl http://192.168.56.101:58080/hello/hihi

[root@bogonbin]#

返回结果为"hi",说明jenkins已经可以正常从gitlab中获取源码来构建生成docker镜像并以docker容器的方式进行发布,供生产环境使用了.但目前还是以手动的方式来执行构建任务,我们真正需要的是一款自动化的发布平台,在开发人员将源代码推送至gitlab后自动触发jenkins构建任务,再次打开构建配置,回到构建触发器配置:

选中Poll SCM,Poll SCM表示定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作.如果需要每隔30分钟检查一次源码变化,有变化就执行则可以在日程表中输入一个基于CRON表达式,比如:H/30 * * * *表示每30分钟执行一次构建.我们来测试一下,在idea中修改测试代码将原来的返回值"hi"改为"hello world",然后push到gitlab中,观察jenkins是否会自动构建.

从上图中我们可以看到jenkins已经开始自动构建了.

最后再来验证下自动化发布的结果.

[root@bogonbin]# curl http://192.168.56.101:58080/hello/hihello world[root@bogonbin]#

返回结果为"hello world"说明jenkins已经成功自动构建并部署了.

参考资料:

https://www.jianshu.com/p/ee4a2a9e7e30

https://www.2cto.com/net/201909/816570.html

https://www.jianshu.com/p/b1f856646296

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容