自动化部署--shell脚本--2

时间:2022-02-27 21:35:19
node1和node2都装apache
 
[root@linux-node1 ~]# yum install httpd -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.zju.edu.cn
* epel: mirrors.tuna.tsinghua.edu.cn
* extras: mirrors.zju.edu.cn
* updates: mirrors.163.com
Package httpd-2.4.6-45.el7.centos.4.x86_64 already installed and latest version
Nothing to do
[root@linux-node1 ~]#

[root@linux-node2 ~]# yum install httpd -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.zju.edu.cn
* extras: mirrors.zju.edu.cn
* updates: mirrors.163.com
Package httpd-2.4.6-45.el7.centos.4.x86_64 already installed and latest version
Nothing to do
[root@linux-node2 ~]#

  

把apache的根目录都改成/opt/webroot

[root@linux-node2 ~]# vim /etc/httpd/conf/httpd.conf 
[root@linux-node2 ~]#

自动化部署--shell脚本--2

上面是默认的,改成如下配置

自动化部署--shell脚本--2

 

 node1也改成如下

自动化部署--shell脚本--2

 

 启动apache

[root@linux-node2 ~]# systemctl start httpd
[root@linux-node2 ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 21937 root 4u IPv6 132900 0t0 TCP *:http (LISTEN)
httpd 21938 apache 4u IPv6 132900 0t0 TCP *:http (LISTEN)
httpd 21939 apache 4u IPv6 132900 0t0 TCP *:http (LISTEN)
httpd 21940 apache 4u IPv6 132900 0t0 TCP *:http (LISTEN)
httpd 21941 apache 4u IPv6 132900 0t0 TCP *:http (LISTEN)
httpd 21942 apache 4u IPv6 132900 0t0 TCP *:http (LISTEN)
[root@linux-node2 ~]#

[root@linux-node1 ~]# systemctl start httpd
[root@linux-node1 ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 23765 root 4u IPv6 117035 0t0 TCP *:http (LISTEN)
httpd 23767 apache 4u IPv6 117035 0t0 TCP *:http (LISTEN)
httpd 23768 apache 4u IPv6 117035 0t0 TCP *:http (LISTEN)
httpd 23769 apache 4u IPv6 117035 0t0 TCP *:http (LISTEN)
httpd 23770 apache 4u IPv6 117035 0t0 TCP *:http (LISTEN)
httpd 23771 apache 4u IPv6 117035 0t0 TCP *:http (LISTEN)
[root@linux-node1 ~]#

访问网页

自动化部署--shell脚本--2

自动化部署--shell脚本--2

修改首页

[www@linux-node1 ~]$ cd /deploy/code/
[www@linux-node1 code]$ cd web-demo/
[www@linux-node1 web-demo]$ pwd
/deploy/code/web-demo
[www@linux-node1 web-demo]$ ll
total 4
-rw-r--r-- 1 www www 9 Apr 26 22:28 index.html
[www@linux-node1 web-demo]$ cat index.html
nmap.com
[www@linux-node1 web-demo]$ cd /scripts/
[www@linux-node1 scripts]$
 
再次部署
[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
code_scp
web-demo_456_2017-04-27-21-40-36.tar.gz 100% 220 0.2KB/s 00:00
web-demo_456_2017-04-27-21-40-36.tar.gz 100% 220 0.2KB/s 00:00
code_deploy
192.168.58.12.crontab.xml 100% 21 0.0KB/s 00:00
code_test
cluster_node_in
[www@linux-node1 scripts]$
 
 
检查部署结果,注意ctrl+f5
自动化部署--shell脚本--2

自动化部署--shell脚本--2

 

查看此时自动化部署脚本的配置

[root@linux-node1 scripts]# cat 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 -p /webroot
#chown -R www:www /deploy
#chown -R www:www /opt/webroot
#chown -R www:www /webroot

#Node List
NODE_LIST="192.168.58.11 192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='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"
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 ]"
}

writelog(){
LOGINFO=$1
echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}

shell_lock(){
touch ${LOCK_FILE}
}
shell_unlock(){
rm -f ${LOCK_FILE}
}

code_get(){
writelog "code_get";
cd $CODE_DIR && echo "git pull"
cp -r ${CODE_DIR} ${TMP_DIR}/
API_VER="456"
}

code_build(){
echo code_build
}

code_config(){
writelog "code_config"
/bin/cp -r ${CONFIG_DIR}/base/* ${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 cfz ${PKG_NAME}.tar.gz ${PKG_NAME}
writelog "${PKG_NAME}.tar.gz"
}

code_scp(){
echo "code_scp"
for node in $NODE_LIST;do
scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
done
}

cluster_node_remove(){
writelog "cluster_node_remove"
}

code_deploy(){
echo code_deploy
for node in $NODE_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

code_test(){
echo code_test
}

cluster_node_in(){
echo cluster_node_in
}

rollback(){
echo rollback
}

main(){
if [ -f ${LOCK_FILE} ];then
echo "Deploy is running" && exit;
fi
DEPLOY_METHOD=$1
case $DEPLOY_METHOD in
deploy)
shell_lock;
code_get;
code_build;
code_config;
code_tar;
code_scp;
cluster_node_remove;
code_deploy;
code_test;
cluster_node_in;
shell_unlock;
;;
rollback)
shell_lock;
rollback;
shell_unlock;
;;
*)
usage;
esac

}
main $1
[root@linux-node1 scripts]#

  

 修改测试部分,完善测试函数

过滤到,返回0,过滤不到返回其它的
-s静默模式

[root@linux-node1 scripts]# curl --head http://192.168.58.11/index.html | grep "200 OK"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 9 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
HTTP/1.1 200 OK
[root@linux-node1 scripts]# curl -s --head http://192.168.58.11/index.html | grep "200 OK"
HTTP/1.1 200 OK
[root@linux-node1 scripts]#

  

准备是这样的,部署一个,测试一个,通了才继续往下部署。这样才合理
很多公司拿预热节点部署。通过之后再部署生产节点

 

先修改下上面,把主机分组,模拟分组部署
GROUP1_LIST模拟预热节点
GROUP2_LIST 模拟其余的全部节点
#chown -R www:www /opt/webroot
#chown -R www:www /webroot

#Node List
GROUP1_LIST="192.168.58.11"
GROUP2_LIST="192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

  

scp这里改下
code_scp(){
writelog "code_scp"
for node in $GROUP1_LIST;do
scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
done
for node in $GROUP2_LIST;do
scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
done
}
 
把code_deploy也修改下
下面这里是修改之前
cluster_node_remove(){
writelog "cluster_node_remove"
}

code_deploy(){
echo code_deploy
for node in $NODE_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

code_test(){
echo code_test
}

  

修改之后

cluster_node_remove(){
writelog "cluster_node_remove"
}

group1_deploy(){
echo code_deploy
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
}

group2_deploy(){
echo code_deploy
for node in $GROUP2_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

cluster_node_in(){
echo cluster_node_in
}

  

 

第一组弄的只有1台机器,作为预生产节点
一个节点如果重启需要1分钟的话,5个节点岂不是5分钟。
所以,1个节点先作为预生产节点,部署完毕,测试完毕之后,其它节点可以直接部署了。思想上是这样

添加group1_test测试函数

group1_deploy(){
echo code_deploy
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
}

group1_test(){
curl -s --head http://192.168.58.11/index.html | grep "200 OK"
if [ $? -ne 0 ];then
shell_unlock;
writelog "test error" && exit;
fi
}

group2_deploy(){
echo code_deploy
for node in $GROUP2_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

  

由于group2也要测试,并且每个节点都要测试
因此可以把测试的部分提取出来,封装成函数

shell_lock(){
touch ${LOCK_FILE}
}

url_test(){
URL=$1
curl -s --head $URL | grep "200 OK"
if [ $? -ne 0 ];then
shell_unlock;
writelog "test error" && exit;
fi
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

  

测试部分可以这么写
cluster_node_remove(){
writelog "cluster_node_remove"
}

group1_deploy(){
echo “code_deploy”
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
}

group1_test(){
curl_test "http://192.168.58.11/index.html"
echo "add to cluster"
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
}

group1_test(){
url_test "http://192.168.58.11/index.html"
echo "add to cluster"
}

group2_deploy(){
echo “code_deploy”
for node in $GROUP2_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

group2_test(){
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}

cluster_node_in(){
echo cluster_node_in
}

  

可以把下面函数删除。是否可以加入集群,放在测试函数即可

cluster_node_in(){
echo cluster_node_in
}

  

 

主函数会这么写
cluster_node_remove(){
writelog "cluster_node_remove"
DEPLOY_METHOD=$1
case $DEPLOY_METHOD in
deploy)
shell_lock;
code_get;
code_build;
code_config;
code_tar;
code_scp;
group1_deploy;
group1_test;
group2_deploy;
group2_test;
shell_unlock;
;;
rollback)
shell_lock;
rollback;
shell_unlock;
;;
*)
usage;
esac

}
main $1

  

测试脚本
[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
web-demo_456_2017-04-27-22-41-54.tar.gz 100% 214 0.2KB/s 00:00
web-demo_456_2017-04-27-22-41-54.tar.gz 100% 214 0.2KB/s 00:00
code_deploy
HTTP/1.1 200 OK
add to cluster
code_deploy
192.168.58.12.crontab.xml 100% 21 0.0KB/s 00:00
HTTP/1.1 200 OK
add to cluster
[www@linux-node1 scripts]$

  

没问题,可以访问
自动化部署--shell脚本--2

 

继续优化脚本
pre是预热节点,生产只有1个
group1_list里面有多个

#Node List
PRE_LIST="192.168.58.11"
GROUP1_LIST="192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H-%M-%S")
 
下面这里改下
code_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
}

  

上面的remove函数不需要了。删除即可,如下
cluster_node_remove(){
writelog "cluster_node_remove"
}

 

 

下面的group_list 名字还需要改,再次优化下,把原先的group1_list改成pre_test,然后下面这里的改成group1
下面的group1_test应该改成for循环,测试里面的节点,可以测一个加一个节点到集群。还可以测试完,一块加测试的时候,
如果你只有2-3个节点,没必要写for循环
优化之后内容

[root@linux-node1 scripts]# sed -n '89,128p' deploy.sh 
code_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 from cluster"
ssh $PRE_LIST "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $PRE_LIST "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}

pre_test(){
url_test "http://${PRE_LIST}/index.html"
echo "add to cluster"
}

group1_deploy(){
writelog "remove from cluster"
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

group1_test(){
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}

rollback(){
echo rollback
}
[root@linux-node1 scripts]#

测试的时候,如果只有几个节点,直接几行地址就行了嘛。没必要写太复杂

group1_test(){
url_test "http://192.168.58.12/index.html"
url_test "http://192.168.58.12/index.html"
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}
主函数部分改成下面
[root@linux-node1 scripts]# sed -n '130,$p' deploy.sh 
main(){
if [ -f ${LOCK_FILE} ];then
echo "Deploy is running" && exit;
fi
DEPLOY_METHOD=$1
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;
shell_unlock;
;;
*)
usage;
esac

}
main $1
[root@linux-node1 scripts]#

  

改下代码,区分下主页显示和之前的不同

[www@linux-node1 scripts]$ cd /deploy/code/web-demo/
[www@linux-node1 web-demo]$ cat index.html
nmap.com
[www@linux-node1 web-demo]$ echo "www.nmap.com" > index.html
[www@linux-node1 web-demo]$ cat index.html
www.nmap.com
[www@linux-node1 web-demo]$
 
再次部署
[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
web-demo_456_2017-04-27-23-17-27.tar.gz 100% 220 0.2KB/s 00:00
web-demo_456_2017-04-27-23-17-27.tar.gz 100% 220 0.2KB/s 00:00
HTTP/1.1 200 OK
add to cluster
192.168.58.12.crontab.xml 100% 21 0.0KB/s 00:00
HTTP/1.1 200 OK
add to cluster
[www@linux-node1 scripts]$

  

检查页面,没问题

 自动化部署--shell脚本--2

自动化部署--shell脚本--2

 

此时脚本内容如下
[root@linux-node1 scripts]# cat 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 -p /webroot
#chown -R www:www /deploy
#chown -R www:www /opt/webroot
#chown -R www:www /webroot

#Node List
PRE_LIST="192.168.58.11"
GROUP1_LIST="192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='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"
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 ]"
}

writelog(){
LOGINFO=$1
echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}

shell_lock(){
touch ${LOCK_FILE}
}

url_test(){
URL=$1
curl -s --head $URL | grep "200 OK"
if [ $? -ne 0 ];then
shell_unlock;
writelog "test error" && exit;
fi
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

code_get(){
writelog "code_get";
cd $CODE_DIR && echo "git pull"
cp -r ${CODE_DIR} ${TMP_DIR}/
API_VER="456"
}

code_build(){
echo code_build
}

code_config(){
writelog "code_config"
/bin/cp -r ${CONFIG_DIR}/base/* ${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 cfz ${PKG_NAME}.tar.gz ${PKG_NAME}
writelog "${PKG_NAME}.tar.gz"
}

code_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 from cluster"
ssh $PRE_LIST "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $PRE_LIST "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}

pre_test(){
url_test "http://${PRE_LIST}/index.html"
echo "add to cluster"
}

group1_deploy(){
writelog "remove from cluster"
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

group1_test(){
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}

rollback(){
echo rollback
}

main(){
if [ -f ${LOCK_FILE} ];then
echo "Deploy is running" && exit;
fi
DEPLOY_METHOD=$1
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;
shell_unlock;
;;
*)
usage;
esac

}
main $1
[root@linux-node1 scripts]#

  

 

自动化部署实战-秒级回滚

自动化部署--shell脚本--2

 

再加个能紧急回滚的,就不考虑用户体验了。以紧急回滚为主。也不测试了

自动化部署--shell脚本--2

 

更紧急流程。直接执行回滚上一个版本
自动化部署--shell脚本--2

 

先写个第一种正常流程的,列出回滚版本的函数

因此ROLLBACK_VER=$2 和rollback $ROLLBACK_VER ;

[root@linux-node1 scripts]# sed -n '129,$p' deploy.sh 
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
[root@linux-node1 scripts]#

  

 完善rollback函数

group1_test(){
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}

rollback_fun(){
for node in $ROLLBACK_LIST;do
ssh $node "rm -f /webroot/web-demo && ln-s /opt/webroo/$1 /webroot/web-demo"
done
}

rollback(){
case $1 in
list)
ls -l /opt/webroot/*.tar.gz
;;
*)
rollback_fun $1
esac
}

main(){
if [ -f ${LOCK_FILE} ];then

  

最前面加上如下行,然后写上所有节点
#Node List
PRE_LIST="192.168.58.11"
GROUP1_LIST="192.168.58.12"
ROLLBACK_LIST="192.168.58.11 192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

  

下面这里改成如下
usage(){
echo $"Usage: $0 { deploy | rollback [ list |version ]}"
}

上面写不合适,应该不传参数列出来可以回退的版本
现在如果rollback一个不存在的版本,它会把软链接删除了,回退也失败,因此可以反过来
再改下
之所以把这个if判断写在for下面。主要是,如果只部署了预生产节点,没部署其它节点
那么回退的时候就可以把预部署节点回退了。否则其它的都回退失败了,并且还要检测其它节点上有没有包。我觉得这里应该ssh -d检测

rollback_fun(){
for node in $ROLLBACK_LIST;do
if [ -d /opt/webroot/$1 ];then
ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroo/$1 /webroot/web-demo"
fi
done
}
继续改造(其实这里通过ssh之后判断其余节点目录是否存在的)
rollback_fun(){
for node in $ROLLBACK_LIST;do
if [ -d /opt/webroot/$1 ];then
ssh $node "[ -d /opt/webroot/$1 ] && rm -f /webroot/web-demo && ln -s /opt/webroo/$1 /webroot/web-demo"
fi
done
}

  

这里就不对了吧。rollback之后没跟参数居然执行了
[www@linux-node1 scripts]$ ./deploy.sh rollback
[www@linux-node1 scripts]$

  

改造下
rollback_fun(){
for node in $ROLLBACK_LIST;do
if [ -d /opt/webroot/$1 ];then
ssh $node "if [ -d /opt/webroot/$1 ];then rm -f /webroot/web-demo && ln -s /opt/webroo/$1 /webroot/web-demo;else echo "hehe";fi"
fi
done
}

  

 执行

[www@linux-node1 scripts]$ ./deploy.sh rollback
[www@linux-node1 scripts]$

  

上面执行为和之前显示一致,再改造下。
rollback_fun(){
for node in $ROLLBACK_LIST;do
ssh $node "if [ -d /opt/webroot/$1 ];then rm -f /webroot/web-demo && ln -s /opt/webroo/$1 /webroot/web-demo;else echo "hehe";fi"
done
}

 测试

[www@linux-node1 scripts]$ ./deploy.sh rollback
[www@linux-node1 scripts]$

执行还是没达到效果
先妥协了。以下面为准。虽然如果少参数,会导致执行不成功,先这样

rollback_fun(){
for node in $ROLLBACK_LIST;do ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroo/$1 /webroot/web-demo"
done
}

  

注意把脚本最后一行改成main $1 $2
[root@linux-node1 scripts]# tail -10 deploy.sh 
shell_lock;
rollback ${ROLLBACK_VER};
shell_unlock;
;;
*)
usage;
esac

}
main $1 $2
[root@linux-node1 scripts]#

  

继续测试,修改首页内容
[www@linux-node1 web-demo]$ cd /deploy/code/web-demo
[www@linux-node1 web-demo]$ ls
index.html
[www@linux-node1 web-demo]$ cat index.html
www.nmap.com
[www@linux-node1 web-demo]$ echo 'www.nmap.org' >index.html
[www@linux-node1 web-demo]$ cat index.html
www.nmap.org
[www@linux-node1 web-demo]$

  

 

继续执行脚本部署
[www@linux-node1 web-demo]$ cd /scripts/
[www@linux-node1 scripts]$ ./deploy.sh deploy
git pull
code_build
web-demo_456_2017-04-28-21-17-17.tar.gz 100% 222 0.2KB/s 00:00
web-demo_456_2017-04-28-21-17-17.tar.gz 100% 222 0.2KB/s 00:00
HTTP/1.1 200 OK
add to cluster
192.168.58.12.crontab.xml 100% 21 0.0KB/s 00:00
HTTP/1.1 200 OK
add to cluster
[www@linux-node1 scripts]$

 检查页面

自动化部署--shell脚本--2

自动化部署--shell脚本--2

 

列出回滚版本
[www@linux-node1 scripts]$ ./deploy.sh rollback list
-rw-rw-r-- 1 www www 204 Apr 23 23:33 /opt/webroot/web-demo_123_2017-04-23-23-33-50.tar.gz
-rw-rw-r-- 1 www www 204 Apr 23 23:43 /opt/webroot/web-demo_123_2017-04-23-23-43-48.tar.gz
-rw-rw-r-- 1 www www 204 Apr 24 00:00 /opt/webroot/web-demo_123_2017-04-24-00-00-14.tar.gz
-rw-rw-r-- 1 www www 204 Apr 24 00:01 /opt/webroot/web-demo_123_2017-04-24-00-01-24.tar.gz
-rw-rw-r-- 1 www www 205 Apr 24 00:02 /opt/webroot/web-demo_123_2017-04-24-00-02-44.tar.gz
-rw-rw-r-- 1 www www 204 Apr 24 00:04 /opt/webroot/web-demo_456_2017-04-24-00-04-05.tar.gz
-rw-rw-r-- 1 www www 220 Apr 27 21:40 /opt/webroot/web-demo_456_2017-04-27-21-40-36.tar.gz
-rw-rw-r-- 1 www www 214 Apr 27 22:41 /opt/webroot/web-demo_456_2017-04-27-22-41-54.tar.gz
-rw-rw-r-- 1 www www 220 Apr 27 23:17 /opt/webroot/web-demo_456_2017-04-27-23-17-27.tar.gz
-rw-rw-r-- 1 www www 220 Apr 28 20:15 /opt/webroot/web-demo_456_2017-04-28-20-15-56.tar.gz
-rw-rw-r-- 1 www www 220 Apr 28 20:16 /opt/webroot/web-demo_456_2017-04-28-20-16-06.tar.gz
-rw-rw-r-- 1 www www 221 Apr 28 20:24 /opt/webroot/web-demo_456_2017-04-28-20-24-23.tar.gz
-rw-rw-r-- 1 www www 220 Apr 28 20:25 /opt/webroot/web-demo_456_2017-04-28-20-25-47.tar.gz
-rw-rw-r-- 1 www www 220 Apr 28 20:28 /opt/webroot/web-demo_456_2017-04-28-20-28-03.tar.gz
-rw-rw-r-- 1 www www 221 Apr 28 20:35 /opt/webroot/web-demo_456_2017-04-28-20-35-37.tar.gz
-rw-rw-r-- 1 www www 222 Apr 28 20:43 /opt/webroot/web-demo_456_2017-04-28-20-43-32.tar.gz
-rw-rw-r-- 1 www www 221 Apr 28 20:45 /opt/webroot/web-demo_456_2017-04-28-20-45-23.tar.gz
-rw-rw-r-- 1 www www 220 Apr 28 20:48 /opt/webroot/web-demo_456_2017-04-28-20-48-01.tar.gz
-rw-rw-r-- 1 www www 222 Apr 28 21:14 /opt/webroot/web-demo_456_2017-04-28-21-14-49.tar.gz
-rw-rw-r-- 1 www www 222 Apr 28 21:17 /opt/webroot/web-demo_456_2017-04-28-21-17-17.tar.gz
[www@linux-node1 scripts]$

  

回滚上一个版本web-demo_456_2017-04-28-21-14-49
[www@linux-node1 scripts]$ ./deploy.sh rollback web-demo_456_2017-04-28-21-14-49
[www@linux-node1 scripts]$

  

测试访问
自动化部署--shell脚本--2

 

自动化部署--shell脚本--2

 

 回滚成功,此时脚本内容如下

[root@linux-node1 scripts]# cat 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 -p /webroot
#chown -R www:www /deploy
#chown -R www:www /opt/webroot
#chown -R www:www /webroot

#Node List
PRE_LIST="192.168.58.11"
GROUP1_LIST="192.168.58.12"
ROLLBACK_LIST="192.168.58.11 192.168.58.12"

# Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='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"
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}
}

url_test(){
URL=$1
curl -s --head $URL | grep "200 OK"
if [ $? -ne 0 ];then
shell_unlock;
writelog "test error" && exit;
fi
}

shell_unlock(){
rm -f ${LOCK_FILE}
}

code_get(){
writelog "code_get";
cd $CODE_DIR && echo "git pull"
cp -r ${CODE_DIR} ${TMP_DIR}/
API_VER="456"
}

code_build(){
echo code_build
}

code_config(){
writelog "code_config"
/bin/cp -r ${CONFIG_DIR}/base/* ${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 cfz ${PKG_NAME}.tar.gz ${PKG_NAME}
writelog "${PKG_NAME}.tar.gz"
}

code_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 from cluster"
ssh $PRE_LIST "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $PRE_LIST "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}

pre_test(){
url_test "http://${PRE_LIST}/index.html"
echo "add to cluster"
}

group1_deploy(){
writelog "remove from cluster"
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot/ && tar xfz ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
scp ${CONFIG_DIR}/other/192.168.58.12.crontab.xml 192.168.58.12:/webroot/web-demo/crontab.xml
}

group1_test(){
url_test "http://192.168.58.12/index.html"
echo "add to cluster"
}

rollback_fun(){
for node in $ROLLBACK_LIST;do
ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
done
}

rollback(){
if [ -z $1 ];then
shell_unlock;
echo "Please input rollback version" && exit;
fi
case $1 in
list)
ls -l /opt/webroot/*.tar.gz
;;
*)
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
[root@linux-node1 scripts]#

  

 再完善下脚本,rollback的时候,后面参数为空,直接退出。也就是整个脚本的$2 为空,退出脚本

rollback(){
if [ -z $1 ];then
shell_unlock;
echo "Please input rollback version" && exit;
fi
case $1 in
list)
ls -l /opt/webroot/*.tar.gz
;;
*)
rollback_fun $1
esac
}

  

自动化部署实战-gitlab和部署和回滚

 

把gitllab装上,参照链接
 

GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。
GitLab拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。
它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。
1.基础环境准备

[root@linux-node1 ~]# yum install curl policycoreutils openssh-server openssh-clients postfix -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.163.com
* epel: mirror01.idc.hinet.net
* extras: mirrors.aliyun.com
* updates: mirrors.163.com
Package curl-7.29.0-35.el7.centos.x86_64 already installed and latest version
Package policycoreutils-2.5-11.el7_3.x86_64 already installed and latest version
Package openssh-server-6.6.1p1-35.el7_3.x86_64 already installed and latest version
Package openssh-clients-6.6.1p1-35.el7_3.x86_64 already installed and latest version
Package 2:postfix-2.10.1-6.el7.x86_64 already installed and latest version
Nothing to do
[root@linux-node1 ~]#

  

 启动postfix

[root@linux-node1 ~]# systemctl start postfix
[root@linux-node1 ~]#

 

 

2.安装gitlab-ce
注:由于网络问题,国内用户,建议使用163或者阿里云镜像源进行安装:

3.配置并启动gitlab-ce
默认从163的源里下载,清华大学的镜像源makecache时报错
此包286MB,安装时占800MB多。生产中注意下

[root@linux-node1 ~]# yum install gitlab-ce -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.163.com
* epel: mirrors.ustc.edu.cn
* extras: mirrors.163.com
* updates: mirrors.163.com
Package gitlab-ce-9.1.0-ce.0.el7.x86_64 already installed and latest version
Nothing to do
[root@linux-node1 ~]#

  

4.配置并启动gitlab-ce

[root@linux-node1 ~]# gitlab-ctl reconfigure

自动化部署--shell脚本--2

 

可以使用gitlab-ctl管理gitlab,例如查看gitlab状态:
[root@linux-node1 ~]# gitlab-ctl status
run: gitaly: (pid 46783) 154s; run: log: (pid 46524) 194s
run: gitlab-monitor: (pid 46839) 152s; run: log: (pid 46671) 170s
run: gitlab-workhorse: (pid 46793) 154s; run: log: (pid 46537) 188s
run: logrotate: (pid 46570) 186s; run: log: (pid 46569) 186s
run: nginx: (pid 47163) 2s; run: log: (pid 46544) 187s
run: node-exporter: (pid 46627) 179s; run: log: (pid 46626) 179s
run: postgres-exporter: (pid 46826) 153s; run: log: (pid 46657) 171s
run: postgresql: (pid 46369) 233s; run: log: (pid 46368) 233s
run: prometheus: (pid 46811) 153s; run: log: (pid 46607) 180s
run: redis: (pid 46312) 239s; run: log: (pid 46311) 239s
run: redis-exporter: (pid 46642) 177s; run: log: (pid 46641) 177s
run: sidekiq: (pid 46509) 195s; run: log: (pid 46508) 195s
run: unicorn: (pid 46483) 196s; run: log: (pid 46482) 196s
[root@linux-node1 ~]#

一些常用命令

gitlab-ctl status
gitlab-ctl stop
gitlab-ctl start
gitlab-ctl restart

  

先停止apache,因为gitlab占用80端口。防止冲突
[root@linux-node1 ~]# systemctl stop httpd
[root@linux-node1 ~]# gitlab-ctl restart
ok: run: gitaly: (pid 47781) 1s
ok: run: gitlab-monitor: (pid 47788) 0s
ok: run: gitlab-workhorse: (pid 47791) 1s
ok: run: logrotate: (pid 47808) 0s
ok: run: nginx: (pid 47814) 1s
ok: run: node-exporter: (pid 47823) 0s
ok: run: postgres-exporter: (pid 47829) 0s
ok: run: postgresql: (pid 47847) 0s
ok: run: prometheus: (pid 47855) 1s
ok: run: redis: (pid 47866) 0s
ok: run: redis-exporter: (pid 47870) 1s
ok: run: sidekiq: (pid 47877) 0s
ok: run: unicorn: (pid 47882) 1s
[root@linux-node1 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9121 0.0.0.0:* LISTEN 47870/redis_exporte
tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN 47855/prometheus
tcp 0 0 127.0.0.1:9187 0.0.0.0:* LISTEN 47829/postgres_expo
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 1896/rsync
tcp 0 0 127.0.0.1:9100 0.0.0.0:* LISTEN 47823/node_exporter
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 47814/nginx: master
tcp 0 0 127.0.0.1:9168 0.0.0.0:* LISTEN 47788/ruby
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 1346/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 45266/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1284/master
tcp 0 0 0.0.0.0:8060 0.0.0.0:* LISTEN 47814/nginx: master
tcp 0 0 127.0.0.1:25151 0.0.0.0:* LISTEN 3249/python2
tcp6 0 0 :::873 :::* LISTEN 1896/rsync
tcp6 0 0 :::3306 :::* LISTEN 41106/mysqld
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 ::1:9168 :::* LISTEN 47788/ruby
tcp6 0 0 :::22 :::* LISTEN 45266/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1284/master
[root@linux-node1 ~]#