通过shell脚本实现代码自动化部署

一、传统部署方式及优缺点

1.传统部署方式

(1)纯手工scp

(2)纯手工登录git pull、svn update

(3)纯手工xftp往上拉

(4)开发给打一个压缩包,rz上去;解压

2.缺点

(1)全程运维参与,占用大量时间

(2)上线速度慢

(3)人为失误多,管理混乱

(4)回滚慢,不及时

二、环境规划

1、开发环境--开发者本地有自己的环境。

运维需要设置的开发环境,大家共用的服务。

2、测试环境:功能测试环境和性能测试环境。

3、预生产环境:生产环境集群中的某一个节点。

4、生产环境:直接对用户提供服务的环境。

测试环境与生产环境的数据库不一致时,可能会导致测试的功能不全面,在测试环境测无问题,放在线上可能出现问题

三、需求分析

一、功能需求需求

一个集群有十个节点

1.实现 一键部署10个节点

2.一键回滚到任意版本

3.一键回滚到上个版本

二、部署需求

部署:

1.代码在哪里:svn、git

2.获取什么版本代码?

svn/git:直接拉去某个分支
svn:指定版本号
git:指定tag

3.差异解决:

(1)各个节点直接差异:配置文件未必一致(crontab.xml)。预生产节点。

(2)代码仓库和实际的差异。配置文件是否放在代码仓库中。

4.如何更新

更新时需要考虑是否重启。例如java代码,需要考虑重启tomcat。重启过程中,用户就不能访问了。

5.测试

部署多个节点,某个节点由于配置问题导致部署不成功。如何测试。

6.串行和并行

部署多个节点,串行部署还是并行部署,视具体业务需求决定。

7.如何执行

1.shell脚本,直接执行
2.web界面

三、部署流程

1.获取代码(直接拉取)----》 2.编译(可选)----》 3.配置文件放进去----》 4.打包 ----》 

5.SCP到目标服务器----》 6.将目标服务器移除集群----》 7.解压 ----》 8.放置到webroot ----》

9.SCP差异文件 ----》 10.重启(可选) ----》 11.测试 ----》 12.加入集群

四、代码实现

1、设置无交互访问

通过ssh-keygen将部署机的公钥发送给应用服务器。
注意,这里通常是用普通用户登陆部署机,生成公钥后,再把公钥发给应用服务器

ssh-keygen -t rsa

切换到.ssh目录下
[[email protected] ~/.ssh]$ ll
total 16
-rwx------ 1 www www  397 Jul 31 22:45 authorized_keys
-rwx------ 1 www www 1679 Jul 31 22:44 id_rsa
-rwx------ 1 www www  397 Jul 31 22:44 id_rsa.pub

将id_rsa.pub中的内容复制粘贴到应用服务器的www用户的.ssh目录下,
文件名称为authorized_keys

[[email protected] .ssh]$ cat authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqT3VwY9Wo7tKsXa4Ce1zXGLT/Iygy30tDBKnV4HW4g5BdUS48urTvYljL9cwJ/HWvoqbtJ5mc7PMmhDMOAjIh1CRZtGxKEkQFB/Xp5cLeAsE7iH+WfkNqavFHD75+YuM2mbNBvisDXO+/pJ/QfbmYwWJ6CW6uLpQKpitdJwrLpQDJGQv5H3aV0kHKZdoA+twdXm0LmQcWWJt7zruPq19CAXG5b93KTdgyt/1x4BfcT5/+PCaEd9suYwEneI2Io8CX9oTAe3MRyRPtlN0szT89qP/q+Q4sktVjc1nkxHhdP2mahqeiBLUGULfkgUBtEjaGAFSWb+ejFV0fRDHk6bSJ [email protected]

注意,修改authorized_keys的权限
chmod 600 authorized_keys

另外,将.ssh目录的权限设置成700
chmod 700 .ssh

2、详细代码

#!/bin/bash

#Node List
PRE_LIST="192.168.56.11"
GROUP1_LIST="192.168.56.12"
ROLLBACK_LIST="192.168.56.11 192.168.56.12"

#Date/Time Variable
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="/deploy1.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}

}

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 czf ${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
}

cluster_node_remove(){
	writelog  "cluster_node_remove"
}

