使用Jenkins部署SpringBoot应用

Jenkins 是基于Java开发的一个可扩展的持续集成引擎,主要用于持续继承,自动化的构建或测试软件项目,并且易于安装部署,带有方便的可视化web界面进行配置管理,将运维人员从大量繁杂的部署工作中解放出来。Jenkins支持分步式构建,可以使得配置好的多个节点同时构建。能够通过安装插件,进行功能上的扩展。总之Jenkins是一个强大的持续集成应用,是DevOps工具的一大利器。本文主要介绍Jenkins的安装及使用,给还未了解的童鞋提供一些帮助。

1. 前提环境

首先来说下我们需要的环境,我们要发布的是一个前后端分离的项目。这里我们使用一台主机发布Jenkins应用,同时在这台主机上进行项目代码的拉取,编译,打包。使用另外一台主机作为我们的UAT环境来发布最新的应用程序。
1. CentOS7 Jenkins应用发布服务器
注:配置好Java运行环境,安装好Maven,同时需要安装好Git客户端,NodeJs(这里我的应用需要NodeJs打包,所以我们安装了NodeJs的环境,如果你不需要NodeJs,可以忽略。)
2. CentOS7 项目部署服务器
注:配置好Java运行环境,安装好Nginx(我们采用Nginx发布我们的前端应用,并且我们将前后端放在同一台主机上)

这里两台主机上需要的软件,Java,Maven,Git通过yum下载也是很方便的,这里简单提一下:

安装java环境

yum install java
查看版本
java -version

安装Git

yum install git
查看版本
git version
初始化设置
git config --global user.name "xxx.sun"
git config --global user.email "xxx.sun@xxx.com"

安装配置maven

Maven官网地址:http://maven.apache.org
找到下载地址: apache-maven-3.5.3-bin.zip 复制下载链接
cd /root
wget http://下载链接
unzip apache-maven-3.5.3-bin.zip

配置maven
pwd 查看maven全路径,复制。
vim /etc/profile
export MAVEN_HOME= 全路径
export PATH=$MAVEN_HOME/bin:$PATH
保存配置,并重新加载配置
. /etc/profile
查看版本
maven -version


2. Jenkins安装

Jenkins的安装还是非常方便的,下载,启动,配置。

免费下载安装

官网地址:http://jenkins.io
找到Download,并且选择我们要安装的平台版本,复制下载链接。
这里我们选择 Download Jenkins 2.137 for: Generic Java package (.war)的版本。
接着在我们的CentOS系统中下载:
cd /opt
wget http://mirrors.jenkins.io/war/latest/jenkins.war

启动:Jenkins

只要配置好Java环境,可以直接通过命令启动Jenkins
java -jar jenkins.war

初始化Jenkins

  1. 启动好之后,我们可以通过这个地址来访问:http://localhost:8080,接下来要做的是初始化密码。
    Jenkins初始化
    按照给的提示,打开指定的文件/root/.jenkins/secrets/initialAdminPassword,复制文件里初始化密码ea634806888141f38fd3ed42cf63def1填在这里。
  2. 接下来我们这里选择推荐安装社区推荐的插件选项,Jenkins会自动进行安装
    Jenkins安装插件
  3. 创建admin账户,保存完成,安装成功。
    Jenkins创建用户
  4. 这时我们就可以看到我们安装的Jenkins实例地址了。
    Jenkins实例地址

登陆

Jenkins登陆页面
Jenkins首页

安装插件

这里我们选择安装两个插件,点击导航中的:系统管理-插件管理-可选插件,
搜索下面的两个插件并安装:
1. Rebuilder(重新构建)
2. Safe Restart(安全的重启Jenkins)

基础设置

依次点击导航菜单中的 系统管理-全局安全配置
全局安全配置里面的授权策略默认是“登录用户可以做任何事”,而我们想要按照用户或者用户组动态的分配权限,因此我们要勾选“项目矩阵授权策略”
并添加“用户或用户组”,这里我们添加我们的superadmin账号,并授权全部权限。
Jenkins授权

添加自定义用户

系统管理-管理用户-新建用户
这里我们可以创建新的Jenkins登陆用户,并在上一步的全局安全配置中,为用户授权。


3. 将Linux节点注册到Jenkins上

配置节点

在我的例子中,实际上是在当前的master主机上打包,并复制到远程主机,并不是直接在远程主机上打包并运行,因此对于这个例子来说添加节点并没有什么作用,但是在实际使用过程中,还是会在远程节点上拉取代码并部署,因此在这里说下添加节点还是有必要的。在导航菜单中依次点击 系统管理-节点管理-新建节点,
1. 填写节点名称,勾选“固定节点”选项
2. 配置远程工作目录:/root/.jenkins
3. 启动方法修改为:Launch slave agents via SSH,表示将通过SSH与主机通信
4. 输入IP,Credentials,选中填写的凭证并保存。
5. 修改“Host Key Verification Strategy”的选项为“Non verifying Verification Strategy”,否则在启动代理的时候会报如下警告并认证失败:

WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file.

保存好节点,回到节点列表我们来尝试连接:单击节点,点击Lanch Agent或者启动代理来测试是否连接成功。
Jenkins添加节点

同时我们也可以在节点的配置中,增加我们需要的环境变量:
Jenkins节点环境变量


