DevOps自从2009年诞生以来,经过多年摸索开始逐步变成一种主流运维模式。网上也有很多关于DevOps的讨论,但大多数都停留在思想层面,真正可落地的方法并不多,本文作者对自身从业经验和唯品会的落地实践加以总结,希望给读者一定的思考和帮助。
在本文开始之前,需先明确几个概念,后文会用到。
ITIL:一种以流程为基础的运维模式,基本思想是PDCA。
服务:能够独立提供完整的一个或者多个功能模块,这里特指业务研发编写可上线运行的代码。
组件:能够独立部署,但需要和其他组件联合才能提供服务的基本单位。
本文主要回答两个方面问题:
为什么需要DevOps?
DevOps如何落地?
本文建议的阅读者:有一定开发和运维经验的工程师,最好是经历过实际生产困难后面临转型困境的人员。
在流程约束上,目前做得最好的运维模式是ITIL理论,它通过流程驱动运维落地,同时有很好的落地实践,包括要建设哪些系统都有清晰的注明。我记得我第一次接触ITIL理论时,惊为天人,因为在复杂运维场景下能够抽象出一套完善理论是一件很不容易的事。对于很多初成立的团队,我建议选择这种模式作为伊始。ITIL的优点除了上面易落地外还有以下原因,值得尝试:
见效快,比如只需要建立一个变更流程,就能立即大幅度提升生产质量。
运维部门主导,在ITIL模式下的绝大多数系统和流程只需要运维部门实施即可,甚至最关键的CICD,ITIL体系也只关注于最后发布到生产那一块。
管理落地,流程落地的过程就是管理落地的过程,在这个过程中,管理者可以把自己的经验和方法完整地实践下来,可以最大屏蔽执行者的差异。
ITIL主要关注质量和效率之间的质量,兼顾效率。这句话的理解是,当质量和效率发生冲突时,ITIL会优先保障质量。所以当要求效率优先时,ITIL会比较困难,这也就为DevOps发展提供了空间。当然ITIL本身也有其他问题,比如流程反弹、边际效益等,但由于不是本文重点因此不展开讲。
而DevOps模式的本质是对开发、测试及运维角色的分工挑战。如果我们把重心放到最终产出物,即如何快速提供新服务给用户时,就会遇到一个非常大的挑战--开发、测试、运维需要融为一体。让以上三种角色协同其实不是一件容易的事情,因为三方的KPI、行事风格及语言体系并不相同,这就是我们常说的那堵部门墙。
举个生产变更的例子:
小D:业务研发
小O:应用运维
他们实施的是DO分离(DO分离也是一个很大的概念,如果以后有空,再单独讲),现在小D要做个变更需求,假设增加一个环境变量,用做代码使用,他们实施的过程会是什么样的呢?
Step1,小D会提交一个变更需求申请,在申请中写明要干什么事情,然后经过小D的上级审批,工单流转到小O;
Step2,小O收到申请,然后他需要写变更执行步骤,在写的时候,他需要确认一下业务影响,所以他线下找到小D问为什么要这样做;
Step3,小D解答自己这么做的原因,并且贴出自己的代码,说明在哪里引用;
Step4,在交流过程中小O发现一个额外步骤,既改完环境变量需要重启应用,而应用重启需要小D发布新的代码,这时他告诉小D,变量更改完,下次你们发代码后生效;
Step5,几轮后二者达成一致,小O开始做变更,做完后,等待小D验收;
Step6,小D无法验收,因此要求代码发布日那天,小O要在场,出现问题及时回滚。
这只是生产最平常也是最简单的一个变更场景。在这个场景中有两个问题,其一,二者沟通的信息有效么?或者更进一步说,当变更完成后,这次变更中所交流的所有信息对以后工作有促进么?其二,这一件工作真的需要二者一起完成么?
其实,答案都是否定的,很多在变更过程中的质疑和沟通都是无效的,只不过二者所处的角色导致信息必须对称才能做好一个变更,最后造成效率低下,解决沟通最优的方式不是提升双方技巧,而是舍弃沟通。如果,运维能够提供一个系统或者平台,在上面设置好各种运维场景,开发可以在上面可视化操作,那么则无需沟通,这也是很多人的思路,即系统化是落地DevOps的途径。
在这里,我复述一遍:DevOps的本质是系统化,我个人比较认同这个理念。但在实际操作中落地过程并不顺利,那么问题来了,为什么都明白这个道理,但依然做不好DevOps?
请大家思考一个问题,在变更场景下,如果我们要找到一个开发和运维都共同关心的事物,那是什么?
不是代码,代码运维并不关心,即使想关心,也是有心无力;不是操作系统,对于大多数研发而言,编写代码需要屏蔽底层差异,如果真的存在这类事物,那么只能是和代码产生直接关系的组件,比如中间件Tomcat、缓存Redis、Mc、数据库Mysql等,实际上绝大多数开发的变更需求也是围绕这些组件实施的。这个很好理解,因为代码层次变更开发可以自己掌控,只有这些直接关联的组件需要运维配合实施,因此做好这些组件的变更场景系统,则能满足百分之九十以上的开发变更需求。
如何基于组件实施DevOps?
首先,要指定组件的范围,既找到上文我们所说的和开发关联密切的组件,每种组件抽象出操作集合,并把这些操作标准化和脚本化,如下图:
有了这些梳理,接下来就可以进行系统建设,在系统划分时,需要遵循以下两个原则:
其一,闭环原则,每个组件层面的操作是个封闭集合,既系统要能囊括这个组件变更的方方面面。
其二,横向抽象原则,对于各个组件共性方面进行横向抽象,用一个系统来完成。比如每个组件都会有配置文件的管理,这类就可以抽象出组件的配置中心平台统一管理。
接下来,以配置举例,我们来看看是如何构建这个系统的。
Crab统一配置平台是唯品会针对组件层面做的配置管理平台,每一个组件都由代码和配置两部分组成,我们操作最多的也是对这些配置的修改,但绝大多数配置是不需要修改的,也就是和应用属性无关。以tomcat为例,在众多配置中,只有Server.xml和Context.xml需要进行个性化设置,而在这些个性化设置里,也只有如下参数需要动态调整,如下图:
Crab把这些参数进行key值化,然后抽象出模板的概念。原理如下图:
其中有一些细节需要注意:
key分为通用型和自定义型,通用型的key基本和业务无关,或者可以说是标准化后的标准,例如服务的端口号,这些由运维把控,全网生产统一,自定义型的key和业务相关,可以交由研发来掌控,当然,这两种类型的key是可以互换的,然而由自定义向通用型过渡是一个比较麻烦的过程,要小心操作。
某些场景下,key值会对应多个value,例如同样是php最大进程数,物理机和容器是不同的,同一个应用,在不同的IDC配置也会有不同,这些需要在渲染过程中加入下发者对象才能实现,这种特殊逻辑越少越安全。
如何控制风险?
当系统权限放开到业务开发时,面临的最大问题是风险失控,这里需要强调一点,DevOps并非不要流程,我看过很多DevOps体系丧失流程的概念,效率提升了,却忘记了运维三角型中运维的及格线:质量。
唯品会的体系中是通过风险矩阵来控制变更风险的。我们发现每一次变更其实是由三部分构成的:变更对象、操作类型及执行变更的人,但当我们系统化后,变更执行人的因素会变弱很多,所以一个风险矩阵真正起作用的是变更对象是否是核心,操作过程是常规还是特殊,由历史数据推断操作的风险系数,这样我们就得到一个变更风险矩阵,如下表:
高风险的变更仍然需要人工审核介入,但审核的内容由原来的执行步骤转变为需求是否合理以及操作时间是否合理。ITIL的变更流程依然存在,只不过蜕化为第二层,对用户不可见,蜕化后的系统结构如下图:
如何持续改进?
评价DevOps的指标有两个,一个是整个变更的平均完成时间,这个时间可以分为高风险,中风险和低风险三个纬度,我们目标是降低低风险和中风险的变更时间,高风险一般不做时间要求。另外一个是研发的自助变更率,当然,有些变更必须运维才能完成,这类变更在统计时要排除在外。
DevOps和ITIL二者理念不同,但关注点相似,并不存在必须舍弃一种的说法,可以在质量和效率之间选取平衡。如果说ITIL需要自上而下贯彻实施,那么DevOps则需要变更的执行者、需求者参与,二者最后会贯穿整个链路。
最后,还是那句话,没有好不好,只有合不合适,只有最合适的,才是最好的。
本文转载自公众号:唯技术, 点击查看原文。
![640?wx_fmt=jpeg](https://i-blog.csdnimg.cn/blog_migrate/3ae791a912abc00b2e686a02054240b5.jpeg)