一:通过jenkins调用shell脚本完成从Gitlab服务器获取代码、打包、部署到web服务器、将web服务器从负载均衡器删除、解压、复制配置文件、创建软连接、测试每一台web服务器、将web服务器添加至负载均衡、回滚到任意指定版本、一键回滚到上一版本等功能,脚本放在user_00用户家目录下的tools/deploy/sbin下,并使用user_00用户执行,每个web服务器也都使用user_00用户运行web服务,且gid和uid相同,web目录和权限都一致,以便达到标准化可以带来更安全的生产环境和更高的效率:
1.1 在jenkins项目配置中调用shell脚本与环境准备:
1.1.1 环境准备:
部署服务器(发布机):
# sudo su - user_00
$ cd /home/user_00/tools/deploy/
$ mkdir data sbin tmp tar conf/web-django/base -p
在发布机上对相应对应用做发布配置:
$ cat /home/user_00/tools/deploy/conf/web-django/deploy.cnf
DEV_LIST="" # 开发环境
PRE_LIST="" # 预发布环境
PRO_LIST="192.168.56.3 192.168.56.4" # 线上环境
GIT_URL='git@192.168.56.3:liuzhousheng/web-django.git'
WEB_DIR='/data/apps'
PORT='22'
$ cat /home/user_00/tools/deploy/conf/web-django/exclude.cnf
.git
web应用节点:
# mkdir /data/apps && chown user_00.users /data/apps
# sudo su - user_00
$ cd /data/apps/ && mkdir release/web-django -p
$ ln -sv /data/apps/release/web-django/web-django_39b295f1_20190426-18-52-36 /data/apps/web-django # 初始化打一个死链接
将发布机user_00的公钥放到多台web服务器user_00 家目录下的文件 .ssh/authorized_keys
$ cat /home/user_00/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHSkr5zTWobDcIUM6mFKDqFK6jO0CBlzD5qaOazO6WeKrJIlHtIaFZW4yAezWp9Cc8ZT0FCUaXHaOk39RKxIJGAuyi8kOpYM07/3NisRhukpu2HTTQKhAM3UpyQAjd+2w+Sw6Dl99YNeq0QVGn+2BGDCjaip4A6jNVpG601q3ztMr/ujtTXT0ulZcoy4xgtULpN66/Fu3YKUO1KuK6a6gxfdGyB9VIbrzS/ftdtsLvBD0TPisLbxN//ydwtvtJ1c1hqJtwob97F5v1Hu7rMEBjTVk3WwJ65eE0cey/L/0oPSePQHXJJI9geSwcHZdkWu1Di035SVa7E402ia6FgJYJ user_00@192.168.56.5
1.1.2 user_00 用户家目录中的脚本内容:
$ cat code_deploy.sh
#/bin/bash
BASE_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd )
. $BASE_DIR/conf/$2/deploy.cnf
exclude_cfg=$BASE_DIR/conf/$2/exclude.cnf
APP_NAME=$2 # 项目名称的函数
#发布时间
DEPLOY_TIME=$(date "+%Y%m%d-%H-%M-%S")
# code env 代码变量
CODE_DIR="/home/user_00/tools/deploy/data" # 从版本管理系统更新的代码目录
CONFIG_DIR="/home/user_00/tools/deploy/conf" # 保存不同项目的配置文件,一个目录里面就是一个项目的一个配置文件或多个配置文件
TMP_DIR="/home/user_00/tools/deploy/tmp" # 临时目录
TAR_DIR="/home/user_00/tools/deploy/tar" # 打包目录
LOCK_FILE="/tmp/${APP_NAME}-deploy.lock" # 锁文件路径
# shell env 脚本位置等变量
SHELL_NAME="code_deploy.sh" # 脚本名称
SHELL_DIR="/home/user_00/tools/deploy/sbin" # 脚本路径
SHELL_LOG="/home/user_00/tools/deploy/logs/${APP_NAME}-deploy.log" # 脚本执行日志文件路径
usage(){ # 使用帮助函数
echo $"Usage: $0 deploy app_name | rollback app_name version"
}
writelog(){ # 写入日志的函数
LOGINFO=$1 # 将参数作为日志输入
echo "${DEPLOY_TIME}: ${SEHLL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}
# 锁函数
shell_lock(){
touch ${LOCK_FILE}
}
# 解锁函数
shell_unlock(){
rm -f ${LOCK_FILE}
}
# 获取代码的函数
code_get(){
echo "code_get"
writelog code_get
if [ -d "$CODE_DIR/$APP_NAME" ];then
cd ${CODE_DIR}/${APP_NAME} && git pull #从git服务器更新代码
else
cd $CODE_DIR && git clone $GIT_URL
fi
/bin/cp -rf ${CODE_DIR}/${APP_NAME} ${TMP_DIR}/${APP_NAME} # 临时保存代码并重命名,包名为时间+版本号,准备复制到web服务器
cd ${CODE_DIR}/${APP_NAME}
API_VERL=$(git show |grep commit |cut -d ' ' -f2)
API_VER=$(echo ${API_VERL:0:8}) # 版本号
}
code_build(){ # 代码编译函数
echo code_build
}
code_config(){ # 配置文件函数
writelog "code_config"
rsync -arP ${CONFIG_DIR}/${APP_NAME}/base/ ${TMP_DIR}/${APP_NAME} # 将配置文件放在本机保存配置文件的临时目录,用于暂时保存代码项目
PKG_NAME="${APP_NAME}"_"$API_VER"_"${DEPLOY_TIME}" # 定义代码目录名称
cd ${TMP_DIR} && mv ${APP_NAME} ${PKG_NAME} # 重命名代码文件为web-django_123id838-20170629-11-19-10格式
}
code_tar(){ # 对代码打包函数
writelog code_tar
#cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude=".git" && rm -rf ${PKG_NAME} # 将目录打包成压缩文件,便于网络传输
cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude-from=$exclude_cfg && rm -rf ${PKG_NAME} # 将目录打包成压缩文件,便于网络传输
writelog "${PKG_NAME}.tar.gz packaged success" # 记录打包成功的日志
}
code_rsync(){ # 代码压缩包同步到客户端的函数
writelog "code_scp"
for node in $PRO_LIST;do # 循环服务器节点列表
rsync -razP ${TMP_DIR}/${PKG_NAME}.tar.gz $node:${WEB_DIR}/release/${APP_NAME} # 将压缩后的代码包复制到web服务器的/opt/webroot
done
rm -f ${TMP_DIR}/${PKG_NAME}.tar.gz
}
cluster_node_add(){ #将web服务器添加至前端负载
echo cluster_node_add
}
cluster_node_remove(){ # 将web服务器从集群移除函数(正在部署的时候应该不处理业务)
writelog "cluster_node_remove"
}
pro_deploy(){ # 代码解压部署函数
writelog "pro_code_deploy"
for node in ${PRO_LIST};do # 循环生产服务器节点列表
cluster_node_remove $node
echo "pro, cluster_node_remove $node"
ssh -p ${PORT} ${node} "cd ${WEB_DIR}/release/${APP_NAME} && tar zxf ${PKG_NAME}.tar.gz && rm -f ${PKG_NAME}.tar.gz" # 分别到各web服务器节点执行压缩包解压命令
ssh -p ${PORT} ${node} "rm -f ${WEB_DIR}/${APP_NAME} && ln -s ${WEB_DIR}/release/${APP_NAME}/${PKG_NAME} ${WEB_DIR}/${APP_NAME}" # 整个自动化的核心,创建软连接
done
}
pro_test(){ # 生产主机测试函数
for node in ${PRO_LIST};do # 循环生产主机列表
#curl -s --head http://${node}:9999/index.html | grep "200 OK" #测试web界面访问
curl -s --head http://www.baidu.com/index.html |grep "200 OK"
if [ $? -eq 0 ];then #如果访问成功
writelog " ${node} Web Test OK!" #记录日志
echo "pro_test,${node} Web Test OK!"
cluster_node_add
writelog " ${node} add to cluster OK!" #记录将服务器 添加至集群的日志
else #如果访问失败
writelog "${node} test no OK" #记录日志
echo "${node} test no OK"
shell_unlock # 调用删除锁文件函数
break # 结束部署
fi
done
}
rollback_fun(){
for node in $PRO_LIST;do # 循环服务器节点列表
# 注意一定要加"号,否则无法在远程执行命令
ssh -p ${PORT} $node "ls -l ${WEB_DIR}/release/${APP_NAME}/$1 && rm -f ${WEB_DIR}/${APP_NAME} && ln -s ${WEB_DIR}/release/${APP_NAME}/$1 ${WEB_DIR}/${APP_NAME}" # 立即回滚到指定的版本,$1即指定的版本参数
echo "${node} rollback success!"
done
}
rollback(){ # 代码回滚主函数
if [ -z $1 ];then
shell_unlock # 删除锁文件
echo "Please input rollback version" && exit 3;
fi
case $1 in # 把第二个参数做当自己的第一个参数
list)
ls -l ${WEB_DIR}/release/${APP_NAME}/*.tar.gz
;;
*)
rollback_fun $1
esac
}
main(){
if [ -f $LOCK_FILE ] ;then # 先判断锁文件在不在,如果有锁文件直接退出
echo "Deploy is running" && exit 10
fi
DEPLOY_METHOD=$1 # 避免出错误将脚本的第一个参数作为变量
ROLLBACK_VER=$3
case $DEPLOY_METHOD in
deploy) # 如果第一个参数是deploy就执行以下操作
shell_lock # 执行部署之前创建锁。如果同时有其他人执行则提示锁文件存在
code_get # 获取代码
code_build # 如果要编译执行编译函数
code_config # cp配置文件
code_tar # 打包
code_rsync # scp到服务器
pro_deploy # 生产环境部署
pro_test # 生产环境测试
shell_unlock # 执行完成后删除锁文件
;;
rollback) # 如果第一个参数是rollback就执行以下操作
shell_lock # 回滚之前也是先创建锁文件
rollback $ROLLBACK_VER
shell_unlock # 执行完成删除锁文件
;;
*)
usage;
esac
}
main $1 $2 $3
1.1.3 jenkins-项目-配置:
sudo ssh user_00@192.168.56.5 "~/tools/deploy/sbin/code_deploy.sh deploy web-django" ##正常发版
构建配置
立即构建
web服务器192.168.56.4:
[root@localhost web-django]# ll /data/apps/release/web-django/
总用量 0
drwxr-xr-x. 3 user_00 users 70 4月 26 18:58 web-django_39b295f1_20190427-14-56-05
drwxr-xr-x. 3 user_00 users 70 4月 26 18:58 web-django_39b295f1_20190427-15-01-54
[root@localhost web-django]# ll /data/apps/
总用量 0
drwxr-xr-x. 3 user_00 users 24 4月 26 12:26 release
lrwxrwxrwx. 1 user_00 users 67 4月 27 15:01 web-django -> /data/apps/release/web-django/web-django_39b295f1_20190427-15-01-54
回滚到web-django_39b295f1_20190427-14-56-05 这个版本:
sudo ssh user_00@192.168.56.5 "~/tools/deploy/sbin/code_deploy.sh rollback web-django web-django_39b295f1_20190427-14-56-05" ##回滚到指定的版本
回滚配置
回滚构建
web节点软链指向回滚版本
[root@localhost web-django]# ll /data/apps/
总用量 0
drwxr-xr-x. 3 user_00 users 24 4月 26 12:26 release
lrwxrwxrwx. 1 user_00 users 67 4月 27 15:10 web-django -> /data/apps/release/web-django/web-django_39b295f1_20190427-14-56-05
网友评论