自动化部署难驾驭,分分钟拯救你的运维体系

笔者Q:552408925、572891887

架构师群:471443208

bjstack运维社区:524721466

有任何疑问请加群互动,或上社区发帖bjstack运维社区 bjstack.com

1.1早期手动部署代码

    1.纯手动scp上传代码。
    2.纯手动登陆,git pull 或者svn update。
    3.纯手动xftp上传代码。
    4.开发发送压缩包,rz上传,解压部署代码。
    缺点:
        1.全程运维参与,占用大量时间。
        2.如果节点多,上线速度慢。
        3.人为失误多,目录管理混乱。
        4.回滚不及时,或者难以回退。

1.2设计自动部署代码

流程设计,确定目标.

1.2.1自动部署环境

1.开发环境
        开发者本地有自己的环境,运维配置公共开发环境,大家可共用的服务。例如:开发数据库MySQL,redis,Memcached等
2.测试环境
        功能测试以及性能测试。
3.预生产环境
        生产环境集群中的某一个节点,并且连接生产库。(不对外,不做破坏型操作。)
4.灰度环境
        根据不同的区域进行划分分。(生产环境)
5.生产环境
        对用户提供服务的环境。
        
预生产环境由来:
    1.数据库不一致,测试环境和生产环境数据库是不一样的。
    2.使用生产环境的联调接口;例如:支付接口。(电商业务)

1.2.1自动部署规划

  1.已经有一个可以上线的代码在git仓库。
    2.我们现在要做10个集群节点的一键部署,秒级回滚。
    3.所有的web服务,都应该使用普通用户。(强烈建议)
    4.所有的web服务都不应该监听80端口,除了负载均衡。
    5.那我们如何设计一套生产自动化部署系统。

1.规划。
2.实现。
3.总结和扩展。(PDCA方法论)
4.生产环境应用。

实现思路:

1.代码放置位置

        Git(首先)、Svn

2.获取最新代码

        1.git pull获取最新分支(更新非常频繁,没有特别严格的项目管理团队。)
        2.git tag 获取指定标签版本(更新没有那么频繁,有一定的项目管理的团队。)
        3.git commit获取指定版本号

3.差异解决

        1.各个节点之间差异
        2.代码仓库和实际的差异。配置文件是否放在代码仓库中。(配置单独进行存放,config.example )短信接口,支付,等敏感信息不让所有开发知道
        3.统一的.集群有10个节点。(Job节点 crontab.xml 配置文件不一样)

4.项目名称如何设计。

        项目名称_环境名称_版本_分支_时间_某开发提交
        测试: rainbow_test_v1.1.1_dev_2016-08-11_12:12_xuliangwei
        生产: rainbow_pro_v1.1.1_master_2016-08-11_11:11_xuliangwei
        
5.如何更新。

        php,tomcat需要重启,重新软链接。

6.如何测试。

        测试(关键的页面,API,后台等)
        测试一个预生产环境,通过则继续部署,如果失败,退出部署操作。

7.记录日志。

        可以部署统计。
        成功多少次。
        失败多少次。
        回滚多少次。

8.多人同时执行脚本。

        防止多人操作导致重复上线失败。通过lock锁对文件进行控制。

9.串行,并行。

        机器少的情况串行感觉不出什么。如果机器过多则会很慢。
        分组部署并行部署,以及分组测试。
        测试一个预生产环境,通过则继续部署,如果失败,退出部署操作。

10.部署服务器双机。

        防止部署系统down机,部署机代码丢失,误操作。

11.如何执行。  

        1.shell执行
        2.web界面点击(自定义或jenkins)

12.如何实现正常回退,以及紧急回退(回滚的必要性)。

        通过软链接的方式来实现代码秒级别回退。

1.2.1自动部署难点

在大公司推进自动化部署上线,是有许多的难点,根据个人公司的不同,来选择不同的方法来进行推进。

自动化推进难点:

    1.能力(个人能力,团队能力)
    2.责任(责任能否承担,敢于承担责任)
    3.公司流程、人员、组织架构。

可通过如下方法推进:

    1.目标化沟通。
    2.责任划分 
    3.ITIL
    4.项目管理:PMBOOK

1.3自动部署实践

整个集群自动化部署流程设计如下:

    1.获取最新代码
    2.编译(可选)
    3.配置文件(软连接或者拷贝)。
    4.打包(tar,加速传输)
    5.文件分发(Scp Rsync Salt)(不需要密码验证)
    6.将目标服务器移除集群(注释配置文件)
    7.解压
    8.防止webroot站点目录
    9.scp差异文件(可能有一个节点配置文件不一样)
    10.重启Web服务
    11.测试

