环境准备
持续集成工具:Jenkins
代码托管:Gitlab
构建工具:Maven
审查工具:SonarQube、SonarQube Scanner
发布容器:Tomcat
思路简介
1.jenkins通过SSh把编译好的war包传输到tomcat远程服务的临时文件夹;
2.执行脚本,检查远程服务器的tomcat是否启动,如果启动,则关闭;
3.关闭tomcat后,将临时文件中的war包转移到tomcat的webapps目录下,启动tomcat。
jenkins系统设置-Publish Over SSH
jenkins将编译好的项目发布到远程tomcat,首先要做的就是jenkins服务器能够通过ssh免密码登录tomcat服务器,进行传输文件及执行Shell命令
1.在jenkins服务器下生成公钥/私钥对
[root@cicd ~]# ssh-keygen -t rsa
2.查看生成的公钥/私钥对
[root@cicd ~]# cd /root/.ssh
[root@cicd .ssh]# ll
3.把jenkins服务器下的id_rsa.pub复制到tomcat服务器下的/root/.ssh/目录下
[root@cicd .ssh]# scp -r id_rsa.pub [email protected]:/root/.ssh/
检查文件是否传输到tomcat服务器
4.在tomcat服务器上,将公钥(id_rsa.pub)复制到/.ssh/authorized_keys中(起到备份的作用)
[root@mysql02 .ssh]# cat id_rsa.pub >> ~/.ssh/authorized_keys
而且要确保authorized_keys的权限至少是600
[root@mysql02 .ssh]# chmod 600 authorized_keys
5.测试免密登陆
[root@cicd .ssh]# ssh 10.255.29.28
至此,jenkins服务器可以免密向tomcat服务器传输文件及执行Shell命令
6.配置Publish Over SSH
Passphrase:SSH的password
生成私钥/公钥对的时候,输入的密码;如果没有创建密码,可以忽略
Path to key:SSH私钥的文件路径
可以是绝对路径。也可以是相对$JENKINS_HOME的相对路径
Key:私钥导出后的文本内容
SSH Server Name:SSH节点配置的名称。在Job中使用Publish over SSH插件时,此名称将出如今“SSH Server”中“Name”的下拉列表中,例如:
Hostname:通过SSH连接到的机器的主机名或IP
Username:SSH服务使用的username,使用key进行连接时为key指定的username
Remote Derictory:运程机器上真实存在的文件夹,而且“Username”指定的用户要有訪问此文件夹的权限,插件将把文件传送到此文件夹下。
创建项目以及构建配置
1.构建一个maven项目,并填写一个名称
2.General
3.Source Code Management
这里就不赘述jenkins如何集成gitlab,可以参考https://blog.csdn.net/weixin_43840640/article/details/88719485
4.Build
5.Post Steps
6.Post-build Actions
Transfer Set Source files:填写jenkins服务器要传输的文件和文件夹,格式:target/*.war
Remove prefix:移除目录(只能指定Transfer Set Source files中的目录)
如果该处不填,则构建后的war包相对于远程目录Remote directory的相对路径为 target/.war (实际上“”为maven构建的war包名称)
如果此处填了,比如我填了target,那么构建后的war包相对于远程目录Remote directory的相对路径为 .war (实际上“”为maven构建的war包名称)
Remote directory:远程目录
Exec command:要执行的命令或者shell脚本写在里面
脚本:
#!/bin/bash
#关闭tomcat
pidlist=`ps -ef|grep tomcat|grep -v "grep"|awk '{print $2}'`
function stop(){
if [ "$pidlist" == "" ]
then
echo "----tomcat 已经关闭----"
else
echo "tomcat 进程号 :$pidlist"
kill -9 $pidlist
echo "KILL $pidlist:"
fi
}
stop
pidlist2=`ps -ef|grep tomcat|grep -v "grep"|awk '{print $2}'`
if [ "$pidlist2" == "" ]
then
echo "----关闭tomcat成功----"
else
echo "----关闭tomcat失败----"
return 1
fi
#移除原来tomcat中的webapps中的项目文件夹
rm -rf /opt/tomcat/webapps/ROOT*
#复制jenkins生成的war包到tomcat中的webapps中,并修改war包的名称
cp -rf /opt/tmp/scm-tomcat-0.0.1-SNAPSHOT.war /opt/tomcat/webapps/ROOT.war
sleep 10s
#启动tomcat
echo "starting tomcat"
cd /opt/tomcat/bin
./startup.sh
构建
控制台输出结果:
tomcat服务器:
部署过程中遇到的坑
1.在执行脚本时,tomcat总是启动失败,并且提示“已杀死”,尝试了多种方法,对代码先做减法,再做加法,确定代码能够检测到tomcat的进程号,但是无论tomcat是否启动,都会执行关闭tomcat的动作。最后,我们发现脚本的名称是“tomcat.sh”,它本身也是一个tomcat进程,把脚本的名称更换为“start.sh”后,脚本执行成功。
2.我在这里遇到了两个坑
第一坑:Transfer Set Source file
这里填写的是相对于Jenkins服务的工作区而言的相对路径,例如:Jenkins的工作区设置为 /var/lib/jenkins/workspace/,存放war包的路径是/var/lib/jenkins/workspace/scm-ssh/target/scm-tomcat-0.0.1-SNAPSHOT.war,只填写target/*.war即可。我这里填写的是war包的绝对路径/var/lib/jenkins/workspace/scm-ssh/target/scm-tomcat-0.0.1-SNAPSHOT.war,导致系统识别不出war包,传输失败。
第二坑:Remote directory
如果不填写,则将Jenkins服务器打的war包拷贝到远程默认的Remote directory目录(系统设置中SSH Server的 Remote directory)
如果填写,比如我填写的为jenkins_war,则将Jenkins服务器打的war包拷贝到远程的Remote directory目录下的jenkins_war 目录下,即该路径是相对于系统配置的远程Remote directory目录的相对路径