传统部署方式

1、纯手工scp

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

3、纯手工xftp往上拉

4、开发给打一个压缩包,rz上去。解压

传统部署缺点:

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

2、上线速度慢。

3、认为失误多。管理混乱

4、回滚慢,不及时

新项目上线,规划排在第一位

一般银行都不提供测试接口。比如一些电商公司测试的话,经常把商品调节成1分,只能特定账号能看到。

环境的规划

1、开发环境-开发者本地有自己的环境,然后运维需要设置的开发环境,放的是大家共用的服务。如开发数据库mysql,其它:redis、Memcached。

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

3、预生产环境:一般可以用生产环境中的某个节点担任

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

预生产环境产生的原因:

1、数据库不一致:测试环境和生产环境数据库肯定不一样的。

2、使用生产环境的联调接口。例如,支付接口

预生产环境--生产环境--灰度发布

灰度发布:

阿里云产品上线,都是一个区一个区上的。肯定不是一下子都上的

qq弹窗:恭喜你获得某某版本资格,请下载新版本享用,你就是小白鼠,这个也是一种灰度发布

规划

已经有一个可以上线的代码在代码仓库。我们如何设计一套生产自动化部署系统。

1、规划

2、实现

3、总结和扩展。PDCA

4、在生产环境应用

自动化部署系统的规划

需求:

1个集群有10个节点。一键部署这10个节点。

2、一键回滚到任意版本

3、一键回滚到上个版本

部署:

1、代码放在哪里:svn,git

2、获取什么版本代码?

svn+git直接拉去某个分支

svn:指定版本号

git:指定tag

3、差异解决:

(1)、各个节点直接差异:

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

(3)、配置文件未必一样:crontab.xml预生产节点

4、如何更新。java tomcat。需要重启。

5、测试。

6、串行和并行 分组部署

7如何执行。(1)shell执行。(2)web界面

关于配置文件存放:

配置文件放代码仓库里,岂不是所有开发都能连数据库了。

因此配置文件不能放git里。

有的人把配置文件放某个分支里。让一些人没法看到

我觉得可以单独有个放配置文件的git

腾讯蓝鲸:我帮你做个平台,你写个脚本,我帮你发布到某个机器上,你通过平台帮你执行

一些公司现在的运维,不管任何发布,都是做好界面,让项目负责人去通过界面管理

关于差异文件:

可能有些节点有特殊的差异性文件

自动化部署流程设计


自动化部署实战-shell函数

环境准备

系统版本

主机名和IP

两台web服务器,node1和node2作为两个web服务器,同时node1也作为部署分发服务器,去管理2个node节点上的web包

两个节点添加普通用户www,作为web服务器管理用户。

配置www用户登录其他机器不用密码。密钥认证。以后www用户作为管理其它机器的用户

查看公钥

node2也添加node1的公钥

改成600权限才能正常登录

登录测试--成功

让node1的www用户ssh自己也不需要输入密码。

node1添加公钥

本地也放自己的密钥,这样可以假装模拟成3台机器。2个ssh免密钥的机器

node1同时作为部署机

开始写自动化部署脚本

根据上面的流程图,先把大体框架写出来

先把框架写出来,然后每个函数里写echo

看看脚本执行流程是否有问题

code_diff 拷贝差异部署文件

这是面向过程的一种开发方式

最末尾还要加个main,否则无法执行

脚本再优化下

尽量不要让$1来回传,否则可能会乱

继续完善脚本--添加日志和锁

1、凡是不记录日志的脚本就是刷流氓,执行到哪一步失败的啊?

2、脚本是否可以多个人一起执行?(最好不要多个人一起执行)不允许多人执行的话可以上锁

一般锁文件放下面目录下

我们可以单独添加个目录,给它用,因为权限问题,需要授权改变属组,我们使用tmp目录

主函数执行之前,应该先判断锁文件是否存在,执行的时候也应该生成这个lock文件

既然2个地方用到了它,是否可以把它制作成变量

新的脚本如下,主要添加了锁的功能

先执行下检查语法错误

加个sleep测试下锁的功能

