05.Jenkins学习笔记

集成部署环境构建

Posted by Chen Xingxu on September 8, 2020

05.Jenkins学习笔记–集成部署环境构建

知识点

  1. 版本仓库选型
  2. 更新机制实现(更新脚本、Jenkins 配置)
    1. 项目更新
    2. 配置文件更新
    3. 版本回滚
    4. 适应不同环境(开发、测试、运维)

版本仓库选型

在整个流程中,版本仓库是非常重要的一项,用于存储版本发布所需的程序包、更新脚本、更新配置。这里我们直接采用 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 公钥和私钥更为详细的知识,可以参考我的这篇博文:

05.Git学习笔记–搭建企业私有Git服务

其 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 远程触发下载指定更新版本

版本分支管理