pre_deploy(){
	writelog "remove from cluster"

        ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $PRE_LIST "rm -rf /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}
url_test(){
	URL=$1
	curl -s --head $URL|grep "200 OK"
	if [ $? -ne 0 ];then
		shell_unlock;
		writelog "test error" && exit;
	fi
}
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 zxf ${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.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 to cluster"
}
rollback_fun(){
	for node in $ROLLBACK_LIST;do
                ssh $node "rm -rf /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_METHON=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHON 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
测试方式

[[email protected] ~]$ curl --head http://192.168.56.11/index.html
HTTP/1.1 200 OK
Date: Mon, 01 Aug 2016 09:42:23 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5
Last-Modified: Mon, 01 Aug 2016 09:39:52 GMT
ETag: "17-538ff61ca0a00"
Accept-Ranges: bytes
Content-Length: 23
Content-Type: text/html; charset=UTF-8

[[email protected] ~]$ curl -s --head http://192.168.56.11/index.html|grep "200 OK"
HTTP/1.1 200 OK

3、回滚

1.列出回滚版本
2.目标服务器移除集群
3.执行回滚
4.重启和测试
5.加入集群

===========
如果是遇到重大bug
1.列出回滚版本
2.执行回滚(重启)

==========
非常紧急
1.直接回滚到上个版本(重启)

自动化部署的核心是创建软链接,同样在回滚的时候也能实现秒级回滚。

如何从git上拉取代码,请听下回分解

时间: 2024-10-10 01:10:08

通过shell脚本实现代码自动化部署的相关文章

shell脚本之全自动化部署PXE

#!/bin/bash #2017-07-21 by max #config pxe #config yum if [ ! -d ~/yum.bak ]; then mv /etc/yum.repos.d/* ~/yum.bak else mkdir ~/yum.bak mv /etc/yum.repos.d/* ~/yum.bak fi cat >/etc/yum.repos.d/server.repo<< EOF [base] name=server baseurl=file:///

利用shell脚本统计代码行数

刚毕业那会儿有一次去一家台湾公司面试,问我写过多少行代码.从没想过这个问题,粗略算了算,随口说道:大概几十万行吧.最近整理资料,看着eclipse左边满满的列表,想起了这个事.倒底总共有多少行代码?--这事如果在windows下要么找工具,要么编程序.又想到linux里的命令统计很方便,于是打算用个命令来完成.可分析来分析去,恐怕一行命令是搞不定的--又涉及递归查找,又涉及指定文件类型,又涉及对文件全路径进行操作.最终还是用了一段shell脚本才达到目的. #!/bin/bash declare

shell脚本--lnmp架构-实战部署

 shell脚本实战                                 ----一键部署LNMP架构 LNMP使用shell实战部署,直接上主题,首先需要准备的包文件,我这里命名为zhunbei的文件. zhunbei文件内容: gcc gcc-c++ automake autoconf libtool make openssl openssl-devel mhash-devel libxslt-devel libjpeg libjpeg-devel libpng libpng-d

Linux Shell脚本之远程自动部署java maven项目

脚本功能: 自动从git上获取java maven项目工程源码,在机器A上build,build完成后,将Class文件和配置文件等上传到机器B,重新启动机器B上的服务以便变更生效. 脚本特点: 1.(与之前的自动部署脚本相比)全新优化了脚本代码,更friendly,结构更紧凑 2.Public header删除了无用或者不好用的有色彩显示函数,并修正了WORKDIR不是绝对路径可能导致的bug 3.修正了域名解析判断是否正常的一个bug,该bug可能导致遇到无法解析后不断尝试解析 4.全新的m

使用开源my-deploy工具实现开发环境的代码自动化部署

@编者按: 由于公司内部存在的开发系统:内网开发--外网预发布--外网生产环境,程序员频繁的更新代码造成运维人员大量时间被占用,于是有了使用该开源工具的部署测试环节.在这里感谢该开源工具的作者,也希望我这边文档能多少帮助需要类似开发环境的技术人员. 1.部署: 开源项目地址:https://github.com/kelvv/my-deploy 操作视频教程:http://v.youku.com/v_show/id_XMTYxMjc0ODg3Mg==.html 基础环境:node 4.X.X以上版

自动化部署java maven项目到多个目标主机的Shell脚本

本篇是<Linux Shell脚本之远程自动化部署java maven项目>的姊妹篇,但包含了bug.issue修正和添加了更多的支持特性,可以从GitHub上获取最新脚本内容:https://github.com/DingGuodong/AutomaticDeployJavaMavenProject . 自动化部署java maven项目到多个主机的环境条件假设: 1.java maven项目至多有一个依赖项目 2.多个目标主机上的部署目录是相同的 支持特性: 1.在部署主机上将java m

利用Fabric+Capistrano实现Python自动化部署

Fabric是一个用于应用(批量)部署和系统(批量)管理的Python库和命令行工具,关于Fabric的介绍请参考:http://www.fabfile.org/. Capistrano是一个用Ruby语言编写的远程服务器自动化和部署工具,关于Capistrano的介绍请参考:http://capistranorb.com/. 本文仅使用Python语言和部分Linux或Windows系统命令,借助Fabric模块和Capistrano的部署思路,实现在Linux平台和Windows平台的自动化

运维与自动化系列③自动化部署基础与shell脚本实现

自动化部署基础与shell脚本实现 关于自动化的基础知识: 1.1:当前代码部署的实现方式: 运维纯手工scp到web服务器纯手工登录git服务器执行git pull或svn服务器执行svn update更新代码通过xftp上传代码开发打压缩包上传到服务器然后解压 缺点:1.需要运维全程参与,占用大量的工作时间2.上线时间比较慢3.人为造成的失误较多,管理比较混乱4.回滚复杂而且慢,还不及时 1.2:运行环境规划:开发环境:开发者本地有自己的环境,然后运维需要设置开发环境的公用服务,例如开发数据

自动化运维Ansible批量部署服务+shell脚本批量推送公钥

一.概述分析 由于互联网的快速发展导致产品更新换代速度逐渐加快,运维人员每天都要进行大量的维护操作,仍旧按照传统方式进行维护会使得工作效率低下.这时,部署自动化运维就可以尽可能安全.高效地完成这些工作.一般会把自动化运维工具划分为两类:一类是需要使用代理工具的,也就是基于专用的ABem程序来完成管理功能,如: Puppet.Func. Zabbix等:另外一类是不需要配置代理工具的,可以直接基于SSH服务来完成管理功能,如: Ansible. Fabric等. - 下面介绍几款功能类似的自动化运