中小型运维团队运维自动化平台设计

引言

咱们今天的话题是中小企业如何实现自动化部署。那么,为何定位中小企业呢?html

由于每每中小企业面临着运维人员有限,成本投入有限,可是版本更新快,并且服务器数量却并很多的状况。node

中小企业甚至,基本不会投入运维开发来开发自动化部署平台。那么,咱们今天就拿运维工程师都熟悉的Shell进行举例,谈谈如何来进行一个自动化部署的设计。git

本次分享主要包括以下内容:web

    1. 中小企业自动化部署的设计算法

    2. 如何在资源有限时开发自动化部署平台shell

    3. 部署的技巧与流程后端

    4. FAQ(有彩蛋哟,不容错过:)缓存

统一认识

在开始以前咱们须要先统一认识,在IT管理里面有三大核心要素,简称PPT,即:服务器

    • 人员/组织架构(People);架构

    • 流程(Process);

    • 技术/工具(Tech/Tool)。

因此说设计一个自动化部署系统,并不简单是上线几个工具,写几个自动化脚本这么简单。不过本文咱们简化流程,主要是聊聊生产环境的自动化部署系统。

同时经过这个“PPT”,咱们也认识到了,设计一个流程,除了流程自己要和咱们的组织架构、人员和技术挂钩,也须要根据企业的实际状况来作,不能好高骛远,梦想着一上来就设计一个庞大的自动化部署平台。这可能并不符合企业现状,又浪费了资源。

同时还有一点就是流程思路很重要,具体的实现方法不少,看团队的技术水平,可使用Python、Shell、PHP等来实现。

肯定目标

好的,咱们统一了认识,下面来肯定下目标。中小企业的部署现状就是更新快,可能常常性的测试不到位(因此,就须要快速回滚)。单业务的集群规模在基本上在100台之内。那么咱们的主要目标是:

    • 一键上线

    • 秒级回滚

流程设计

本文的重点就是流程设计。上面说了,因为篇幅有限咱们简化流程。完整的上线流程,可能经历开发环境、测试环境(功能测试、性能测试、预生产测试)、生产环境。

本次我就来谈谈生产环境如何自动化部署(假设如今新的功能已经在开发和测试环境就绪,Git或者svn仓库已经存放了能够上线的代码)。

我相信有读者目前的上线是使用管理工具,批量在全部服务器上执行svn update或者git pull。固然,我还见过每次上线执行rsync进行代码部署的。

咱们下面的流程或许会完全改变你的思路。不要惊讶,本来上面的方法也没有什么错,只要符合企业需求就能够,可是咱们能够作的更好。

直接上部署流程图:

流程分析

我想,看到这样的流程可能不少朋友在心中会有一些疑问,咱们慢慢来分别阐述下,这样设计的思路、设计原则和目的。

1. 获取代码

这一步的疑问最少,咱们能够经过svn或者git进行获取,也能够指定svn版本号或者git的tag,commit id,或者直接获取最新代码均可以。

注意,你须要在专用的部署服务器进行这样的操做,而不是各个Web服务器。

2. 编译

这个是可选的,若是你是Java,则须要进行编译,好比Ant或Maven就能够方便的帮你完成,Python和PHP则不须要进行编译操做,能够忽略。

总之,最后你有了一个目录,这个目录里面是准备上线的代码。须要注意的细节是,包名(目录名)的设计,能够涉及到环境、包名、版本号和时间。以下面的名称:

prod_web_xxxxx_2015-09-09-10:10

3. 匹配环境配置文件

这样,你这个部署系统(脚本)能够支持多个环境。这里有人会问配置文件不该该在代码仓库里面吗?

不是的!至少重要的和差别性的配置文件是须要单独进行管理的,尤为是涉及到支付、验证类的配置。

最佳实践是:最好给配置文件单独作一个版本库进行管理,同时能够经过目录来区分是测试仍是生产,只有相关的负责人才有权限进行更新和提交。这样的话,你须要将配置文件copy到代码目录下。

4. 打包

直接使用tar czf 打一个包就能够了。

5. COPY代码包到目标服务器:

如今能够将须要部署的代码包COPY到目标服务器,好比你可使用SCP。同时你能够在打包的时候给这个包生成一个md5文件,scp完毕后可使用md5sum验证一下包的完整性。

6. 将部署节点拿出集群:

先举一个反例,有些朋友可能这样操做,在部署时,直接部署和重启Web服务,让负载均衡的健康检查工做自动将节点踢出集群?

想这么搞的话的朋友,须要想想了,这作法也太暴力了。

咱们知道负载均衡的健康检查也是有时间间隔、次数的,若是你直接重启了后端Web服务,那么在负载均衡作判断后端主机是否下线的时间范围内,用户的请求可能就会失败。

因此,咱们要提早将要部署的后端节点拿出集群,好比Haproxy,你能够经过socat和Haproxy Unix Socket进行通讯,实现部署节点的开启和关闭,以下所示:

关闭节点:

    echo "disable server www_example_com/web-node1" | socat /usr/local/haproxy/haproxy.sock stdio

启用节点:

    echo "enable server www_example_com/web-node1" | socat /usr/local/haproxy/haproxy.sock stdio

7. 解压软件包

在目标服务器上解压这个软件包,不管你是用管理工具如Saltstack仍是SSH均可以轻松搞定。

8. 建立软链接

