前言:
发布对于运维人员而言是一件常事,发布的时候你敲每一个命令都得很细心,但人往往会因为一些环境因素影响而导致失误,而且有些小公司代码迭代速度快一天需要更新几个版本,运维人员在多次的同样操作后,可能会因为精神不集中或其他事而分心,导致误操作而影响线上业务。
简介:
本文将介绍jenkins结合gitlab实现持续集成,解放运维人员的双手,让运维人员可以有更多的时间去钻研其他技术,提升服务稳定性和创造更大的价值。
环境:
Jenkins发布机器:172.16.47.187
gitlab代码仓库:172.16.47.185
Nginx服务器:172.16.47.188
Jenkins的安装将会在往后更新,敬请谅解
配置ssh免密登陆:
#在发布机器上创建sshkey
[root@jenkins ~]# useradd www
[root@jenkins ~]# passwd www
Changing password for user www.
New password: 123456
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 123456
passwd: all authentication tokens updated successfully.
[root@jenkins ~]# su - www
[www@jenkins ~]$ ssh-keygen -t ras
[www@jenkins ~]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDX9V9MAzNlITVsDu97EgXSSu3q4pRq6CleXY9468BJWRlIWEMpuSy1a6NYlY+kEUjnFfvhjtG6o0WJy96NIH+0p4iSfI/5j2pMQuViJl7M8sA3ujJ9EwIgXwX1zYkpWvQEC2znHR5/GdpuJCZnH0clJs+RmUAxG6X7xxXQTFSzXzHp2Gktzunr1R/yfvIZEqIlozbf7IDHYujiCtZDNhdKrKEUFjmZwTk4XRMsRu08wD12ygCEtV/xCoYuPdco3YtYSoYjpkOlR0RHBl2eMbkze+ogIyAieRjK4WRiT7ucl+ddQ7rGi0dG1RvzBctvtWfHCKYdRdALSunvJxUN/Th www@jenkins
#将公钥放到nginx服务器上的www用户下
[root@nginx-node1 ~]# user add www
[root@nginx-node1 ~]# su - www
[www@nginx-node1 ~]$ vim ~/.ssh/authorized_keys
#将Jenkins发布机器生成的ssh公钥放到里面
#Jenkins测试登陆nginx服务器
#将Jenkins发布机器公钥放到gitlab上
#创建一个项目并测试通过ssh拉取代码
持续化构建配置:
#在浏览器输入http://172.16.47.187:8080 点击系统管理-插件管理-可选插件
#将Jenkins发布机器私钥添加到Jenkins里 点击凭据
#创建一个新的任务
#保存退出,点击立即构建
#随机生成10个数字用于jenkins与gitlab的token验证
[www@jenkins ~]$ openssl rand -hex 10
84b3b8cdf9ab33a0481b
#配置jenkins触发器
#配置gitlab webhook
#返回200即为成功
#安装ssh插件
#返回首页,点击凭据
#添加凭据
#保存返回首页,点击auto-deploy项目-配置
#更改index.html文件,提交代码
#到此为止,通过git push触发jenkins自动化部署就已经完成了。
附录:
自动化Shell脚本
该脚本并不是很完善,仅仅满足自动化部署,可根据自身情况修改该脚本
#!/bin/bash
USER="www"
#Code env
PRO_NAME="auto-deploy"
CODE_DIR="/data/code"
SOURCE_DIR="/data/source/$PRO_NAME"
WEB_DIR="/data/nginx/html"
TMP_DIR="/data/deploy_tmp"
#Date/Time
CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H%M_%S")
#Node list
NODE_LIST='172.16.47.188'
ROLLBACK_LIST='172.16.47.188'
#Shell Env
SHELL_DIR="/data/shell/"
SHELL_NAME="auto-deploy"
#log
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/deploy.lock"
#Lock
shell_lock(){
touch ${LOCK_FILE}
}
shell_unlock(){
rm -f ${LOCK_FILE}
}
#URL Test
url_test(){
URL=$1
curl -s --head $URL|egrep '200|301|302'
if [ $? -ne 0 ];then
shell_unlock;
echo "$URL test error" && exit;
fi
}
writelog(){
LOGINFO=$1
echo "${CDATE}-${CTIME}:${SHELL_NAME}:${LOGINFO}" >> ${SHELL_LOG}
}
code_get(){
writelog "code_get"
cd $SOURCE_DIR
git pull
GIT_CID=$(git log|awk 'NR==1{print $2}'|cut -c 1-6)
PKG_VER="${CDATE}_${CTIME}_${GIT_CID}"
PKG_NAME="${PRO_NAME}_${PKG_VER}"
cp -r ${SOURCE_DIR} ${TMP_DIR}/${PKG_NAME}
}
code_tar(){
writelog "code_tar"
cd ${TMP_DIR} && tar czf ${PKG_NAME}_tar.gz ${PKG_NAME}
writelog "${PKG_NAME}_tar.gz"
}
code_scp(){
writelog "code_scp"
for node in $NODE_LIST;do
scp ${TMP_DIR}/${PKG_NAME}_tar.gz $USER@$node:${TMP_DIR}/
done
}
pre_deploy(){
writelog "remove from cluster"
ssh $USER@$NODE_LIST "cd ${TMP_DIR} && tar xf ${PKG_NAME}_tar.gz -C ${CODE_DIR}/"
ssh $USER@$NODE_LIST "rm -f $WEB_DIR/${PRO_NAME} && ln -s ${CODE_DIR}/${PKG_NAME} $WEB_DIR/${PRO_NAME}"
}
pre_test(){
url_test "http://${NODE_LIST}/${PRO_NAME}/index.html"
echo "Rre add to cluster"
}
rollback_list(){
for node in $NODE_LIST;do
ssh $USER@$node ls -l "$WEB_DIR" && \
ssh $USER@$node find "$CODE_DIR/" -maxdepth 1 -mtime -2|sed 1d|awk -F '/' '{print $4}'
done
}
rollback_fun(){
if [ -z $ROOLBACK ];then
shell_unlock;
echo "Please input rollback version" $$ exit;
else
for node in $NODE_LIST;do
ssh $USER@$node rm -f $WEB_DIR/${PRO_NAME} && \
ssh $USER@$node ln -s ${CODE_DIR}/$ROOLBACK $WEB_DIR/${PRO_NAME}
done
fi
}
main(){
if [ -f "$LOCK_FILE" ];then
echo "Deploy is Running" && exit;
fi
DEPLOY_METHOD="$1"
ROOLBACK="$2"
case $DEPLOY_METHOD in
deploy)
shell_lock;
code_get;
code_tar;
code_scp;
pre_deploy;
pre_test;
shell_unlock;
;;
list)
rollback_list;
;;
rollback)
shell_lock;
rollback_fun $ROOLBACK;
shell_unlock;
;;
*)
echo "$Usage:$0 [ deploy | list | rollback ]"
esac
}
main $1 $2