使用shell脚本完成自动化部署及秒级回滚
一、部署机代码目录结构
使用www用户进行代码部署,所有部署机上需要创建www用户,并赋予根目录权限,同时配置公私钥认证建立信任关系。
[www@ansible-node1 deploy]$ tree
.
├── code
│?? └── web-demo #存放代码
│?? ├── index.html
│?? └── \\\
├── config #存放服务器配置文件
│?? └── web-demo
│?? ├── base
│?? │?? └── config.ini
│?? └── other
│?? └── 192.168.226.130.crontab.xml #不同机器之间的差异匹配值文件
├── tar
└── tmp
二、部署节点
ip:192.168.226.130、192.168.226.132 分别模拟两个主机组来部署不同代码
web根目录: /webroot/webdemo、同时赋予www用户权限
历史代码版本保存路径: /opt/webroot、同时赋予www用户权限
三、使用gitlab来管理代码(在此不做介绍)
四、主要作用
通过脚本,模拟线上环境,实现代码的半自动化部署,以及秒级回滚。
五、脚本实现
流程:获取代码(直接拉取)-----> 编译(可选)-------> 配置文件 ------>打包 -----> scp到目标服务器---->将目标机服务器移除集群----->解压---->放置到webroot----->scp差异文件----->重启(可选)----->测试----->加入集群
[www@ansible-node1 ~]$ cat deploy.sh
#!/bin/bash #Node List
GROUP1_LIST="192.168.226.130"
GROUP2_LIST="192.168.226.132"
ROLLBACK_LIST="192.168.226.130 192.168.226.132" #Date/Time Veriables
LOG_DATE=`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"
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=$
echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
} shell_lock(){
touch ${LOCK_FILE}
} shell_unlock(){
rm -rf ${LOCK_FILE}
} code_get(){
writelog code_get
cd $CODE_DIR && git pull #需要提前从git仓库clone代码到部署机代码存放目录$CODE_DIR
cp -r ${CODE_DIR} ${TMP_DIR}/
API_VERL=$(git show | grep commit | cut -d ' ' -f2)
API_VER=$(echo ${API_VERL::})
} code_build(){
echo code_build
} code_config(){
echo 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 czf ${PKG_NAME}.tar.gz ${PKG_NAME}
writelog "${PKG_NAME}.tar.gz"
} 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 } cluster_node_remove(){
writelog "iluster_node_remove"
} url_test(){
URL=$1
curl -s --head $URL | grep "200 OK"
if [ $? -ne 0 ];then
shell_unlock;
writelog "test error" && exit;
fi
} group1_deploy(){
echo code_deploy
for node in $GROUP1_LIST;do
ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -sf /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
} group1_test(){
url_test "http://192.168.226.130/index.html"
echo "add to cluster"
}
group2_deploy(){
echo code_deploy
for node in $GROUP2_LIST;do
ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
ssh $node "rm -rf /webroot/web-demo && ln -sf /opt/webroot/${PKG_NAME} /webroot/web-demo"
done
} group2_test(){
url_test "http://192.168.226.132/index.html"
echo "add to cluster"
} config_diff(){
echo config_diff
scp ${CONFIG_DIR}/other/192.168.226.130.crontab.xml 192.168.226.130:/webroot/web-demo/crontab.xml
} code_test(){
echo code_test
} cluster_node_in(){
echo cluster_node
} rollback_fun(){
for node in $ROLLBACK_LIST;do
ssh $node "rm -rf /webroot/web-demo && ln -sf /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)
ssh $GROUP1_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;
cluster_node_remove;
group1_deploy;
config_diff;
group1_test;
group2_deploy;
group2_test;
cluster_node_in;
shell_unlock;
;;
rollback) shell_lock
rollback $ROLLBACK_VER;
shell_unlock;
;;
*)
usage;
esac
}
main $1 $2
六、执行脚本
[www@ansible-node1 ~]$ bash deploy.sh
Usage: deploy.sh {deploy | rollback [ list | version]}
[www@ansible-node1 ~]$ bash deploy.sh deploy #部署代码 [www@ansible-node1 ~]$ bash deploy.sh rollback list #列出代码版本
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz
-rw-rw-r-- www www Mar : /opt/webroot/web-demo_123_2018-----.tar.gz [www@ansible-node1 ~]$ bash deploy.sh rollback web-demo_3d9c99_2018----- #回滚到指定版本
使用shell脚本完成自动化部署及秒级回滚的更多相关文章
- kubernetes云平台管理实战: 滚动升级秒级回滚(六)
一.nginx保证有两个版本 1.查看当前容器运行nginx版本 [root@k8s-master ~]# kubectl get pod -o wide NAME READY STATUS REST ...
- Shell脚本,自动化发布tomcat项目【转载】
Shell脚本,自动化发布tomcat项目脚本. 1. vko2c_auto_build_by_scp.sh 文件内容: #---------------------start------------ ...
- Shell脚本,自动化发布tomcat项目【转】
Shell脚本,自动化发布tomcat项目脚本. 1. vko2c_auto_build_by_scp.sh 文件内容: #---------------------start------------ ...
- Dubbo入门到精通学习笔记(二):Dubbo管理控制台、使用Maven构建Dubbo的jar包、在Linux上部署Dubbo privider服务(shell脚本)、部署consumer服务
文章目录 Dubbo管理控制台 1.Dubbo管理控制台的主要作用: 2.管理控制台主要包含: 3.管理控制台版本: 安装 Dubbo 管理控制台 使用Maven构建Dubbo服务的可执行jar包 D ...
- 使用shell脚本来自动化处理我们的工作,解放双手
Shell脚本介绍 1.Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合. 2.Shell可以直接使用在wi ...
- Jenkins+maven+gitlab+shell实现项目自动化部署
确认jdk , maven,git这些已经在服务器上搭建成功,gitlab使用的是公司服务也没有进行搭建 下面是jenkins的两种搭建方式 1. 第一种比较简单下载对应jenkins.wa ...
- shell脚本编写nginx部署脚本
下面为shell脚本编写的nginx的安装及修改nginx.conf的脚本,脚本比较简单: #!/bin/bash function yum_install(){ yum install epel-r ...
- nginx之热部署,以及版本回滚
热部署的概念:当从老版本替换为新版本的nginx的时候,如果不热部署的话,会需要取消nginx服务并重启服务才能替换成功,这样的话会使正在访问的用户在断开连接,所以为了不影响用户的体验,且需要版本升级 ...
- shell脚本编写-自动部署及监控
1.编写脚本自动部署反向代理.web.nfs: I.部署nginx反向代理两个web服务,调度算法使用加权轮询 II.所有web服务使用共享存储nfs,保证所有web都对其有读写权限,保证数据一致性: ...
随机推荐
- Thread 和 Runnable
Thread 和 Runnable 1. 简介 Java 主要是通过 java.lang.Thread 类以及 java.lang.Runnable 接口实现线程机制的. Thread 类为底层操作系 ...
- C# 批量设置窗体中控件状态的方法
在开发中常遇到当点击某个按钮的时候,禁用文本框或按钮的的状态,以防止误操作,下面的代码是我已批量设置指定控件中的按钮状态的代码,同理可以延伸出很多操作. /// <summary> /// ...
- list 字符串拼接效率实验
ist 字符串拼接有多种方法,我就其中常用三种做了实验,实验代码如下: 第一次是为了初始化静态方法,后面的才是效率比较. 结果如下: StringUtils join 方法用的是StringBuild ...
- 6.移动端自动化测试-小知识 if __name__==’__main__:是什么意思?
1 引言 在Python当中,如果代码写得规范一些,通常会写上一句“if __name__==’__main__:”作为程序的入口,但似乎没有这么一句代码,程序也能正常运行.这句代码多余吗?原理又在哪 ...
- 6.AOP配置与应用(xml的方式)
xml 配置 AOP 1.将 拦截其器对象 初始化到容器中 2.<aop:config> <aop:aspect.... <aop:pointcut <aop:befor ...
- 英语是学习Java编程的基础吗
就当前市场行情需求来看,Java人才需求依旧火爆,在如今互联网时代,手机移动端的软件开发是非常重要的,如今无论是大中小企业都是需要进行软件的开发的,又因为Java是开源的使用起来可以节约一大批的成本, ...
- SQLite3学习笔记(1)
命令: DDL-数据定义: CREATE -- 创建一个新的表,一个表的视图,或者数据库中的其他对象 ALTER -- 修改数据库中的某个已有的数据对象,比如一个表 DROP -- 删除整个表,或者表 ...
- ACM中值得注意/利用的C++语法特性
C++ 的易踩坑点 随时补充 STL不能边循环边erase() //自己写的求交集RE了 for (set <int> ::iterator it = s.begin(); it != s ...
- set调用add报错:
Map<String, String> goodsStandMap = new HashMap<>();goodsStandMap.put("key1", ...
- okhttp拦截器之ConnectInterceptor解析
主流程分析: 继续分析okhttp的拦截器,继上次分析了CacheInterceptor缓存拦截器之后,接下来到连接拦截器啦,如下: 打开看一下它的javadoc: 而整个它的实现不长,如下: 也就是 ...