DevOps自2009年诞生以来,经过多年的探索,逐渐成为一种主流的运维模式。网上也有很多关于DevOps的讨论,但大多停留在思想层面,真正能够落地的方法并不多。本文作者总结了自己的经验和唯品会的实施实践,希望能给读者一些思考和帮助。在开始本文之前,需要明确几个概念,后面会用到。ITIL:一种基于流程的运维模型,基本思想是PDCA。服务:能够独立提供一个或多个完整的功能模块,具体指业务研发编写可在线运行的代码。组件:可以独立部署但需要与其他组件组合提供服务的基本单元。本文主要回答两个问题:为什么需要DevOps?DevOps如何实现?本文推荐读者:具有一定开发和运维经验的工程师,最好是经历过实际生产困难后面临转型困难的工程师。为什么我们需要DevOps?在回答这个问题之前,我们先了解一下什么是运维模式。所有的模型都是在对人对事的态度之后得到的方法论。比如我对人性持悲观态度,所以我需要建立一个流程体系来约束人,让他们在做事的时候尽量减少主观意志,客观地理解他们。完成分配的任务。反之,如果我对人性持乐观的态度,那么我可能会多鼓励一些,让人们发挥主观能动性,形成共同的价值观和行为准则,并系统地实施。这里需要注意的是:人是一种非常复杂的动物,往往不能单独考虑。很多时候需要两者结合,适合自己的才是最好的。如果你想和更多的DevOps技术专家交流,可以加我微信liyingjiese,备注“加群”。群里每周都有全球各大公司的最佳实践和行业最新动态。在流程约束方面,ITIL理论是目前最好的运维模型,它通过流程来驱动运维,并且有很好的实施实践,包括明确指示要构建哪些系统。记得刚开始接触ITIL理论的时候,我是很震惊的,因为在复杂的运维场景下,抽象出一套完整的理论并不容易。对于许多新成立的团队,我建议选择这种模式作为起点。ITIL的优点不仅是易于实施,还有以下原因值得一试:见效快,比如只需要建立一个变更流程,生产质量马上就能得到很大的提升。运维部门牵头,ITIL模型中的大部分系统和流程只需要由运维部门来实现即可。即使是最关键的CICD,ITIL系统也只关注发布到生产。管理过程和过程实施就是管理实施的过程。在这个过程中,管理者可以充分实践自己的经验和方法,可以完全屏蔽执行者之间的差异。ITIL主要关注质量和效率之间的质量,兼顾效率。这句话的理解是,当质量和效率发生冲突时,ITIL会优先考虑质量保证。因此,当需要优先考虑效率时,ITIL的难度会更大,这也为DevOps的发展提供了空间。当然,ITIL本身还有其他问题,比如流程反弹、边际收益等,但由于不是本文的重点,就不展开了。DevOps模式的本质是对开发、测试、运维角色分工的挑战。如果我们专注于最终的产品,即如何快速的为用户提供新的服务,我们会遇到一个非常大的挑战——开发、测试、运维需要整合。协调以上三个角色其实不是一件容易的事,因为三者的KPI、行事风格、语言体系都不尽相同。这就是我们常说的部门墙。举个生产变更的例子:小D:业务研发小O:应用运维他们实现DO分离(DO分离也是个大概念,以后有空再单独说),现在小D要做一个Change需求,假设增加一个环境变量供代码使用,他们的实现过程会是怎样的呢?Step1、小D会提交变更请求申请,在申请中写明要做什么,然后通过小D的上级审批后,将工单转给小O;Step2,小O收到申请,接下来需要写变更执行步骤。写的时候需要确认业务影响,于是在线下找到小D,问他为什么要做这个;Step3,小D解释了自己这样做的原因,并贴出了自己的代码,说明了引用的地方;Step4,小O在通信过程中发现多了一步,更改环境变量后,需要重启应用,而应用重启需要小D发布新代码,此时他告诉小D,变量后已更改,将在您下次发布代码后生效;Step5,几轮之后,两人达成一致,小O开始修改。完成后,等待小D验收;Step6,小D无法接受,所以要求代码发布当天小O在场,出现问题及时回滚。这只是最常见和最简单的生产变更场景。这个场景中有两个问题。第一,两者之间传递的信息是否有效?或者更进一步说,变更完成后,这次变更传达的所有信息是否对以后的工作有帮助?第二,这是一项工作真的需要一起完成吗?事实上,答案是否定的。变更过程中的很多质疑和沟通都是无效的。只是两者的作用使得信息必须对称才能做好。改变,***导致效率低下,解决沟通问题的方法不是提高双方的技能,而是放弃沟通。如果运维可以提供一个系统或者平台,可以在上面设置各种运维场景,可以在上面可视化开发,那就不需要交流了。这也是很多人的想法,即系统化才是实现DevOps的方式。在这里,我重申一下:DevOps的本质是系统化,我个人非常认同这个概念。但是在实际操作中落地的过程并不顺利,那么问题来了,为什么明明明白了这个道理,却还是做不到DevOps?DevOps如何落地?事实上,DevOps的方法论并不明确,它的所有思想都停留在一个相对抽象的层面,系统化是一个很好的实现方式。然而,在系统化之后,很多公司的DevOps之路并不平坦。在运维和研发的使用场景中,***只能不断打补丁,疲于应付,无法继续改进。CICD是一个很好的切入点。刚需,场景清晰单一,也优化了开发痛点,利于推广落地。网上也有很多讨论,所以这不是本文的重点。你可以自己找。这里主要讲一下DevOps在生产管理中的落地方案,尤其是生产变更场景。请思考一个问题。在不断变化的场景中,如果我们想找到开发和运维双方都关心的东西,是什么?不是代码,代码运维不关心,就算我们想关心也无能为力;不是运维对于大部分研发系统来说,写代码需要屏蔽底层差异。如果真的存在这样的东西,那只能是和代码直接相关的组件,比如中间件Tomcat、缓存Redis、Mc、数据库Mysql等,其实大部分的开发变更需求都是围绕这些组件实现的。这个很好理解,因为代码层面的变更开发是自己可以控制的,只有这些直接相关的组件需要运维配合才能实现。因此,一个好的针对这些组件的变更场景系统,可以满足90%以上的开发变更需求。唯品会实践下面将结合唯品会的实践来讲解具体怎么做。如何基于组件实现DevOps?首先,明确组件的范围,即找到与我们上面提到的开发密切相关的组件。每个组件抽象出一组操作,并将这些操作标准化、脚本化,如下图所示:经过这些梳理之后,接下来就可以进行系统构建了。在划分系统时,需要遵循以下两个原则:一是闭环原则,每个组件层级的运行都是一个闭集,即系统必须能够覆盖组件变化的所有方面。二、横向抽象原则,横向抽象各个组件的共性方面,用一个系统来完成。比如每个组件都会有配置文件管理,可以抽象出组件的配置中心平台统一管理。下面以配置为例,看看如何搭建这个系统。Crab统一配置平台是唯品会在组件层面做的配置管理平台。每个组件由两部分组成:代码和配置。我们操作最多的就是修改这些配置,但是大部分配置是不需要修改的,也就是说,与应用程序属性无关。以tomcat为例,在众多配置中,只有Server.xml和Context.xml需要进行个性化设置,而在这些个性化设置中,只有以下参数需要动态调整,如下图所示:Server.xml参数表上下文。xml参数表Crab将这些参数转化为键值,然后抽象出模板的概念。原理如下图所示:有一些细节需要注意:key分为通用和自定义,通用key基本和业务无关,或者可以说是标准化的标准,比如服务端口号,由运维决定。控制,全网统一生产,自定义key与业务相关,研发可控。当然,这两种类型的密钥是可以互换的,但是从定制到通用的过渡是一个麻烦的过程。过程,小心。在某些场景下,键值会对应多个值。比如同样的php***进程数,物理机和容器不一样,同一个应用在不同的IDC配置中也会不一样。这些都需要在渲染过程中进行处理。只能通过在中间添加sender对象来实现,越少这种特殊逻辑越安全。如何控制风险?当系统权限下放给业务发展时,最大的问题就是风险失控。这里需要强调的是,DevOps并不是没有流程的。我已经看到许多DevOps系统失去了过程的概念。效率提高了,但是忘记了运维三角形中运维的及格线:质量。在唯品会的体系中,变更的风险是通过风险矩阵来控制的。我们发现每一次变更其实都是由三部分组成:变更的对象、操作的类型、实施变更的人。但是当我们系统化的时候,变更执行者的因素会弱很多,所以一个风险矩阵真正起作用的是变更对象是否是核心,操作过程是常规的还是特殊的,推断操作的风险系数从历史数据中,这样我们可以得到一个变更风险矩阵,如下表所示:是否合理,手术时间是否合理。ITIL的变更过程依然存在,只是退化到了第二层,对用户来说是不可见的。退化的系统结构如下:如何持续改进?评价DevOps有两个指标。一是整个变更的平均完成时间。时间可以分为三个纬度:高风险、中风险和低风险。我们的目标是减少低风险和中风险的变更时间。一般高风险没有时间要求。另一个是研发的自助服务变化率。当然,有些变更必须要运维才能完成,而这样的变更要排除在统计之外。总结一下,在DevOps实施过程中最头疼的就是观念的转变。为什么要承接原有运维的开发?看到真正的好处,不能为了DevOps而做DevOps。DevOps和ITIL概念不同,但关注点相似。没有说一定要舍弃的,可以在质量和效率之间取一个平衡点。如果说ITIL需要自上而下实施,那么DevOps则需要变革执行者和需求者的参与,两者贯穿整个环节。***,正如那句话,没有好坏,只有适合,只有最适合的,才是最好的。
