实现项目自动化部署以及秒级回滚
部署流程:
版本回滚:
1.环境准备
1.1 系统信息
[root@linux-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@linux-node1 ~]# uname -r 3.10.0-327.18.2.el7.x86_64 [root@linux-node1 ~]# ifconfig eth0|awk -F "[ :]+" 'NR==2{print $3}' 192.168.56.11 [root@linux-node1 ~]# hostname linux-node1.example.com #node2主机名为linux-node2.example.com,IP为192.168.56.12,其余配置相同
1.2 添加www用户及配置免密码登陆
#所有的web服务,都应该使用普通用户,所有的web服务都不应该监听80端口,除了负载均衡 useradd www usermod -s /bin/bash www #给www用户使用bash权限 [root@linux-node1 ~]# id www uid=1000(www) gid=1000(www) groups=1000(www) [root@linux-node2 ~]# id www uid=1000(www) gid=1000(www) groups=1000(www) #设置www用户免密码登陆 ssh-keygen -t rsa 把id_rsa.pub里的公钥粘贴到另一台机器~/.ssh/authorized_keys中
gitlab-ce部署在192.168.56.12中,演示中只用192.168.56.11部署项目来演示
2.自动化部署脚本
2.1 创建目录
mkdir -p /deploy/code/web-demo #项目存放目录
mkdir -p /deploy/config/web-demo/base #通用文件存放目录
mkdir -p /deploy/config/web-demo/other #差异文件存放目录
mkdir -p /deploy/tar #项目打包放置目录
mkdir -p /deploy/tmp #项目拷贝放置目录
mkdir -p /opt/webroot #项目解压目录
mkdir /webroot #项目发布根目录
chown -R www:www /deploy
chown -R www:www /opt/webroot
chown -R www:www /webroot
2.2 脚本编写
[www@linux-node1 ~]# vi deploy.sh #!/bin/bash #Dir List # mkdir -p /deploy/code/web-demo # mkdir -p /deploy/config/web-demo/base # mkdir -p /deploy/config/web-demo/other # mkdir -p /deploy/tar # mkdir -p /deploy/tmp # mkdir -p /opt/webroot # mkdir /webroot # chown -R www:www /deploy # chown -R www:www /opt/webroot # chown -R www:www /webroot # Node List PRE_LIST="192.168.56.11" #预生产节点列表 #GROUP1_LIST="192.168.56.12" #生产节点列表,可添加多个 ROLLBACK_LIST="192.168.56.11" #回滚节点列表 # Date && Time Variables #添加时间信息 LOG_CDATE=`date "+%Y-%m-%d"` LOG_CTIME=`date "+%H-%M-%S"` CDATE=$(date "+%Y-%m-%d") CTIME=$(date "+%H-%M-%S") # Shell Env SHELL_NAME="deploy.sh" #脚本名称 SHELL_DIR="/home/www/" #脚本路径 SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log" #脚本日志 # Code Env PRO_NAME="web-demo" #项目名称 CODE_DIR="/deploy/code/web-demo" #项目放置目录,仅用于git pull CONFIG_DIR="/deploy/config/web-demo" #项目配置目录 TMP_DIR="/deploy/tmp" #代码拷贝放置目录 TAR_DIR="/deploy/tar" #代码打包放置目录 LOCK_FILE="/tmp/deploy.lock" #锁文件放置路径 usage(){ #使用方式 echo $"Usage: $0 { deploy | rollback [ list | version ] }" } writelog(){ #记录日志 LOGINFO=$1 echo "${CDATE} ${CTIME} : ${SHELL_NAME} : ${LOGINFO} " >> ${SHELL_LOG} } shell_lock(){ #加锁 touch ${LOCK_FILE} } shell_unlock(){ #解锁 rm -f ${LOCK_FILE} } url_test(){ #项目部署测试 URL=$1 curl -s --head $URL|grep '200 OK' if [ $? -ne 0 ];then shell_unlock; echo "test error" && exit; fi } code_get(){ #代码获取 writelog "code_get" cd $CODE_DIR && git pull cp -r ${CODE_DIR} ${TMP_DIR}/ API_VERL=$(git show | grep commit | cut -d ' ' -f2) #获取git提交版本号前6位 API_VER=$(echo ${API_VERL:0:6}) } code_build(){ #代码编译 echo "code_build" } code_config(){ #代码配置 echo code_config /bin/cp -r ${CONFIG_DIR}/* ${TMP_DIR}/"${PRO_NAME}" PKG_NAME="${PRO_NAME}"_"$API_VER"-"${CDATE}-${CTIME}" #项目重新命名 cd ${TMP_DIR} && mv ${PRO_NAME} ${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(){ #scp分发代码包 writelog "code_scp" for node in ${PRE_LIST};do scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ done for node in ${GROUP1_LIST};do scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ done } pre_deploy(){ #预生产节点部署 writelog "remove pre_list from cluster" ssh ${PRE_LIST} "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" ssh ${PRE_LIST} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" #通用软链接灵活部署项目 } pre_test(){ #预生产节点测试 url_test "http://${PRE_LIST}/index.html" echo "add pre_list to cluster" #测试部署成功后加入集群 } group1_deploy(){ #生产节点组1部署 writelog "remove group1 from cluster" for node in $GROUP1_LIST;do ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" done scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml } group1_test(){ url_test "http://192.168.56.12/index.html" echo "add group1 to cluster" #测试部署成功后加入集群 } rollback_fun(){ #回滚ROLLBACK_LIST中的项目到指定版本 for node in $ROLLBACK_LIST;do ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo" echo "$node rollback success" done } rollback(){ #显示回滚列表,选择版本回滚 if [ -z $1 ];then shell_unlock; echo $"Usage: $0 { rollback [ list | version ] }" echo "Please input list and choose rollback version" && exit; fi case $1 in list) ls -l /opt/webroot/ -I "*.tar.gz" | cut -d ' ' -f 9 ;; *) rollback_fun $1 esac } main(){ if [ -f $LOCK_FILE ];then echo "Deploy is running" && exit; #脚本正在使用加锁 fi DEPLOY_METHOD=$1 ROLLBACK_VER=$2 case $DEPLOY_METHOD in deploy) shell_lock; code_get; code_build; code_config; code_tar; code_scp; pre_deploy; pre_test; # group1_deploy; # group1_test; shell_unlock; ;; rollback) shell_lock; rollback $ROLLBACK_VER; shell_unlock; ;; *) usage; esac } main $1 $2
3.项目部署测试
3.1 修改Apache根目录
#在node1和node2上都装一个apache,把根目录改成/webroot/web-demon,然后启动apache [root@linux-node1 ~]# grep web-demo /etc/httpd/conf/httpd.conf DocumentRoot "/webroot/web-demo" [root@linux-node1 ~]# systemctl start httpd [www@linux-node1 ~]$ ./deploy.sh deploy #执行一键部署脚本,git pull注掉,自定义一个版本号模拟批量部署
访问192.168.56.11和192.168.56.12,查看测试结果如下
3.2 集成gitlab-ce
[root@linux-node2 webroot]# systemctl stop httpd #关闭httpd服务
[root@linux-node2 webroot]# gitlab-ctl start #启动gitlab
添加web-demo项目
点击右上角admin area先创建一个web组,然后在web组下创建web-demo项目
添加ssh keys
把node1,node2的ssh公钥拷贝到指定处添加
3.3 模拟开发提交代码
[www@linux-node1 ~]$ git clone git@192.168.56.12:web/web-demo #把代码库拉到本地 Cloning into 'web-demo'... remote: Counting objects: 12, done. remote: Compressing objects: 100% (7/7), done. remote: Total 12 (delta 0), reused 0 (delta 0) Receiving objects: 100% (12/12), done. [www@linux-node1 ~]$ cd web-demo/ [www@linux-node1 ~/web-demo]$ ll total 8 -rw-rw-r-- 1 www www 32 Aug 13 07:48 index.html -rw-rw-r-- 1 www www 6 Aug 13 07:48 README.md [www@linux-node1 ~/web-demo]$ vi index.html #编辑代码 chegva.com hehehehe verision1.0 [www@linux-node1 ~/web-demo]$ git add * [www@linux-node1 ~/web-demo]$ git commit -m "add version1.0" [master 5f5a78e] add version1.0 1 file changed, 1 insertion(+), 1 deletion(-) [www@linux-node1 ~/web-demo]$ git push #提交代码 [www@linux-node1 ~]$ ./deploy.sh deploy #部署代码,由于node2 80端口被占用只用第一台演示,懒! remote: Counting objects: 6, done. remote: Compressing objects: 100% (4/4), done. remote: Total 6 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (6/6), done. From 192.168.56.12:web/web-demo 85c3ca9..5f5a78e master -> origin/master Updating 85c3ca9..5f5a78e Fast-forward index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) code_build code_config web-demo_5f5a78-2016-08-13-07-51-47.tar.gz 100% 10KB 10.2KB/s 00:00 HTTP/1.1 200 OK add pre_list to cluster
查看部署结果
模拟项目版本更新
[www@linux-node1 ~/web-demo]$ cat index.html wwww.chegva.com hahahhahaha verision2.0 [www@linux-node1 ~/web-demo]$ git add * [www@linux-node1 ~/web-demo]$ git commit -m "add version2.0" [master bf67cb3] add version2.0 1 file changed, 2 insertions(+), 2 deletions(-) [www@linux-node1 ~/web-demo]$ git push [www@linux-node1 ~]$ ./deploy.sh deploy
3.4 版本回滚
[www@linux-node1 ~]$ ./deploy.sh rollback list web-demo_5f5a78-2016-08-13-07-51-47 web-demo_85c3ca-2016-08-13-06-29-21 web-demo_bf67cb-2016-08-13-07-56-30 [www@linux-node1 ~]$ ./deploy.sh rollback web-demo_5f5a78-2016-08-13-07-51-47 192.168.56.11 rollback success
查看测试结果,已经回滚到上一版本