好的,这就是咱们设计的重点了,咱们使用软链接的方式来管理包的更新。好比咱们的Web根路径是/var/www/html/webroot,咱们把全部的代码都存放在/data目录下,那么webroot其实是一个软链接,它连接到当前的版本,好比prod_web_xxxxx_2015-09-09-10-10。这样的话,webroot实际是这样

    webroot -> /data/prod_web_xxxxx_2015-09-09-10-10/

我想,不少朋友,看到这里就明白了,这回滚绝对是秒级啊,只须要从新建立一个软链接便可。

9. COPY差别文件

同一个集群中,存在不一样的配置文件,这很常见,好比我须要在某个节点跑一些定时任务,好比Java可使用Quartz来实现,只须要一个crontab.xml便可,那么咱们就须要把这个差别文件在这个时候scp进去。

10. 重启Web服务

这个是可选的,若是是Java,运行的Tomcat,就须要重启Tomcat,别忘记清理相关的Tomcat缓存哦。

11. 自动化测试

若是有的话,固然好了,你调用一个接口就能够进行测试。而后等待测试完毕再继续。若是没有测试团队提供这样的接口,那么curl能够帮你轻松的实现,把重要的接口访问一遍,判断下返回码或者返回内容便可。

12. 加入集群

好的,这个节点部署完毕了,把他加入集群吧。还记得刚才说的socat吗。

13. 继续下一个节点

说了这么多,原来只是一个节点啊。那么继续吧,可能这个只是for循环中的一部分哦,是否是想到了shell该怎么写了。

部署小技巧

这里把实际使用的时候可能有用的小技巧分享下:

分组部署:

为何要分组?上面的流程中,你会发现,每次部署都会在重启和自动化测试那里等待很久。

由于你要等待Web服务的重启,好比Tomcat。那么如何减小这个时间呢?

答案就是分组部署,将该业务的服务器进行分组,好比group一、group二、group3:

    • 那么部署group1到重启那里后,流程不往下走了,直接部署group2;

    • 当group2部署完毕,停下来开始对group1进行自动化测试,测试完毕添加到集群;而后继续部署group3。

    • 当group3部署完毕后,再来自动化测试group2,而后你懂的。

日志记录:

没有日志记录功能的脚本就是耍流氓!你必须清楚的知道目前脚本在干啥,干到哪里了,若是有报错就能够及时的定位问题。

部署服务器双机:若是这台部署服务器宕机会怎么样?因此这台部署服务器必须是双机的。包括部署脚本应该是使用svn或者git来作版本控制。应该有详细的部署脚本的设计、使用文档。别忘了,文档化建设是流程设计必备的内容之一。

回滚流程

我想通过部署流程,你们很容易就想到了下面的流程,咱们主要能够简单的阐述下:

    • 列出回滚版本:ls –l能够了吧,只要列出能回滚的版本便可。

    • 目标服务器移除集群:同部署操做。

    • 执行回滚:删除旧的软链接,建立到指定版本的软链接

    • 重启:可选的

    • 自动化测试:同部署操做

    • 加入集群:同部署操做

    • Next:继续下一个节点

OK,这是一个回滚的流程。若是仅仅这样是远远不够的,别忘了咱们的定位是中小企业,每每我见到更多的状况是回滚是遇到了没有测试出来的比较大的bug。

那么咱们就须要一个紧急的回滚流程。这种状况下,暴力一点多是最佳选择了。

    • 执行回滚:对,不要列出来了,直接就用上一个版本便可。因此注意,部署的时候你须要记录上一个版本是什么。

    • 重启:可选。顾不了那么多了,如今是和时间赛跑。那么注意了,你的上一个版本须要是一个可用的版本,若是你没法记录,那么可能须要把列出版本再加上了。

好的,咱们的流程设计结束了,先在脑子里想明白,而后拿起Shell开始实现吧。会有不少小细节须要注意哦,我相信这难不倒你。

FAQ

问:有没有完整的自动化部署的流程图能够参考?

还真有,以前画过一个,请你们参考。目前咱们IAAS这块主要以Open Stack为主,Mesos+Docker也正在研究中。

 

问:大家是否考虑使用Jenkins来实现自动化部署呢?

实际上,咱们测试环境的自动化部署是使用的Jenkins。开发能够自助进行部署操做,同时也集成了代码审查和代码质量管理的流程。

可是咱们生产环境没有使用Jenkins,主要是咱们自动化测试还跟不上,每每不少发布须要人肉测试。整个流程没法完美衔接,因此就分开了。因此咱们生产部署其实产品发起,测试审核(测试),而后测试人员进行部署上线。

并且生产环境并非测试人员ssh到服务器执行咱们编写的脚本(他们没有权限),咱们基于SaltStack开发了Job管理平台,测试人员在Job管理平台上进行部署操做。

问:部署的一致性怎么保证的,好比刚更新的服务器和集群中的其它服务器版本不一致?

首先,平常的变更和更新是不会有这样的问题,若是有大的变更,不推荐在运维部门来实现,更好的实现方法是:好比在SOA的各个服务之间,加入API版本号的实现,实现多个版本并存。

若是你发现有不一致的状况,试试Nginx的ip_hash,或者Haproxy的source的负载均衡算法,让某个用户的请求一直落在某个节点,即实现了会话保持,也解决了你的疑虑。这样作固然也有不少缺点,看你的选择了。

问:咱们是否能够将线上部署修改成本文设计的流程?

欢迎使用,并且咱们后期还会提供Shell脚本模板。

这个流程的设计背景是一个电商的架构,物理机+虚拟机,供300多台的规模,使用了SOA。

可是,当时重构部署流程也经历了很长一段的时间,并且须要运维顶着很大的压力和责任,必定要充分测试,分批上线。