给一个函数加下sleep 测试下执行中,另外的人是否可以执行这个脚本

运行脚本

新打开一个窗口执行测试

正常情况下一个窗口执行部署,再开一个窗口肯定执行不了

增加日志功能

其实就是echo一行到日志文件中,每个函数写加echo 写到日志里,这样比较low

能不能写个日志函数,加时间戳。以后日志函数可以复制到其它脚本里

脚本默认从上到下执行,遇到函数先加载,但是不执行

继续优化下。如下

还不能这么写,不然以后的时间都是一样的

可以改成这样,它不会执行

打包的时候,也用到时间戳命名了。还得用一个固定不变的时间用于打包

因为解压的时候,scp的时候用必须知道确定的包名字。

这里用到了2个时间,log-date是让它不执行的,cdate是让它执行的

自己先测试下

eval的用法

怎么可以让它在一行呢。暂时没找到办法(倒是可以单独定义一个时间变量)

单独定义一个时间变量(这里用不到,但是可以实现)

编写记录日志函数

这样code_get函数就记录日志了

规范点,加上双引号,分号可要可不要,写上不会报错

获取代码

把代码放哪里?

为什么创建这些目录,写着写着你就知道了

最终目录建立成这种

修改脚本

有的不需要编译,拉下代码之后,可以先把配置文件放进去

配置文件不要放这个目录下,这个目录只用来更新---git pull.你不好判断配置文件是仓库里面的,还是你专门下载下来的(最佳实践)

规划的时候,只让这里目录执行git pull

下面这个目录用于整合配置文件。

继续优化获取代码的函数

配置操作的函数时候,觉得不合适,应该区分项目,标准化。比如web-demo可以理解为一个项目包名字

目录新建

模拟下,在里面写上hehe

因为web-demo项目出现频繁,把它弄成变量

调整下脚本,优化code_config函数

规范下,给变量加大括号

注意是/bin/cp ,这样原先有配置文件,这里可以直接替换了

如果开发把配置文件打包进去了。连接的是测试的库,假如你部署生产环境了,连接测试的库。出了问题,谁背黑锅

运维是最后一道防线。开发和测试没遇到。你背黑锅

该给包重命名了

继续优化

添加版本号,先随便定义个版本

现在没有git pull 假装以echo 代替git pull

属组授权

内容为hehe,生成代码(页面)

文件和目录结构如下

以www用户测试脚本

测试结果

版本和时间之间改成下划线

再次执行

可以看到tmp目录需要定期清理

给下面2个函数加写日志功能

打包,记录日志

再次测试脚本

准备拷贝到目标服务器

前4步都完毕,开始第五步--拷贝到目标服务器


遍历节点

脚本里添加node_list

分发到目标节点

2台机器建立webroot

完善拷贝函数

再次部署测试下

检查

该第6步了,写个日志代替


解压完毕,拷贝差异文件。你要把差异文件单独放一个目录下。不要和配置文件放一起

修改上面,上面是相同配置目录文件

改成如下

创建配置文件目录,base存放相同的配置,other存放差异配置

调整下配置文件所在目录

拷贝差异文件到目标服务器的目标目录

再次测试

上面还有不足的地方,scp到目标服务器并解压,应该使用ssh远程执行、。上面脚本远程node2上解压是失败的

脚本再次改造下,把部署的函数和差异配置合并到一起

创建webroot

再次对部署函数优化,添加使用软链接参数(这个是秒级回滚的关键)

再次对脚本优化

自动化部署的精髓,创建软链接

对脚本优化,每个服务器要执行相同的操作,因此放在循环里

拷贝差异文件应该创建软链接之后拷贝,其实就是路径写的少点

第一次没软链接,会报错。需要先手动创建个软连接,或者先创建web-demo目录

其实我觉的完全可以在上面脚本里加入mkdir /webroot/web-demo -p 这样永远不会错

再次执行部署脚本。node1完成了

继续优化脚本,rm -rf 这里要写为-rf

测试脚本

主函数里,删除这个 config_diff

继续测试和检查

模拟版本更新,把版本写成456

继续测试

检查

链接 到了新的版本