时间:凌晨3点 地点:深圳科技园 职业:运维汪
凌晨2:50,睡眼朦胧的我从手机铃声中醒来,还有10分钟,就要上线2.0版本,
看着研发丢过来的满满三页的操作文档,心中有点淡淡的惆怅,又到上线新版本的时候了。
凌晨3:30,操作文档已经执行到了第22条,还有5条,心中默默有点小激动,仿佛全世界都在我的手上,
机械键盘的音符已经汇聚成一曲交响曲, 上传包,解压,拷贝文件,所有的操作如丝般顺滑。
凌晨3:35,最后一步了,深呼吸,仿佛已经可以看到凌晨四点钟的南山科技园, 当回车键按下的一瞬间,执行失败,瞬间懵圈,
开始漫长的排查过程,确认上面的每一步操作是否正确。
凌晨4:30,终于找到原因了,第18条操作文档,有个旧的目录没有删除,终于松了一口气,极度疲惫的状态下,敲下了这些命令,
敲下去的一瞬间,发现所有的命令都执行不了了,仔细一下原来删除了根目录,所有的数据都没有了,顿时世界安静了。
你是否也经历过类似的手工发布过程?在持续交付中有三类部署反模式。
(*本篇部分内容来源于了《持续交付:通过自动化构建、测试、部署流水线实现可靠的软件发布 》一书)
第一类:手工部署软件
对于现在的应用程序来说,无论规模大小,其部署过程都比较复杂,而且包含很多非常灵活的部分。许多组织都使用手工方式来发布软件。也就是说部署应用程序所需的这些步骤是独立的原子操作,且由某个人或某个小组来分别执行。每个步骤里都有一些需要人为判断的事情,因此很容易发生人为错误。即便不是这样,这些步骤的执行顺序和时机的不同也会导致结果的差异性。而这种差异性很可能给我们带来不良结果。
这种反模式的特征是:
有一份非常详尽的文档,该文档描述了执行步骤及每个步骤中易出错的地方。
以手工测试的方式来确认该应用程序是否正确运行了。
经常发生这样的情形:在发布当天开发团队会接到电话,被通知部署出错了,以及出错的现象是怎样的。
在发布时,常常会修正一些在执行过程中发现的问题。
如果是集群环境部署,常常发现在集群中各环境的配置都不相同,比如应用服务器的连接池设置不同,文件系统有不同目录结构等。
整个发布过程需要较长的时间。
发布结果不可预测,常常不得不回滚或遇到不可预见的问题。
发布之后凌晨两点还睡眼惺忪地坐在显示器前,绞尽脑汁想让刚刚部署的应用程序正常工作。
相反,随着时间的推移,部署应该走向完全自动化。即对于那些负责将应用程序部署到开发环境、测试环境或生产环境的人来说,应该只需要做两件事:(1)挑选版本及需要部署的环境,(2)按一下“部署”按钮。对于套装软件的发布来说,还应该有一个创建安装程序的自动化过程。
我们将在本书中讨论很多自动化问题。当然,并不是所有的人都能接受这个想法。那么,我们先来解释一下,我们为什么把自动化部署看作是一个必不可少的目标。
如果部署过程没有完全自动化,每次部署时都会发生错误。唯一的问题就是“该问题严重与否”而已。即使通过了良好的部署测试,有些错误也很难追查。
如果部署过程不是自动化的,那么它就是不可重复的或不可靠的,就会在调试部署错误的过程中浪费很多时间。
手动部署进程不得不记录在案。文档维护是一个复杂而费时的任务。它涉及多人之间的协作,因此该文档基本上要么是不完整的,要么是未及时更新的。而把一个自动化部署脚本作为文档,它就永远是最新的和完整的,否则就无法进行部署工作了。
自动部署本质上也是鼓励协作的,因为所有的内容都在这个脚本里,一览无遗。而文档是建立在一种假设的基础之上的,即读者的知识水平与作者的水平相当。可事实上,这个文档通常只是执行部署者所写的备忘录,他人并不清楚当时写作的上下文。
根据以上几点,我们可以得到这样的结论:手工部署过程需要部署专家。如果专家去度假或离职了,那你就有麻烦了。
尽管手工部署是枯燥且重复性的劳动,但仍需要有相当程度的专业知识。一方面,专家要做这些无聊且重复性的工作,而另一方面,技术要求高的任务仍需要他们来完成。结果,我们只有通过“剥夺睡眠”这样的方式来解决时间不足等问题啦。而自动化部署可以解放那些昂贵的高技能人员,让他们投身于更高价值的工作活动当中。
对手工部署过程本身进行测试的唯一方法就是原封不动地做一次(或者几次)。这往往费时又昂贵。而自动化的部署过程却是既便宜又容易测试。
另外,还有一种说法:“自动化过程不如手工过程的可审计性好”。我们不同意这个观点。对于一个手工过程来说,没人能确保其执行者会非常严格地遵照文档中所记述的内容。只有自动化过程是完全可审核的。有什么东西会比一个可工作的部署脚本更能够被审核的呢?每个人都应该使用自动化部署过程,而且它应该是软件部署的唯一方式。这个纪律可以确保:在需要部署时,部署脚本一定会很好地完成工作。在本书中我们会提到多个原则,而其中之一就是“使用相同的脚本将软件部署到各种环境”。如果您使用相同的脚本将软件部署到各类环境中,那么在发布当天需要向生产环境进行部署时,这个脚本已经被验证过成百上千次了。如果此时出现任何问题的话,你可以百分百地确定是该环境的具体配置问题,而不是这个脚本的问题。
当然,手工密集操作的发布工作有时也会非常顺利。但不幸的是,我们经常看到的却是糟糕的情况。假如在整个软件生产过程中它不算是一个易出错的步骤,那为什么还总是出错呢?为什么需要这些流程和文档呢?为什么团队在周末还要加班呢?为什么还要求大家原地待命,以防意外发生呢?
第二类:只有在开发完成之后,才能向类生产环节上部署
当软件开发完成后第一次被部署到类生产环境(比如试运行环境)时,开发团队认为“该软件开发完成了”。
这种模式中,经常看到下面这些情况:
测试人员部署之前就已参与开发流程,但只在开发环境中对软件应用进行了测试。
只有在向试运行环境部署时,运维人员才第一次接触到这个应用程序。在某些组织中,通常是由独立的运维团队负责将应用程序部署到试运行环境和生产环境。在这种工作方式下,运维人员只有在产品发布到生产环境时才第一次见到这个软件。
有可能由于类生产环境非常昂贵,权限控制严格,操作人员自己无权对该环境进行操作,也有可能环境没有按时准备好,甚至根本没人去准备环境。
开发团队将正确的安装程序、配置文件、数据库迁移脚本和部署文档一同交给那些真正执行部署任务的人员——而所有这些产物都没有在生产环境或试运行环境中进行过测试。
开发团队和真正执行部署任务的人员之间的协作非常少。
当需要将软件部署到试运行环境时,只是临时地组成一个团队来完成这项任务。有时候这个团队可能是一个全功能团队,然而在一个大型组织中,这种部署责任通常落在多个分立的团队肩上。DBA、中间件团队、Web团队,以及其他团队都会染指应用程序最后版本的部署工作。因为部署工作中的很多步骤根本没有在试运行环境上测试过,所以常常遇到问题。文档中也漏掉了一些重要的步骤。这些文档都基于一个基本假设,即软件版本或目标环境的配置都是正确的。然则情况常常恰恰相反,而引起部署失败。部署团队不得不猜测开发团队到底是怎么做的。
有的时候,情况会比这还糟。 以下这些事情会使问题恶化。
当一个应用程序是全新开发的,当第一次将它部署到试运行环境时,可能会比较棘手。
发布周期越长,开发团队在错误的假设下开发的时间就越长,修复这些问题的时间就越长。
在那些划分有开发、DBA、运维、测试等部门的大型组织中,这些独立部门之间的协作成本可能会非常高,有时甚至会将发布过程拖上地狱列车。此时为了完成某个部署过程,开发人员、测试人员和运维人员之间总是是高举着问题单(不断地互发EMail)。更糟糕的是,这些Email都是为了解决部署过程中发现的问题。
开发环境与生产环境差异性越大,开发过程中所做的那些假设与现实差距就越大。虽然很难度量,但我敢说,如果你在Windows系统上开发软件,却最终需要部署到Solaris集群上,那么你会遇到很多意想不到的事情。
如果你的应用程序是由客户自行安装的(你可能没有权限操作客户的环境),或者其中的某些组件不在企业控制范围之内。此时可能需要很多额外的测试工作。
那么,
第三类:生产环境的手工配置管理
这种反模式的特征是:
多次部署到试运行环境都非常成功,但当部署到生产环境时就失败。
集群中各节点的行为有所不同。例如,与其它节点相比,某个节点所承担的负载少一些,或者处理请求的时间花得多一些。
运维团队需要较长时间为每次发布来准备环境。
系统无法回滚到之前部署的某个配置上,这些配置包括操作系统、应用服务器、关系数据库、Web服务器或其它基础设施。
不知道从什么时候起,集群中的某些服务器所依赖的操作系统和第三方库的版本就不同了,或者更新了错误的补丁。
直接修改生产环境上的信息来改变配置。
一个完善的自动构建、部署、测试和发布系统威力不可小觑,它可以通过事前操作以成百倍的效率提升整个环境的部署速度。即使出错,也可以在同样短的时间内实现回滚功能。
EasyOps平台通过绑定应用与程序包的操作,使得平台在发布应用时仍可以对程序包实现
1)版本管理
2)回滚
3)编辑权限
等功能点,极大提升应用发布的效率。
而过程,大概我们给一个3分5秒的视频,你就明白了。