本文使用SpringBoot项目完成一个简单的Jenkins实践,利用docker-maven插件实现Docker从build到run再到push的完整流程,大大简化了Jenkins相关工作,不必再为Jenkins配置证书和编写额外的脚本.
简化的关键在于fabric8io的docker-maven-plugin插件,利用它可以实现用maven指令对docker远程控制,网上其他文章的思路大多是利用spotify的maven插件完成docker镜像的build和push,再编写脚本文件,让Jenkins通过SSL在docker主机上远程执行脚本,达到在远程主机运行docker容器的目的.
这种做法第一是太麻烦,远程执行脚本需要配置SSL免密码访问,第二是SpringBoot项目和脚本耦合度高,由于镜像是在SpringBoot的插件完成相关构造的,而脚本其实就是死代码,必须人为地保证两者的统一协调.
而使用fabric8io的docker-maven-plugin则可以完整地控制docker镜像/容器的生命流程,从而避开这些问题.当然,用脚本自由度会比较高,可以做其他的事情,这个见仁见智.
以下是关于docker远程控制和插件使用的两篇文章:
Docker 守护进程+远程连接+安全访问
最强大的Docker插件 fabric8io/docker-maven-plugin
另外,Jenkins跑起来是比较耗资源的,如果Jenkins运行时突然挂掉,那多半是因为内存不足.我是使用docker来运行Jenkins的,有时候它还会把别的docker容器给挤挂了,无奈下只能另买一台阿里的学生机供Jenkins使用
如下图,是对Jenkins容器的单独监控,可以看到工作时运行内存占用在1.2G左右,这还只是在Docker内部,如果docker还有其他的容器在运行,再加上linux其他的服务,其实内存很容易就不够用的,另外,即使不挂,内存不够的情况下也可能导致Jenkins内部的任务执行出错,这种错误往往来得很莫名其妙,下文遇到的时候再介绍.
我使用的是docker部署,指令如下
docker run -p 9003:8080 -p 9004:50000 -v /opt/docker-volume/jenkins2:/var/jenkins_home -u root --name lin_jenkins -d jenkins/jenkins:lts
这里需要注意的是,jenkins/jenkins:lts并不是默认的官方镜像,官方镜像已经被废弃(deprecated )了,jenkins在Docker Hub的镜像首页推荐使用jenkins/jenkins:lts.
另外,因为Jenkins会产生比较多的文件(比方说一些插件和运行环境)在/var/jenkins_home目录下,所以建议将这个目录挂载出来
接下来登录 IP:9003 就可以访问Jenkins了
cat /opt/docker-volume/jenkins2/secrets/initialAdminPassword
就可以获取密码,复制粘贴点继续“系统管理”->”全局工具配置”
因为是在docker内,使用外部系统的JDK和Maven等工具比较麻烦,所以我这里直接使用自动下载,这里需要自己选定配置的工具有JDK,Git,Maven
注意,全局工具只有在第一次用到的时候才会去下载,以Maven为例,如果含”mvn”命令的shell脚本在第一次”调用顶层Maven目标”之前执行,则会报“sh: mvn: not found”错误
1. JDK
我选用的是JDK8,注意自动安装JDK的话需要Oracle账号
2. Git
3. Maven
最后记得点 Save保存
“系统管理”->”插件管理”
先点击”可选插件”,再通过右上角的”过滤”来筛选,这里我们需要安装两个插件,GitLab,Maven Integration
“系统管理”->”全局安全配置”
关闭防止跨站点请求伪造,原因如下:
webhooks与jenkins配合使用时提示:HTTPStatus403-Novalidcrumbwasincludedintherequest,这是因为jenkins在http请求头部中放置了一个名为.crumb的token。在使用了反向代理,并且在jenkins设置中勾选了“防止跨站点请求伪造(Prevent Cross Site Request Forgery exploits)”之后此token会被转发服务器apache/nginx认为是不合法头部而去掉。导致跳转失败。
“系统管理”->”系统设置”
这里主要是设置”全局属性”中的”环境变量”
这里我们要设置的环境变量是Maven,如果环境变量没有设置好的话,会导致在非Maven任务(如自由风格任务)的时候使用shell命令是提示找不到mvn指令(Cannot run program “mvn” error=2, No such file or directory),或者是找不到其他的指令也是同理
另外,虽然上一步已经设置好Maven工具,但现在还没有下载,可以通过运行任务时在Maven顶级目录调用-v
查看,这里我直接给出路径,前面的路径是一样的,后面的是安装时候给的Maven名
/var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/MyMaven
环境配置如下图,就是增加了Maven的目录,再将maven目录下的bin添加到原Path里,使bin下的mvn指令可以在Path找到,就可以执行了
Path的值为:(用冒号而不是分号分隔)
$Path:$MAVEN_HOME/bin:
很多教程都有配这个,但这个又不能用于”源码管理”模块拉取代码,我一直很困惑这个配置有什么用,然后就找到了该插件的github项目地址才弄明白,链接:https://github.com/jenkinsci/gitlab-plugin
上面说了”GitLab”插件的作用是当gitlab有push时触发jenkins拉取代码和将构建状态发送回GitLab,这分别对应了两种状态:GitLab-to-Jenkins和Jenkins-to-GitLab,这里就是配置对应的授权信息的
第一是Enable authentication for ‘/project’ end-point
这个打个勾就可以了,它是负责GitLab-to-Jenkins身份验证的开关,如果这里关闭的话,任何人只要知道你项目的钩子地址(webhook URL)就可以疯狂触发任务,而且通常webhook URL又是按规则生成的,很容易猜,不安全,所以不建议关闭身份认证.
另外,身份认证有两种,全局认证和每个项目认证,全局认证并没有减轻多少工作量(毕竟每个项目的webhook URL不能一样),而且还会带来全局密码泄露的风险,所以通常用的都是项目单独认证.感兴趣的可以去上面给的gitlab插件项目地址看使用说明.
第二就是GitLab connections
这里提供的是Jenkins-to-GitLab身份验证,此身份验证配置仅用于访问GitLab API以将构建状态发送到GitLab。它不用于克隆git repos
。克隆凭证(通常是SSH凭证)应该在git插件中单独配置。
返回首页,选择”创建一个新任务”,如下,这里我们创建的是一个自由风格的项目,也可以选择maven项目(这是由于我们上面装的插件才有的),maven项目会配置好Maven环境变量,也就是说可以在shell运行”mvn”指令而不需要我们上面的环境变量配置,选定好确认进入
源码管理选择Git
注意,这一部分要根据自己项目的功能来.需要注意的是,如果构建步骤里需要运行程序,那Jenkins会认为程序的运行也是构建的一部分,简单来说,就是运行个Java Web服务,由于程序一直不结束,所以构造也一直不会停止.
解决办法是保证成后台运行,并用BUILD_ID=dontKillMe避免构建结束时进程被杀.
以使用fabric8io的docker-maven插件为例:
相关使用见:
Docker 守护进程+远程连接+安全访问
最强大的Docker插件 fabric8io/docker-maven-plugin
这里我们分两部分来,因为run
比较特殊,把它单独放在第二部分
clean package docker:stop docker:remove docker:build docker:push
BUILD_ID=dontKillMe
nohup mvn docker:run &
如果只是想尝试一下运行,不使用docker相关的话,则直接用shell运行如下指令即可
BUILD_ID=dontKillMe
nohup mvn clean package spring-boot:run &
保存就可以了
可以在工程主页点立即构建,或者在GitLab的Webhooks那里点Test,选择Push events,第一次为了验证和GitLab的连接,就用第二种方式吧
然后就可以了,第一次拉取代码会比较花时间,而且可能失败.
(默认)
,英文是(Default)
,都是有括号的)而没有选择你自己配置的BUILD_ID=dontKillMe
,注意,如果Jenkins Pipeline使用JENKINS_NODE_COOKIE而不是BUILD_ID.同时,该进程不能是在前台运行的,可以通过daemonize 来包装成守护进程,但这需要额外安装,我使用的方法是用nohup + 指令 + &.参考:
https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller
https://wiki.jenkins.io/display/JENKINS/Spawning+processes+from+build
https://github.com/jenkinsci/gitlab-plugin
https://blog.csdn.net/wangbin0016/article/details/41948171
Docker 守护进程+远程连接+安全访问
最强大的Docker插件 fabric8io/docker-maven-plugin