作者:赵舜东
江湖人称赵班长,曾在武警某部负责指挥自动化的架构和运维工作,2008年退役后一直从事互联网运维工作。曾带团队负责国内某食品电商的运维工作,即将出版的《saltstack入门与实践》作者之一。
文章编辑:高浩淼-北京
引 言
我们今天的话题是中小企业如何实现自动化部署。那么,为什么定位中小企业呢?
因为往往中小企业面临着运维人员有限,成本投入有限,但是版本更新快,而且服务器数量却并不少的情况。
中小企业甚至,基本不会投入运维开发来开发自动化部署平台。那么,我们今天就拿运维工程师都熟悉的Shell进行举例,谈谈如何来进行一个自动化部署的设计。
本次分享主要包括如下内容:
中小企业自动化部署的设计
如何在资源有限时开发自动化部署平台
部署的技巧与流程
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则不需要进行编译操作,可以忽略。
总之,最后你有了一个目录,这个目录里面是准备上线的代码。需要注意的细节是,包名(目录名)的设计,可以涉及到环境、包名、版本号和时间。如下面的名称:
3. 匹配环境配置文件
这样,你这个部署系统(脚本)可以支持多个环境。这里有人会问配置文件不应该在代码仓库里面吗?
不是的!至少重要的和差异性的配置文件是需要单独进行管理的,尤其是涉及到支付、验证类的配置。
最佳实践是:最好给配置文件单独做一个版本库进行管理,同时可以通过目录来区分是测试还是生产,只有相关的负责人才有权限进行更新和提交。这样的话,你需要将配置文件copy到代码目录下。
4. 打包
直接使用tar czf 打一个包就可以了。
5. COPY代码包到目标服务器:
现在可以将需要部署的代码包COPY到目标服务器,比如你可以使用SCP。同时你可以在打包的时候给这个包生成一个md5文件,scp完毕后可以使用md5sum验证一下包的完整性。
6. 将部署节点拿出集群:
先举一个反例,有些朋友可能这样操作,在部署时,直接部署和重启Web服务,让负载均衡的健康检查工作自动将节点踢出集群?
想这么搞的话的朋友,需要想一想了,这做法也太暴力了。
我们知道负载均衡的健康检查也是有时间间隔、次数的,如果你直接重启了后端Web服务,那么在负载均衡做判断后端主机是否下线的时间范围内,用户的请求可能就会失败。
所以,我们要提前将要部署的后端节点拿出集群,比如Haproxy,你可以通过socat和Haproxy Unix Socket进行通信,实现部署节点的开启和关闭,如下所示:
7. 解压软件包
在目标服务器上解压这个软件包,无论你是用管理工具如Saltstack还是SSH都可以轻松搞定。
8. 创建软连接
好的,这就是我们设计的重点了,我们使用软连接的方式来管理包的更新。比如我们的Web根路径是/var/www/html/webroot,我们把所有的代码都存放在/data目录下,那么webroot实际上是一个软连接,它链接到当前的版本,比如prod_web_xxxxx_2015-09-09-10-10。这样的话,webroot实际是这样
我想,很多朋友,看到这里就明白了,这回滚绝对是秒级啊,只需要重新创建一个软连接即可。
9. COPY差异文件
同一个集群中,存在不同的配置文件,这很常见,比如我需要在某个节点跑一些定时任务,比如Java可以使用Quartz来实现,只需要一个crontab.xml即可,那么我们就需要把这个差异文件在这个时候scp进去。
10. 重启Web服务
这个是可选的,如果是Java,运行的Tomcat,就需要重启Tomcat,别忘记清理相关的Tomcat缓存哦。
11. 自动化测试
如果有的话,当然好了,你调用一个接口就可以进行测试。然后等待测试完毕再继续。如果没有测试团队提供这样的接口,那么curl可以帮你轻松的实现,把重要的接口访问一遍,判断下返回码或者返回内容即可。
12. 加入集群
好的,这个节点部署完毕了,把他加入集群吧。还记得刚才说的socat吗。
13. 继续下一个节点
说了这么多,原来只是一个节点啊。那么继续吧,可能这个只是for循环中的一部分哦,是不是想到了shell该怎么写了。
部署小技巧
这里把实际使用的时候可能有用的小技巧分享下:
分组部署:
为什么要分组?上面的流程中,你会发现,每次部署都会在重启和自动化测试那里等待好久。
因为你要等待Web服务的重启,比如Tomcat。那么如何减少这个时间呢?
答案就是分组部署,将该业务的服务器进行分组,比如group1、group2、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。
但是,当时重构部署流程也经历了很长一段的时间,而且需要运维顶着很大的压力和责任,一定要充分测试,分批上线。
社区介绍
DBGeeK社区的创建,是为了更好的提供一个DBA的交流和活动平台(QQ群:516293316)。社区通过技术交流,线上、线下活动的分享,不断帮助用户提升数据库技能、获取数据库最佳实践,帮助用户更好、更安全的使用数据库。【做中国最好的共享数据库技术知识的社区】
领取专属 10元无门槛券
私享最新 技术干货