这里代码仓库使用gitlab。在介绍如何通过gitlab和jenkins进行自动化部署之前,需要先安装完成gitlab以及jenkins。两种程序的安装方式以及相关配置可以参看以下内容:
linux中安装gitlab:linux安装极狐gitlab
linux中安装jenkins:linux安装jenkins
部署jenkins的服务器上,还需要部署完毕对应的git和maven,用来进行代码拉取以及打包操作。git和maven的安装就不在文章中进行赘述了。
创建一个springboot的web项目,具体创建流程不在说明。项目创建完成后,创建一个接口outputA,作用是直接返回字符串AAA。
package com.example.jenkinstest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class TestController {
@GetMapping("/outputA")
@ResponseBody
public String outputA() {
return "AAA";
}
}
另外修改配置文件application.properties,将项目端口改为9000
server.port=9000
完成上述操作后,从ide运行项目,如果项目运行没有错误,就可以继续下述步骤的操作了。
接下来,我们把能正常运行的代码,提交至之前从自建的gitlab中创建的项目内
首先要进入到自己的项目路径下,打开命令行工具,然后根据gitlab的初始化提示,执行对应的命令
如果在执行命令的时候出现了该错误:error: unknown option `initial-branch=main’
则可以使用下述命令进行处理
git init
git checkout -b main
git remote add origin https://192.168.220.105/gitlab-instance-d6b15872/jenkinstest.git
git add ./*
git commit -m "初始化提交"
执行完毕后,从gitlab页面上就可以看到提交的内容了
接下来,我们从jenkins服务器上先直接通过git拉取代码并且使用maven进行打包并且运行jar包,以此来保障后续的操作可以顺利进行。首先我们先从服务器上拉取gitlab仓库的代码
git clone https://192.168.220.105/gitlab-instance-d6b15872/jenkinstest.git
遇到了一个报错信息
fatal: unable to access 'https://192.168.220.105/gitlab-instance-d6b15872/jenkinstest.git/': Issuer certificate is invalid.
这种错误是由于通过HTTPS访问Git远程仓库的时候,如果服务器上的SSL证书未经过第三方机构认证,git就会报错。因为未知的没有签署过的证书意味着可能存在很大的风险。可以通过关闭SSL验证解决。
git config --global http.sslVerify false
重新执行克隆命令,然后就可以执行成功了。
而后进入到拉取下下来的目录中,使用maven进行打包
cd jenkinstest/
mvn clean package
打包完成后,会得到一个target包,进入到target包后,直接前台执行jar包
cd target/
java -jar jenkinstest-0.0.1-SNAPSHOT.jar
通过浏览器打开页面,访问http://192.168.220.105:9000/outputA,如果页面正常显示,则代表jenkins服务器上的git和maven以及jdk等都是配置无误的。
上述流程都走通后,我们就开始准备配置jenkins,由jenkins代替我们手动进行代码拉取以及打包的操作。
如果gitlab和jenkins在同一台服务器上,由于gitlab 10.6版本以后为了安全,默认不允许向本地网络发送webhook请求,如果想要向本地网络发请求的话,我们需要配置gitlab允许对本地网络发起请求。
需要使用管理员账户登录gitlab,然后点击左上角gitlab图标右侧的图标,选择管理员
然后在跳转的页面中,选择左侧的设置,然后点击网络
从跳转的页面中,选择出站请求,然后勾选 允许来自 web hooks 和服务对本地网络的请求 的按钮
首先需要为jenkins标明git、maven等程序的位置。
我们先从jenkins安装一些插件,方便我们与gitlab进行集成
在这里我们先安装三个必要的插件
gitlab
集成gitlab。这个插件允许 GitLab 触发 Jenkins 构建,并在 GitLab UI 中显示它们的结果。
Maven Integration
jenkins与maven的集成使用。
Gitlab Authentication
用于gitlab的认证。
Publish Over SSH
通过ssh传送文件。
打开jenkins首页,选择新建任务或者Create a job都可以
接下来需要填写任务名称和任务处理内容,这里由于之前安装了maven插件,且示例项目也是使用的maven,因此选择构建一个maven项目
接下来需要填写对应的git项目地址、gitlab认证方式以及对应的分支信息
如果之前没有全局配置过认证信息,那么可以直接点击添加按钮进行添加,这里我直接使用gitlab的用户名和密码进行认证
这里有个地方需要注意,如果是填入了gitlab地址,并且用户密码都没有问题,但是仍然提示
stderr: fatal: unable to access 'xxx': Issuer certificate is invalid.
这种错误信息,如下图所示
那么就需要去把jenkins用户修改成root用户进行启动,或者直接在jenkins服务器上使用以下命令
git config --system http.sslverify false
如果都没有出现错误提示,则可以继续向下配置
输入maven打包命令
选择只有构建成功才执行后续操作
到这里,我们先进行保存,然后执行下构建,看能否正常进行代码拉取和打包操作。
点击最下方的保存后,选择左侧的立即构建。
点击对应的编号就可以查看详情
选择控制台输出选项,就可以查看对应的日志。等执行完成后,可以看到
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:17 min
[INFO] Finished at: 2023-02-11T19:18:20+08:00
[INFO] ------------------------------------------------------------------------
Waiting for Jenkins to finish collecting data
[JENKINS] Archiving /var/lib/jenkins/workspace/jenkinstest/pom.xml to com.example/jenkinstest/0.0.1-SNAPSHOT/jenkinstest-0.0.1-SNAPSHOT.pom
[JENKINS] Archiving /var/lib/jenkins/workspace/jenkinstest/target/jenkinstest-0.0.1-SNAPSHOT.jar to com.example/jenkinstest/0.0.1-SNAPSHOT/jenkinstest-0.0.1-SNAPSHOT.jar
channel stopped
Finished: SUCCESS
这时候我们从服务器上,看一下对应的目录中是否有日志里边的 /var/lib/jenkins/workspace/jenkinstest/target/jenkinstest-0.0.1-SNAPSHOT.jar 文件
可以看到,的确构建出了对应的jar包。
我们先实现一个功能,将生成的jar包放置到项目目录中,然后启动对应的jar包,并且通过浏览器进行访问。
假如我们的项目想要放置在/home/project/jenkinstest中。我们先找到post steps,选择Run only if build succeeds,也就是构建成功后才执行,然后点击 add post-build step,选择调用shell
然后在框体内写入
APP_PID=`ps -ef|grep jenkinstest-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $2}'`
if [ $APP_PID > 0 ]
then
kill -9 $APP_PID
fi
rm -rf /home/project/jenkinstest/*.jar
cp /var/lib/jenkins/workspace/jenkinstest/target/jenkinstest-0.0.1-SNAPSHOT.jar /home/project/jenkinstest/
cd /home/project/jenkinstest/
nohup java -jar jenkinstest-0.0.1-SNAPSHOT.jar >./start.log 2>&1 &
保存后重新执行构建,从jenkins的控制台输出中可以看到以下内容
而后打开网页,输入对应的ip:9000,我这里是http://192.168.220.105:9000/,可以看到项目已经启动成功了
在上述步骤中,我们是通过jenkins编译完成后,直接在服务器上启动对应的jar包,从而开启web服务。然而在实际使用的时候,应用服务器和jenkins服务器是分开的,因此我们需要实现一个功能,那就是在jenkins编译完成以后,我们把编译出来的jar包分发到应用服务器上,而后启动对应的jar包。
接下来就实现该功能。想要实现该功能,jenkins里就需要用到Publish Over SSH插件,在安装插件中也已经提到了该插件。另外这里把192.168.220.106作为应用服务器。
首先登录部署了jenkins的服务器,执行ssh-keygen命令,都直接回车即可。
[root@localhost ~]# ssh-keygen
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:sqM1UfKjKBU1G3XP18q1VH0cu3Ob5dAHA3pV/FYJM4E [email protected]
The key's randomart image is:
+---[RSA 2048]----+
| +.. . o=+=*|
| . + . E oooO|
| . o . . + +o*|
| . + . o.*=|
| . o S +==|
| . . = . oB|
| . . * o.|
| . o o |
| . |
+----[SHA256]-----+
执行完成后,就会在/root/.ssh/目录下方生成对应的文件
[root@localhost ~]# ls /root/.ssh/
id_rsa id_rsa.pub
这时候,我们可以把 id_rsa.pub 中的内容复制到jenkins所在服务器(192.168.220.105)要连接的应用服务器(192.168.220.106)对应的用户或root用户目录的.ssh目录下,这里我们直接放置到应用服务器(192.168.220.106)root用户目录下的.ssh目录中。
如果应用服务器还没有初始化ssh目录,也可以先执行下ssh-keygen命令。
因为我的应用服务器中root用户目录下的.ssh目录中还没有authorized_keys这个文件,因此就直接把jenkins服务器的id_rsa.pub复制一份名称改为authorized_keys,然后直接传送到106应用服务器上,如果大家的应用服务器已经存在了authorized_keys文件,那么需要注意将文本追加进去即可,不要直接覆盖文件。
cd /root/.ssh/
cp id_rsa.pub authorized_keys
接下来使用scp命令,将authorized_keys直接传送到应用服务器(192.168.220.106)中
# 下述命令的含义是将authorized_keys文件传送到106服务器的/root/.ssh目录中,登录用户使用root
# scp 要传递的文件 目标服务器用户名@目标服务器ip:要放置的目录
scp authorized_keys [email protected]:/root/.ssh
输入完成106服务器root用户对应的密码,没有错误后就会将文件传递到106应用服务器的目录下了
打开系统管理的系统配置,然后找到Publish Over SSH
点击SSH Servers下方的新增按钮
接下来,我们配置jenkins编译完成后将文件传输到应用服务器上。
打开之间从jenkins创建的任务,先选择新增一个执行操作,用来向应用服务器传输文件
而后填写对应内容
# 远程执行的脚本
APP_PID=`ps -ef|grep jenkinstest-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $2}'`
if [ $APP_PID > 0 ]
then
kill -9 $APP_PID
fi
rm -rf /home/project/jenkinstest/*.jar
mv /home/jenkins_putfile/jenkinstest-0.0.1-SNAPSHOT.jar /home/project/jenkinstest/
cd /home/project/jenkinstest/
nohup java -jar jenkinstest-0.0.1-SNAPSHOT.jar >./start.log 2>&1 &
上述配置填写完成后,我们将之前配置的本地执行的shell操作删除掉,最后保存操作。
执行构建,可以看到命令如果顺利执行的话,会提示一个文件传输成功。
这时候打开106服务器,会发现对应目录下已经有了对应的jar包,而且也可以访问对应的服务。
在上述的例子中,都是通过手动点击构建进行的,接下来要实现一个功能,那就是在代码出现新的推送(push)以后,自动触发构建操作。
打开之前从jenkins创建的任务,找到构建触发器,然后选中Build when a change is pushed to GitLab选项,复制下来后面的GitLab webhook URL地址,后面需要配置到gitlab对应的项目中。在我这里是:http://192.168.220.105:8090/project/jenkinstest
而后点击高级,找到Secret token然后点击Generate进行生成
这时候先不要关闭页面或者保存,先打开gitlab中对应的项目,在设置中找到webhooks然后进行配置
接下来配置触发规则,这里直接默认选中所有分支,如果不同分支需要对应不同的jenkins任务,则可以通过通配符或者表达式进行对应,然后创建多个webhook即可。
配置完毕后,点击下方的添加webhook按钮,就可以看到新增的内容了
回到jenkins中,对刚才的配置进行应用及保存。而后在gitlab中点击测试,选择推送事件,回到jenkins中,就可以看到触发构建任务了。
我们在实际开发中,往往不会直接向主分支提交代码,一般的流程都是从自己的开发分支上进行代码开发,而后合并到测试分支进行测试,测试没有问题后才会合并到主分支上。接下来将实现该流程下的自动创建。
先修改下之前配置的webhook规则,只有main分支出现push的时候,才触发webhook。
而后修改下jenkins的配置,去除掉Opened Merge Request Events,目的是防止提交合并请求的时候就直接触发了构建操作。
最后我直接从gitlab对应的项目上创建一个test分支,然后使用gitlab的web ide直接从test分支进行一些修改,合并到主分支。
将原本/outputAAA接口直接返回的字符串AAA改为outputAAA,保存修改后,发起合并请求,将test分支合并到main
接下来进行代码合并,将test分支合并到main
接下来处理提交的合并请求
而后jenkins就会开始触发构建操作,等待构建完成后,打开页面进行访问,可以看到显示的内容已经变成了outputAAA。