05.Jenkins学习笔记–集成部署环境构建
知识点
- 版本仓库选型
- 更新机制实现(更新脚本、Jenkins 配置)
- 项目更新
- 配置文件更新
- 版本回滚
- 适应不同环境(开发、测试、运维)
版本仓库选型
在整个流程中,版本仓库是非常重要的一项,用于存储版本发布所需的程序包、更新脚本、更新配置。这里我们直接采用 SVN 实现。为什么不采用 Nexus 或 Git 呢?因为 Nexus 不能存储更新脚本和配置文件,而 Git 对于测试人员和运维人员使用稍复杂,此外版本仓库只是单纯的存储,Git 的特性发挥不出来。
SVN 服务搭建
SVN 服务安装
#yum 安装
yum install subversion
#查看svnserver版本
svnversion --version
创建 SVN 版本目录
mkdir -p /data/svn/repository
svnadmin create /data/svn/repository
SVN 配置
配置目录:/data/svn/repository/conf authz:目录权限设置
cd /data/svn/repository/conf
vim authz
#--------------------------------------
#表示admin 拥有所有目录的读写权限
[/]
admin=rw
passwd:用户与密码设置
cd /data/svn/repository/conf
vim passwd
#--------------------------------------
#表示添加一个admin帐号,密码为 admin123
admin=admin123
svnserve.conf :SVN 服务
cd /data/svn/repository/conf
vim svnserve.conf
#--------------------------------------
anon-access = read
auth-access = write
password-db = passwd
authz-db = authz
realm = /data/svn/repository
启动 SVN 服务
svnserve -d -r /data/svn/repository
基于客户端访问 SVN
TortoiseSVN
下载:
https://gitee.com/zhuzhulu/java-dev-software
https://tortoisesvn.net/downloads.html
RabbitVCS
下载:
https://github.com/rabbitvcs/rabbitvcs
默认端口:3690
地址:svn://192.168.25.159:3690/
创建 test 版本仓库和 release 版本仓库
更新机制实现
更新机制是指项目如何进行实质的更新,以下介绍两种方式:一种是自动推送,另外一种是手动拉取。前者用于开发环境,后者可用于所有环境。
获取集成部署环境更新脚本:
https://gitee.com/telyfox/jenkinsDeployShell
将 services 目录放置到 /root/svr 目录下:
根据 services / bin / env-set.sh 中的以下内容:
unset JRE_HOME JAVA_HOME CLASSPATH
export nexus_redirect="http://192.168.25.159:8081/nexus/service/local/artifact/maven/redirect"
export data_home="/root/svr"
export server_home="$data_home/services"
export JAVA_HOME="$data_home/jdk"
export CATALINA_HOME="$data_home/apache-tomcat"
export CATALINA_BASE="$CATALINA_HOME"
export PATH=$JAVA_HOME/bin:$PATH
export g_env_set=true
将 JDK 和 Tomcat 配置到脚本中指定的路径下,也可以直接修改脚本中 JDK 和 Tomcat 的路径。
要修改 nexus_redirect 中的 IP 地址和端口号为自己的 Nexus 私服的 IP 地址和端口号。
手动拉取
拉取更新流程如下:
上述流程通过编写的一个 deploy.sh 脚本实现:
#!/bin/bash -e
cd "`dirname $0`"
. ./pom.sh
#1. download war, ready env
echo "deploy time: $work_time"
mkdir -p war/
war=war/$pom_a-$pom_v.war
#download_path在测试环境、预发布环境还有生产环境的时候
#可以进行相应的修改
download_path="$nexus_redirect?r=$pom_r&g=$pom_g&a=$pom_a&v=$pom_v&e=war"
wget $download_path -O $war
deploy_war
pom.sh 脚本:
#!/bin/bash -e
. ../bin/env-set.sh
#groupId
pom_g=demo.yangxu
#artifactId
pom_a=yangxu-simple-webbapp
#version
pom_v=1.0-SNAPSHOT
#snapshots or releases
pom_r=snapshots
deploy_war() {
target_d=war/${pom_a}-${pom_v}-$work_time
target_dir=`pwd`/$target_d
if [ ! -f "$war" ]; then
echo "war not exist: $war"
exit 1
fi
unzip -q $war -d $target_dir
#相关配置文件可以放在app-conf目录下
#部署时会拷贝到对应的WEB-INF/classes目录下
cp -r app-conf/* $target_dir/WEB-INF/classes/
rm -rf appwar
#通过软链接将appwar指向最新的war包解压目录
ln -sf $target_d appwar
./tomcat.sh stop
target_ln=`pwd`/appwar
echo '<?xml version="1.0" encoding="UTF-8" ?>
<Context docBase="'$target_ln'" allowLinking="true">
</Context>' > conf/Catalina/localhost/ROOT.xml
./tomcat.sh start
}
tomcat.sh 脚本:
#!/bin/bash
if [ "`whoami`" != "root" ];then
echo "Error: You must be apps to run this command."
exit 1
fi
cd "`dirname $0`"
. ../bin/env-set.sh
. ./pom.sh
export CATALINA_BASE="`pwd`"
tomcat "$1" "${pom_a}-${pom_v}"
使用前要在 services / yangxu-simple-webbapp / conf / server.xml 文件中配置 Tomcat 的相关端口号。
注:在上述 deploy.sh 脚本中还用到了 pom.sh 与 tomcat.sh,其作用后续再作说明。
在测试环境、预发布环境还有生产环境的时候 ,我们是不会直接从 Nexus 中下载的,而是特定的版本库。这时只要修改 $download_path 参数即可。
修改脚本的运行权限:
cd /root/svr/services/yangxu-simple-webbapp
chmod 755 deploy.sh
chmod 755 jenkins.sh
chmod 755 pom.sh
chmod 755 tomcat.sh
cd /root/svr/services/bin
chmod 755 env-set.sh
执行 deploy.sh 脚本:
cd /root/svr/services/yangxu-simple-webbapp
./deploy.sh
执行结果:
在浏览器中访问:
自动推送
自动推送方式采用在 Jenkins 构建完成之后,执行远程 sh 脚本用于下载本次构建的 WAR 包,再自动部署重启。
jenkins.sh 是放置在应用目录下的一个脚本:
#!/bin/bash -e
cd "`dirname $0`"
. ./pom.sh
#1. download war, ready env
echo "deploy time: $work_time"
mkdir -p war/
# 配置下载存放目录
war=war/$pom_a-$pom_v.war
# ${BUILD_URL} 是一个隐式参数,表示本次构建的 URL。
# 基于远程传过来的 BUILD_URL下载本次构建
wget "${BUILD_URL}${pom_g}\$${pom_a}/artifact/$pom_g/$pom_a/$pom_v/$pom_a-$pom_v.war" -O $war
# 执行部署函数
deploy_war
Jenkins 所在服务器要在业务服务器上做免密登录,方法是将 Jenkins 所在服务器的公钥配置到业务服务器的 /root/.ssh/authorized_keys 文件中:
注意:ssh-rsa 开头的是自己配置的公钥,command 开头的是后面的 /root/svr/gogs/gogs 配置的公钥,要把ssh-rsa 开头的公钥放到 command 开头的公钥前面,不然的话 Jenkins 进行 ssh 连接会因为 gogs 的干扰而连接失败。
有关 ssh 公钥和私钥更为详细的知识,可以参考我的这篇博文:
其 Jenkins 配置如下:
1、系统管理 –> 全局安全配置 –> 授权策略
开启 匿名用户具有可读权限
2、系统管理 –> Manage Credentials –> Stores scoped to Jenkins –> Jenkins –> 全局凭据(unrestricted) –> 添加凭据
配置 ID、描述、用户名、私钥:
3、系统管理 –> 系统配置 –> SSH remote hosts
填写 Hostname 和 Port,选择第 2 步配置的凭证:
4、进入任务 –> 配置 –> Post Steps –> Add post-build step –> Execute shell script on remote host using ssh
配置以下内容:
BUILD_URL=$BUILD_URL /root/svr/services/yangxu-simple-webbapp/jenkins.sh
博主在 Jenkins 2.235.5 版本中使用上述方法部署成功,如果上述方法部署失败,可以尝试配置以下内容:
BUILD_ID=dontKillMe BUILD_URL=$BUILD_URL /root/svr/services/yangxu-simple-webbapp/jenkins.sh
如果还是部署失败,可能的原因:因为 BUILD_ID=dontKillMe 不会被修改 ,而是当作参数来传递。
可以参考下面的方法解决:
1、进入任务 –> 配置 –> Post Steps –> Add post-build step –> 执行 shell
2、配置以下内容
BUILD_ID=dontKillMe
echo $BUILD_ID
ssh root@192.168.25.159 BUILD_URL=$BUILD_URL /root/svr/services/yangxu-simple-webbapp/jenkins.sh
#如果jenkins.sh就放在Jenkins所在的服务器
#可以不用ssh登录,直接使用下面的shell
BUILD_ID=dontKillMe
echo $BUILD_ID
BUILD_URL=$BUILD_URL /root/svr/services/yangxu-simple-webbapp/jenkins.sh
3、部署结果
配置文件更新
我们在迭代的过程当中总共要经过四个环境,每个环境的配置信息是不一样的,如何在更新项目的时候把对应的配置文件也一起更新呢?一种做法是采用 Disconf 之类的配置系统来管理各个环境的配置,但这里我们采用的是一个简单些的方案:把当前环境的配置文件放到 app-conf 目录下,等更新脚本的时候会一同覆盖原来的配置文件。
版本回滚
之前在部署的时候是通过软链接的形式指向指定程序目录,而且原历史版本不会删除,回滚的时候只要把原软链接指定历史程序目录即可。而且配置文件也会一同回滚。
更新脚本说明
前面说过 deploy.sh 部署脚本中还用到了 pom.sh 与tomcat.sh 等脚本,这些脚本的作用是什么呢?整体逻辑如下依赖关系如下:
说明:
- env-set.sh:设置 JVM、Tomcat 等环境参数
- pom.sh:设置当前项目的 groupID、artifactID、version 信息
- tomcat.sh:启动关闭 Tomcat
- deploy.sh:下载并部署项目
- jenkins.sh:用于被 Jenkins 远程触发下载指定更新版本