1.4正常回退实践

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

1.5紧急回退实践

1.列出回滚版本(ls -l或find查出对应的历史版本)。
2.执行回滚操作(删除软链接,重建软链接)。
3.重启对应服务。

1.6自动部署采坑

自动化部署php环境或者java环境的过程中,那么你一定遇到了如下的问题。

1.如何应用到你的生产环境。

2.回退到“上一个”“正常”版本。

3.自动部署软连接的坑。

1.PHP如果开启Opcache,需要重启PHP,或者清理opcache

2.Java Tomcat是必须要重启,最好每次清理work,tmp缓存目录。

自动化系统构建实践-运维体系

1.1环境准备

首先在执行脚本前,先做好初始化环境,最好是通过saltstack来完成。我这里没有那么多机器,就先用两台演示。

linux-node1 192.168.90.201

linux-node2 192.168.90.202

1.创建普通用户

useradd xuliangwei
passwd xuliangwei

2.配置密钥

[[email protected] ~]# su - xuliangwei #切换至普通用户
[[email protected] ~]$ ssh-keygen -t dsa #生成密钥
Generating public/private dsa key pair.
Enter file in which to save the key (/home/xuliangwei/.ssh/id_dsa):  #默认回车一路
/home/xuliangwei/.ssh/id_dsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/xuliangwei/.ssh/id_dsa.	#这是钥匙
Your public key has been saved in /home/xuliangwei/.ssh/id_dsa.pub.	#这是锁
The key fingerprint is:
39:6f:d8:42:61:d7:c3:f9:4b:e7:fb:b0:af:52:cd:59 [email protected]
The key‘s randomart image is:
+--[ DSA 1024]----+
|                 |
|           o .   |
|        o . =    |
|       . +   o  E|
|        S     oo+|
|       . =   ..=o|
|        o +  .o .|
|         o  .  o.|
|             .o++|
+-----------------+
[[email protected] ~]$ ssh-copy-id -i ~/.ssh/id_dsa.pub [email protected]  #公钥分发给其他服务器
[email protected]‘s password: 
Now try logging into the machine, with "ssh ‘[email protected]‘", and check in:
  .ssh/authorized_keys
to make sure we haven‘t added extra keys that you weren‘t expecting.
[[email protected] ~]$ ssh -p22 [email protected] 		#使用xuliangwei用户登录node2节点服务器
Last login: Wed Aug 10 17:59:02 2016 from 192.168.90.201
[[email protected] ~]$	#成功登录

3.创建相关目录

mkdir /deploy/
mkdir -p /deploy/code/rainbow_pro
mkdir -p /deploy/source/rainbow_pro
mkdir -p /deploy/config/rainbow_pro/config
mkdir -p /deploy/config/rainbow_pro/admin_config
mkdir -p /deploy/tmp
mkdir -p /home/xuliangwei/webroot
chown -R www:www /deploy
chown -R www:www /home/xuliangwei/webroot

4.配置Nginx

user xuliangwei;  #指定用户
root  /home/xuliangwei/webroot/rainbow_pro; #指定项目路径

5.配置好git环境

1.[centos7部署gitlab][https://about.gitlab.com/downloads/#centos7]
2.克隆项目可参考 [git远程仓库创建与建立][http://www.bjstack.com/thread-25-1-1.html]
3.最终效果如下:
[[email protected] ~]$ ll /deploy/source/rainbow_pro/
总用量 4
-rw-rw-r-- 1 xuliangwei xuliangwei   34 8月  12 18:05 index.html

1.2剖析脚本  配合上文来进行

[[email protected] ~]$ cat deploy.sh
#!/bin/bash

# useradd xuliangwei  && sshkey需认证
# Nginx 权限必须让xuliangwei用户可访问

# Dir List
# mkdir -p /deploy/code/rainbow_pro  # web code的仓库
# mkdir -p /deploy/source/rainbow_pro #存放git源码仓库
# mkdir -p /deploy/config/rainbow_pro/config  #存放config信息
# mkdir -p /deploy/config/rainbow_pro/admin_config  #存放后台config信息
# mkdir -p /deploy/tmp

# Web Root Dir
# mkdir -p /home/xuliangwei/webroot

# chown web
# chown -R www:www /deploy
# chown -R www:www /home/xuliangwei/webroot

# Code Env
PRO_NAME="rainbow_pro"
CODE_DIR="/deploy/code/$PRO_NAME"
SOURCE_DIR="/deploy/source/$PRO_NAME"
CONFIG_DIR="/deploy/config/$PRO_NAME"
WEB_DIR="/home/xuliangwei/webroot"
TMP_DIR="/deploy/tmp"

# Node List
PRE_LIST="192.168.90.201"
GROUP1_LIST="192.168.90.202"
ROLLBACK_LIST="192.168.90.201 192.168.90.202"

# Date/Time Veriables
CTIME=$(date "+%F-%H-%M")

# Shell Env
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/xuliangwei/webroot"

# Log
LOG_FILE="${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  "test error" && exit;
	fi
}

# log 
writelog(){
    LOGINFO=$1
    echo "${CTIME}: ${SHELL_NAME} : ${LOGINFO}" >> ${LOG_FILE}
}

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="${CTIME}_${GIT_CID}"
	PKG_NAME="${PRO_NAME}_${PKG_VER}"
	cp -r ${SOURCE_DIR} ${TMP_DIR}/${PKG_NAME}
}