4. 发布Spring Boot应用

  1. 导航菜单 选择 创建新任务-构建一个自由风格的软件。
  2. 勾选“限制项目运行的节点”,同时,在下面的标签表达式(Label Expression)中输入选中我们要在哪一个节点上运行。当然因为我们的前后端项目都要在Jenkins应用服务器上打包编译,所以我这里直接选择master。
  3. 在源码管理的位置,我们要填上项目远程仓库的地址,以及分支,分支后面我们也可以随时的进行切换:
    Jenkins源码管理
  4. 接着在下面构建的执行Shell(Executes shell)一栏中输入我们要执行的shell指令,保存就可以了。脚本比较多,我们将shell脚本放在第5部分来展示。
  5. 我们点击立即构建,就可以看到我们的项目已经开始构建,它会在第二步配置的节点上,拉取我们配置的远程仓库的分支代码,执行上一步我们输入的shell指令并完成。这样,如果控制台输出没有给出error的话,那么我们的应用也就发布成功了,可以通过应用访问的地址去验证一下。

5. 示例代码:

分享部署的两个shell脚本:
1.首先是前端项目的部署脚本,Jenkins中,我们前端项目构建配置的shell如下:

cnpm install 
npm run build-uat

#cd dist
#cp -r ./ /usr/local/nginx/html
#cd ../config/deploy/sit/
#cp -r nginx.conf /usr/local/nginx/

cd dist
scp -r ./ root@10.72.84.215:/usr/local/nginx/html-temp
cd ../config/deploy/uat/
scp -r nginx.conf  root@10.72.84.215:/usr/local/nginx/conf/

ssh root@10.72.84.215 "/opt/deploy-lms-uat-web.sh"

这段代码比较简单,主要是通过npm对前端代码进行打包,通过远程访问测试发布应用主机,来将打包文件复制过去,并执行远程主机上的指定脚本。
那么,在生产或测试环境上,我们放置一个这样的可运行的shell脚本:deploy-lms-uat-web.sh,内容如下:

#!/bin/bash

NGINXDIR=/usr/local/nginx/
TEMPDIR=/usr/local/nginx/html-temp
DIR=/usr/local/nginx/html
BACKDIR=/opt/lms/backup
DATE=$(date +%Y%m%d%H%M)

killNginx()
{
    pid=`pgrep -lo nginx|awk '{print $1}'`
	if [ "$pid" = "" ]
	then
		  echo "no nginx pid alive"
	else
		  /usr/local/nginx/sbin/nginx -s stop
	fi
}
killNginx
echo "killed nginx"

if [ ! -d "$BACKDIR/web$DATE" ]
then
   mkdir -p $BACKDIR/web$DATE
fi
echo "mkdir $BACKDIR/web$DATE"

cd $NGINXDIR
mv -fu html $BACKDIR/web$DATE
echo "backup"

if [ -d "$TEMPDIR" ]
then
   mv $TEMPDIR $DIR
fi
echo "mv html"

mkdir html-temp
$NGINXDIR/sbin/nginx -c $NGINXDIR/conf/nginx.conf

代码也比较的简单,杀掉当前的Nginx进程,创建一些目录,将之前发布的应用进行备份,并重新发布,最后启动Nginx服务,并加载Nginx的配置文件。

  1. Jenkins上的我们的第二个应用是一个Java的后端服务,同样我们配置的构建脚本如下:
    BUILD_ID=DONTKILLME
    
    DATE=$(date +%Y%m%d)
    DIR=/opt/lms
    JARFILE=lms-1.0.jar
    
    mvn clean install -Dmaven.test.skip=true
    
    if [ ! -d $DIR/backup ];then
       mkdir -p $DIR/backup
    fi
    
    if [ ! -d $DIR/web ];then
       mkdir -p $DIR/web
    fi
    
    scp target/$JARFILE root@10.72.84.215:/opt/lms/web/
    
    ssh root@10.72.84.215 "/opt/deploy-lms-uat.sh"
    

    可以看到,这里我们通过maven进行clean,以及打包,同样将打包后的jar文件,通过远程复制到目标的测试服务器,同时执行远程的shell脚本执行发布指令。
    在生产环境上,我们同样要放置一个可执行的shell脚本:deploy-lms-uat.sh

    #!/bin/bash
    
    DATE=$(date +%Y%m%d)
    DIR=/opt/lms
    JARFILE=lms-1.0-uat.jar
    killLmsJar()
    {
        pid=`ps -ef|grep $JARFILE |grep java|awk '{print $2}'`
        echo "lms.jar Id list :$pid"
        if [ "$pid" = "" ]
        then
          echo "no $JARFILE pid alive"
        else
          kill -9 $pid
        fi
    }
    killLmsJar
    
    if [ ! -f "$DIR/web/lms-1.0.jar" ]
    then
    	echo "no lms-1.0.jar can be run"
    else	
    	
    	if [ ! -d "$DIR/backup" ]
    	then
    	   mkdir -p $DIR/backup
    	fi
    
    	if [ ! -d "$DIR/web" ]
    	then
    	   mkdir -p $DIR/web
    	fi
    	
    	if [ ! -f "$DIR/web/$JARFILE" ]
    	then
    		echo "no lms-1.0-uat.jar need backup"
    	else
    		mv $DIR/web/$JARFILE $DIR/backup/$JARFILE$DATE
    	fi
    
    	mv $DIR/web/lms-1.0.jar $DIR/web/$JARFILE	
    fi
    
    /usr/software/jdk1.8.0_131/bin/java -jar -Dspring.profiles.active=uat $DIR/web/$JARFILE >> out.log 2>&1 &
    

上面是两个简单的例子,本身并不是很完善,这里只是提供一种参考,因为刚开始使用所遇到的一些问题,这几个脚本基本上都能够提供帮助。对于初次使用的童鞋还是有一些帮助的。

好了,到这里,我们看到我们每一个应用的控制台输出都正常执行,那也就表明我们的项目是发布成功了的,下次发布,直接立即构建,就可以反复的进行部署了,是不是很方便?

发表评论

电子邮件地址不会被公开。 必填项已用*标注