code_bulid(){
	echo code_bulid #由于php没有编译过程
}

code_config(){
	writelog "code_config"
	/bin/cp -r ${CONFIG_DIR}/config.php ${TMP_DIR}/${PKG_NAME}/config.php
}

code_tar(){
	writelog "code_tar"
	cd ${TMP_DIR} && tar czf ${PKG_NAME}_tar.gz ${PKG_NAME} --exclude=.git --exclude=.gitignore
	writelog "${PKG_NAME}_tar.gz"
}

code_scp(){
	writelog "code_scp"
	for node in $PRE_LIST;do
		scp ${TMP_DIR}/${PKG_NAME}_tar.gz $node:${TMP_DIR}/
	done

	for node in $GROUP1_LIST;do
		scp ${TMP_DIR}/${PKG_NAME}_tar.gz $node:${TMP_DIR}/
	done

}

pre_deploy(){
	writelog "remove from cluster"
	ssh $PRE_LIST "cd ${TMP_DIR} && tar xf ${PKG_NAME}_tar.gz -C ${CODE_DIR}/"
	ssh $PRE_LIST "rm -f $WEB_DIR/${PRO_NAME} && ln -s ${CODE_DIR}/${PKG_NAME} $WEB_DIR/${PRO_NAME}"
}

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

group1_deploy(){
        writelog "remove from cluster"
	for node in $GROUP1_LIST;do
        	ssh $node "cd ${TMP_DIR} && tar xf ${PKG_NAME}_tar.gz -C ${CODE_DIR}/"
        	ssh $node "rm -f $WEB_DIR/${PRO_NAME} && ln -s ${CODE_DIR}/${PKG_NAME} $WEB_DIR/${PRO_NAME}"
	done
   #scp ${CONFIG_DIR}/other/192.168.90.201.crontab.xml 192.168.90.201:/$WEB_DIR/${PRO_NAME}/crontab.xml 额外不一样的配置可能需要用到
}

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

code_reload(){
	systemctl restart php-fpm  #重启php清楚opcode缓存
}

rollback_list(){
  for node in $GROUP1_LIST;do
        ssh $node ls -l "$WEB_DIR" &&        ssh $node find "$CODE_DIR/" -maxdepth 1 -mtime -2|sed 1d|awk -F ‘/‘ ‘{print $5}‘
        #find "$CODE_DIR" -type d -name "$PRO_NAME*" -mtime +30|xargs rm -fr
  done
}

rollback_fun(){
  if [ -z $ROOLBACK ];then
	shell_unlock;
	echo "Please input rollback version" && exit;
else
	for node in $ROLLBACK_LIST;do
	ssh $node rm -f $WEB_DIR/${PRO_NAME} && 	ssh $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_bulid;
		code_config;
		code_tar;
		code_scp;
		pre_deploy;
		pre_test;
		group1_deploy;
		group1_test;
	#	group2_deploy;
	#	group2_test;
		shell_unlock;
		;;
	list)
	rollback_list;
		;;
	rollback)
		shell_lock;
		rollback_fun $ROLLBACK;
		shell_unlock;
		;;
	*)
		echo "$Usage:$0 [ deploy | list | rollback ]"
	esac
}

main "$1" "$2"

执行上线:

[[email protected] ~]$ sh deploy.sh deploy
Already up-to-date.
code_bulid
rainbow_pro_2016-08-12-21-16_46236b_tar.gz                                     100% 6016KB   5.9MB/s   00:00
rainbow_pro_2016-08-12-21-16_46236b_tar.gz                                     100% 6016KB   5.9MB/s   00:00
rainbow_pro_2016-08-12-21-16_46236b_tar.gz                                     100% 6016KB   5.9MB/s   00:00
HTTP/1.1 200 OK
Rre add to cluster
HTTP/1.1 200 OK
HTTP/1.1 200 OK
group1_node add to cluster
php-fpm restart

查看当前版本

[[email protected] ~]$ sh deploy.sh list
总用量 16
lrwxrwxrwx 1 xuliangwei xuliangwei    60 8月  12 21:16 rainbow_pro -> /deploy/code/rainbow_pro/rainbow_pro_2016-08-12-21-16_46236b
rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-21-16_46236b
总用量 0
lrwxrwxrwx 1 xuliangwei xuliangwei 60 8月  12 21:16 rainbow_pro -> /deploy/code/rainbow_pro/rainbow_pro_2016-08-12-21-16_46236b
rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-21-16_46236b

执行回滚操作

[[email protected] ~]$ sh deploy.sh rollback #直接执行是不允许的
Please input rollback version
[[email protected] ~]$ sh deploy.sh rollback rainbow_pro_2016-08-12-19-24_46236b #这个操作一定要配合list来做。

查看已经回退到19点的版本
[[email protected] ~]$ sh deploy.sh list
总用量 16
-rw-rw-r-- 1 xuliangwei xuliangwei 14224 8月  12 21:16 deploy.sh.log
lrwxrwxrwx 1 xuliangwei xuliangwei    60 8月  12 21:18 rainbow_pro -> /deploy/code/rainbow_pro/rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-21-16_46236b
总用量 0
lrwxrwxrwx 1 xuliangwei xuliangwei 60 8月  12 21:18 rainbow_pro -> /deploy/code/rainbow_pro/rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-19-24_46236b
rainbow_pro_2016-08-12-21-16_46236b

查看日志:

[[email protected] ~]$ cat webroot/deploy.sh.log
2016-08-12-21-35: deploy.sh : code_get
2016-08-12-21-35: deploy.sh : code_config
2016-08-12-21-35: deploy.sh : code_tar
2016-08-12-21-35: deploy.sh : rainbow_pro_2016-08-12-21-35_46236b_tar.gz
2016-08-12-21-35: deploy.sh : code_scp
2016-08-12-21-35: deploy.sh : remove from cluster
2016-08-12-21-35: deploy.sh : remove from cluster

1.3脚本其他功能

当然此脚本功能不仅仅如此,可以通过git分支,git tag包等方式来上线,这些根据贵公司的具体业务来进行调整,也可以自己开发一个web界面来调用此脚本,这样就可以将上线工作交给开发,当然也可以使用开源jenkins来实现。

1.4后期更新

(如上脚本)+gitlab+jenkins+Sonar 构建自动化部署代码,并代码发布前质量管理

笔者Q:552408925、572891887

架构师群:471443208

bjstack运维社区:524721466

有任何疑问请加群互动,或上社区发帖[bjstack运维社区][http://bjstack.com]

时间: 2024-11-05 21:50:28

自动化部署难驾驭,分分钟拯救你的运维体系的相关文章

从零到一 | 如何搭建数据库自动化运维体系

需求背景: 随着业务的增长.对运维效率和质量的要求不断提高,对自动化运维体系的需求也不断增强. 目前笔者服务的很多中大型企业客户,运维其实还停留在“刀耕火种”的原始状态. 这里所说的“刀”和“火”就是运维人员的远程客户端,例如 xshell 和Windows 远程桌面. 这种工作模式有很多局限性, 比如服务器.数据库.中间件等的安装.初始化,应用软件部署.服务发布和监控都是通过手动方式来完成的. 这就需要运维人员登录到服务器上,一台一台去管理和维护. 如果有个几十上百台,累就累死人了. 笔者曾运

SaltStack (1)运维自动化部署

运维自动化saltstack是一个轻量简洁的运维自动化软件,下面说一下我的安装过程: 首先第一步就是关闭你的防火墙或者是selinux,如果开启的话就给开放个端口. 一:master和agent端软件安装 master 控制端: rpm -Uvh http://ftp.linux.ncsu.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm yum update yum install salt-master /etc/init.d/salt-mast

[转载]运维自动化201009

运维趋势 第 0 期 运维自动化 [人物]基于开源服务的运维自动化实现 [国际前沿]什么是 DevOps ? [运维漫画阁]正则表达式有什么用? [命令行 & 工具]面向 Linux 系统管理员的开源工具链 [命令行 & 工具]自动化开源工具一览 [实战] Kickstart 无人值守安装搭建 RHCE 实验室 [实战]戏说 Cobbler : Linux 网络安装的革命 1  [人物]运维专家李洋:漫谈基于开源服务的运维自动化实现 随着各种业务对 IT 的依赖性渐重以及云计算技术的普及,

游戏运维的最佳实践:搜狐畅游自动化运维之旅!

搜狐黎志刚见证了畅游游戏自动化运维平台的从无到有,通过在其中踩过的坑.解过的结,他向大家来阐述游戏运维的进阶之路.本文主要围绕畅游游戏管理体系与运维自动化的演变历程.运维自动化的实现及未来运维四方面展开. 畅游运维管理体系与运维自动化的演变历程 畅游运维管理体系演变历程 从 2008 年毕业以实习生的身份进入搜狐畅游,我同公司一起成长,经历了整个运维管理体系从小到大的过程. 整个运维管理体系是从最初石器时代(脚本化),之后的青铜时代(半自动化).蒸汽时代(DevOPS)一路演变过来,现在处于自动

[运维] 第三篇:漫谈数据中心运维自动化

运维自动化是从2010年以后起来的一个运维需求,10年之前,运维项目主要集中在监控和ITIL流程上,当时也有BMC Control-M等产品在推,但是客户接受程度和影响力不如监控和流程.10年之后,运维自动化提上日程,建行开始招运维自动化的标,IBM.BMC.HP都纷纷参与,测了三轮,最后HP opsware中标,只能说一句厉害!工商银行也在自己组织服务商做自己特色的运维自动化平台,做了3.4年,基本成型,服务商也做出了自己的运维自动化产品,正式推向市场.当时运维自动化的主要功能是五项:自动化巡

漫谈自动化运维——实现标准化

自动化介绍 和大数据.云计算一起热火朝天的就是自动化运维了,然后就有了现在很火的职位DevOps.各个培训机构雨后春笋般,推出了Python自动化运维培训.不知道培训的效果怎样.但是感觉有点误导的意味. 有个朋友参加了某培训机构的Python自动化运维培训,培训完后就给我说他要做自动化运维.当时我就懵圈了,在想他都没做过运维就培训了下Python,然后直接可以实现自动化运维了.仔细聊了以下,原来是他想多了,他所说的只是实现了自动化最后的一步--平台化. 所谓运维自动化就是将日常运维中大量的重复性

构建高效的研发与自动化运维

为什么IT运维需要自动化?  所谓IT运维管理的自动化是指通过将日常IT运维中大量的重复性工作,小到简单的日常检查.配置变更和软件安装,大到整个变更流程的组织调度,由过去的手工执行转为自动化操作,从而减少乃至消除运维中的延迟,实现"零延时"的IT运维.简单的说,IT运维自动化是指基于流程化的框架,将事件与IT流程相关联,一旦被监控系统发生性能超标或宕机,会触发相关事件以及事先定义好的流程,可自动启动故障响应和恢复机制.自动化工作平台还可帮助IT运维人员完成日常的重复性工作(如备份,杀毒

浅谈自动化运维

关于这篇文章,源自于很久之前学习产品时的一个认知. 大家都知道"自动化运维"其实是一个很广泛的概念,其概念的不确定性在于"自动化",有争议的地方在于"自动化"到什么程度,才能称之为"自动化运维". 运维工程师: 运维工程师(Operations)在国内又称为运维开发工程师(Devops),在国外称为 SRE(Site Reliability Engineering).负责维护并确保整个服务的高可用性,同时不断优化系统架构.提升

2016全球运维大会,优云蒋君伟演讲“CMDB+自动化的管理融合”成一大亮点

2016全球运维大会于9月23日-24日在上海盛大开幕.作为国内运维行业的重量级大会,优云产品总监蒋君伟在自动化专场与来自全国各地的运维同行一起探讨.分享业内自动化运维的最佳实践.现场情绪热烈,气氛高涨,成为了本届全球运维大会的一大亮点. 全新梳理自动化与CMDB的融合之道 全球运维大会当天,运维自动化专场很多大牛针对自动化运维管理中的CMDB进行了激烈的讨论.来自优云软件的产品总监蒋君伟关于<CMDB+自动化的管理融合>作了精彩的主题演讲.蒋君伟提出了一个观点:“CMDB建设一定要以消费场景