本文将介绍《DevOps Handbook》全书的核心:三步工作法。《DevOps Handbook》全书就是从三步工作法的思路出发,进行知识体系的组织和实践的编排。
简单说一下拆书联盟的活动,目前有几位小伙伴一起做拆书活动,首先由我做来第一期,然后是石雪峰,他是乐视配置管理和持续交付部门总监,他会给大家带来第二期拆书活动,后面还有王磊、大梁、景韵、赵班长等同学,都会参与到读书分享过程中。如果大家有兴趣可以联系我们,继续扩大阵容。
三步工作法是什么?如何通过三步工作法来指导DevOps的整体实施?以及它的核心思路和基础原则?
我们再来看一下DevOps与精益、敏捷和其他的管理运动的关系。
DevOps本身的方法以及它的技术、架构、文化实践都参考了这些优秀的管理方法、管理运动、管理哲学,DevOps是以上这些方法的集大成者。
下面我们来具体看看如何提升效率,在说具体方法之前先解释一个概念,什么叫做价值流。图中左边是生产价值流,指的是生产制造领域中设计、开发和交付产品所需要的活动,包括信息和材料的双重流动。聚焦在创造平顺和流式的工作,关注小批量,避免返工,减少在制品等。
右边是技术的价值流,也就是IT的交付过程,从需求提出到开发、测试、部署、发布、运营整个的过程。我们认为技术的价值流同样可以采用在生产制造价值流中经过验证有用的技术。技术价值流关注从商业的假设提出,到把它转化成技术辅助服务,最终交付价值给用户。
技术价值流的重点在于如何聚焦和缩短部署的前置时间,这里面有两个部分。首先是上游,设计、开发的部分。其次是下游,测试、运营的部分。
我们认为在设计、开发部分是精益产品开发过程,特点是高度的易变性和不确定性,需要有深度创新的工作。下游的测试和运营,我们希望它有更好的预测性和机械性,以最小的易变性完成工作。
怎么达到这个目标?有两个核心方法:
如何加快速度,我们要关注Lead Time和Process Time。
Lead Time是前置时间,从需求提出到需求被满足的整个周期。Process Time是从开始工作到工作结束,不包含在队列里等待的时间。Lead Time和Process Time之间的比率是非常重要的衡量效率指标,快速流动和缩短前置时间最重要的一个抓手就是要缩短队列中的等待时间,这可能是我们日常工作中非常容易忽略的。
下面是两个常见的场景:
下面我们进入到三步工作法最核心的部分。整个DevOps实施可以分解为三步:
每个部分我都做了一张总图,把核心思路做了梳理。
第一部分是Flow,让价值快速流动,其中有六个实践,分别是:可视化、限制在制品、减少规模、减少交接数量、持续识别和拓展约束,以及在价值流中消除浪费。
让工作可视化。技术价值流和生产制造价值流的区别是工作不可视,工厂里面有物料的流动和堆积,如果发现大量堆积,说明这里有瓶颈、有排队。而IT交付价值流里看不到显而易见的堆积,很多问题被隐藏掉,直到最后爆出更大的问题。
在DevOps领域里,包括敏捷、精益的理念,都在提可视化,通过可视化去管理价值流动。
图中左下角是一个典型的看板,看板里把整个软件的生命周期分成需求调研、需求就绪,开发进行中、开发完成,测试过程中、测试完成,以及UAT测试、准生产、发布等不同的列。通过这些列的划分,管理工作单元的流动,快速发现问题和解决问题。
通过看板可以让工作可视化、管理流动,并度量整个交付周期,看板一定要跨越整个价值流。
在这里推荐一本书,何勉老师最近编写的《精益产品开发》,前一个月刚上市,我认为是在国内做看板比较权威和完整的理论与实践相结合的书,强烈推荐大家阅读,里面会讲很多看板的方法和原则,如何建立、如何实践。
这里还要强调,做工作的可视化要考虑全局而不是局部,如果仅仅度量开发的完成率、度量测试发现了多少缺陷、度量系统的可用性,这些都是局部的目标。
我们更关注全局、端到端的价值流动,如何整体加快从需求提出到生产部署的时间,去增加服务的可靠性和质量。精益里讲全局的改进大于局部的优化。这是可视化的概述,看板也有很多方法和实践,后面的分享里再逐步分解。
限制在制品。刚才讲了很多Handbook里面的内容,下面讲两个小的故事,来理解在制品的概念。
我们来看一个实际的看板,为什么要限制在制品?因为我们的工作来自于很多渠道,尤其是那些共享的职能部门,比如开发中心、测试中心、运维中心,我们有正常的任务,有工单、有邮件、有电话,也有老板临时派下来的紧急任务,日常工作经常会被打断,切换成本非常高。
以前有过一个大致的统计,如果同时做两个任务,每个任务所花的时间并不是50%,而是40%,因为有20%在做任务的上下文切换。
如果同时在做三个任务,花在每个任务上的时间只有20%,因为有40%的时间在做任务的切换。参照“束水攻沙”的思路,限制在制品,增加流速,让整个流动速度加快,并且更快的发现问题。
参照“水落石出”的故事引申,因为限制了在制品,会发现某些下游环节(可能是测试、或者部署等)发生排队,发现了阻塞就可以针对性的去解决问题。图中右上角还有一些tips,如果已经产生堆积,这时候你处理的策略是什么?这里面有非常经典的一句话,”Stop starting,Start finishing”,我们要暂缓开始、聚焦完成。
我前一阵在北京的望京工作,这边有个大山子十字路口,这个路口经常会堵车,那么如果交警发现双向车道已经堵死,他会怎么处理?我相信交警第一步处理的动作是暂缓开始,所有的车不要再进入这个路口,然后他要把中间已经堆积的车一辆一辆疏通掉。这就是一个暂缓开始、聚焦完成的例子。
减少批量规模。这里面有一个简单的实验,如果有十封信要发,每封信制作需要四个步骤,分别是折纸、插入信封、封口、贴邮票。
有两种制作的方式:
所以很多人认为敏捷是一种快速交付软件的技术,其实并不是很准确,应该说它是一种能够更早交付价值的技术,让我能够更早的交付软件、灵活应对变化。
图中右上角有一些tips,小批量给我们很多好处,更快的前置时间,更快的发现错误和解决问题,更少的返工。通过这个小的实验,类比到IT交付价值流里,我们关注的方法叫做单件流,持续部署就是单件流的一种实现,只要代码提交入库,就自动做编译、测试、部署与发布,只要在我们的流水线里完成了所有验证,我们就认为这是一个潜在的可发布的版本。我们要减少批量的规模,频繁提交代码、频繁集成和验证,才能更早的进行交付。
减少交接数量。这也是非常关键的一个实践,代码从提交版本库到运行在生产环境要经历很多过程,有很多部门要跨越。
部门之间交接是非常痛苦的事情,交接意味着有人要发出请求,有人要去响应,要做很多解释、说明,要做排期、排序,要解决冲突、做测试验证等等,整个过程是非常耗时并且痛苦的。
过多的交接一定会导致整体效率的下降,只要压力一上来,各个部门都是满负荷运作,一定会出现排队,就会导致前置周期加长,为了按时交付就需要向上升级,找到老板干涉项目,临时调整优先级,这会造成更多混乱。
DevOps怎么解决这个问题?最有效的方法是右下角这个图,即实现自服务,我们要建设一个自服务的平台赋能给开发。要提高整体生产效率,开发需要通过API和自服务的方式,自助完成常见的场景,比如申请环境、部署上线等。
在技术价值流里关注两个词,自动和自助,自动是系统或平台自动化的帮你完成日常操作,自助是给上游的开发人员赋能,让他愿意用运维做的系统或平台完成一些任务。
之前看到一个挺不错的文章,说DevOps分成四个阶段:
这个描述非常容易理解,大家可以记住右下角这张图,通过自服务和自助化,破解过多交接带来的消耗。
持续识别和拓展约束。为了缩短前置时间并增加吞吐量,我们需要找到瓶颈点,只有在瓶颈点处的改进才是真正有效的。
我们来看一个视频,这个视频在模拟日常工作场景,每个人有不同的容量,有的人工作容量高,有的人低一些。经常会发现工作会堆积在整个价值流里工作容量最低的那个人或者部门头上,比如这里的3号工作人员,他的在制品不断堆积,他是整个价值流的瓶颈。到了第五天时,这个人最终崩溃了,无法继续完成工作。
这是约束理论带给我们的启示,我们需要找到和解决瓶颈,一般分为如下步骤:
上面是约束理论中解决约束的方法,我们再结合实际情况,看一下IT价值流中如何解决约束。在IT价值流中,约束一般按以下四个阶段演进。
在价值流中排除浪费。传统的制造业里有七种浪费,分别是传输浪费、动作浪费、过度生产浪费、过度加工浪费、等待浪费、库存浪费和缺陷浪费,后来又增加了一个创造力浪费。
在价值流里要提升效率,就要看到软件交付过程中的浪费。这里也列举了八种:
刚才把三步工作法的第一步 — 流动原则讲完了,下面来看第二步 — 反馈原则。这里有四个实践:
先给大家一个背景的认知,我们工作在复杂系统之上。Cynefin框架描述了组织所处的环境。组织所处环境有五种类型,分别是简单、繁杂、复杂、混沌、失序。
简单是指,因果关系是清晰可见的。繁杂是指,因果关系明确,但是需要专家研究和解决。复杂是指,因果关系可以被回溯,但不可能提前预知,这是绝大多数企业所处的状态,这里有一个关键词是Emergent,翻译过来是浮现,即解决方案是慢慢浮现出来的,而不是一次性就明确的,所以需要不断探索、不断试错、不断迭代。
我们所处的环境就是复杂的环境,出现问题是不可避免的,我们要做的是在问题发现时,快速发现和解决问题。
左边的图指出,需要持续测试我们的设计和运营假设,要不断做验证,提升问题发现的速度,增加恢复能力。
要建立向前的反馈循环,比如原来采用瀑布模型,有可能花费一年的时间开发一个产品,到最后一个月测试才发现有重大问题,这种反馈是非常慢的。
我们建议的方式是快速迭代,持续集成、持续交付的方式。代码提交之后几分钟就能得到一个反馈,这次提交的代码如果存在错误,能快速发现、快速解决。
右边的图是密集解决问题,最典范的例子是安灯拉绳,丰田在生产汽车之前生产了丰田的织布机,丰田织布机里一个非常有用的装置就叫做安灯拉绳,也就是说发现问题的时候及时通报并解决问题。
在精益生产过程中都会有安灯拉绳的装置,参观汽车生产线时,可以看到有的车架上会有一个安灯拉绳装置,出现问题时可以被触发,立即发现问题而不是绕开问题。因为如果选择绕开问题,修复成本会几何上升,不断提升的技术债,让下游工作更难完成。
在DevOps实践中,持续集成是很关键的一个部分。之前业界大师Jez Humble和Martin Fowier提出了一个经典的测试,验证是不是在做持续集成。
有些人说我用Jenkins,所以我在做持续集成,实际上这并不充分。这个测试有三个问题。
为什么举这个例子,因为刚才讲了很多,有些听起来貌似是生产制造领域的一些理念,而实际上这些理念同样是持续集成里最关键的原则。
保持将质量向源头推进,并为下游优化。这里面一个很关键的点,审批流程的有效性会随着决策远离工作执行处而降低。我们倾向于工作由下游的人去审核审批,但是如果我们下游的人根本不了解我们工作的情况,这种审批就是不增值和无效的。
有一些无效审批的例子,比如需要跨越另外一个团队去执行手工的任务,需要远离工作执行处、最繁忙的人进行审批,强迫审批人在缺少足够信息的情况下做决策,以及编写大量的文档,但其中很多细节在写完后会很快过期,这些都是无效的质量控制。
有效的质量控制的例子,比如通过Peer Review确认变更是否符合设计,就像谷歌的代码文化,他们要求进入代码库经过非常严格的自动化测试和代码评审,另外自动化尽可能多的质量检查,就像传统由测试和信息安全部门做的那样,让开发人员可以快速测试自己的代码,甚至自己部署生产环境。
图中右上角列举了一些tips,我们需要价值流中的每个人在他们控制的领域里找到并解决问题,作为日常工作的一部分。质量和安全责任要在工作执行处得到保障。
精益里面有一个实践叫做JKK,就是每个工作单元100%的完成和保证自身质量,戴明博士提出的内建质量也是这样含义,质量不是测试出来的,而是在整个过程中内建进去的,我们要将质量向源头推进。
三步工作法最后一步是持续学习和实验原则。这里面提了四个实践:
开启组织学习和安全文化,因为我们工作在复杂系统中,不可避免会经常出错。出现错误时,很多公司处理的方法是:Name , Blame , Shame。出现错误时是一种责备和追责为主的文化。
这样会导致组织内形成一种恐惧感,如果团队成员都很恐惧,怕做错事受到责备,就会选择把小的问题隐藏掉,直到问题积累到一定程度最终灾难性的爆发。
Westrum模型提出组织文化的三种类型,分别是病态型组织、官僚型组织和生机型组织。
在DevOps的范畴里应该构建生机型的文化,引导一个免责的故障事后分析机制,让学习过程变成良性的循环。
下面这段文字我觉得非常有启发,消除责备就会消除恐惧,消除恐惧就会得到诚实,诚实才能形成预防措施。从Name , Blame , Shame转变为免责文化,收获的是能够找到问题的根因。
有一个很好例子,今年1月31号晚上GitLab发生了非常重大的事故,某个运维人员在凌晨删除了数据库,大概有6小时的数据丢失,包括合并请求、评论等,而且是永久性丢失。有707位用户、5037个项目受影响。
官方视频直播了恢复过程,他们主要做的是问题根因分析,采用了5W(五个为什么)的方法,分析问题并制定改进措施。但是官方也表态,造成问题的运维人员不会被解雇,而是被迫看一个很无聊的视频作为处罚。
这个例子反映出DevOps提倡的是免责的文化,重点并不在追责,而是转移到根因分析和对于恢复过程的改进,这是生机型组织的明显特征。
改进制度化,局部发现转为全局改进。
举两个案例,Linkedin 2003年成立,当时核心业务运行在叫做Leo的Java单体应用上,多年发展后,2010年Leo外围有100个系统,问题是核心的Leo系统经常宕机,难以发布新代码。
于是Linkedin做出一个决定,通过两个月时间,完全不做新的功能开发,完全聚焦在非功能需求上,将之前积累近十年的技术债务一次性偿还,相信这是一个非常艰难的决定。
这个案例给我们的启示,比日常工作更重要的,是改进日常工作,我们要把改进融入到日常的工作中。
右图是将局部发现转为全局改进的案例,平安科技有一个“看板大巡游”的活动,在组织级推动看板时,每个团队会选一个人参加看板巡游活动,由一个敏捷教练带队,像导游一样带着大家到各个团队看板处观摩,评价每团队的看板,相互学习。
最终巡游完成后,他们集中讨论哪个地方好,哪个地方可以借鉴,最后把学到的成果用于自己的改善。这就是很典型的例子,把局部发现转化为全局改进,比如可以让整个组织都能检索到事故分析报告,可以共享代码,让代码横跨整个组织被所有人都能搜索到。
百度前几年工程能力建设的重要部分,就是建立了基于Git的代码托管平台,除了可以更容易进行代码库和分支管理之外,很重要的一点是代码的全局搜索,在权限范围内可以让更多人都搜索到所需的代码片段,促进组织的知识复用。
在日常工作中注入恢复模式。这里也有一个例子,丰田的一个顶级供货商有两条生产线,但是在Slow Day的时候会把所有的制造放在一条生产线上,用来实验增大压力、扩充容量是否会导致失败,增强反脆弱的能力。
在技术价值流里也有这种模式,比如Game Day演习,模拟大范围失败,或者在生产环境注入大范围失败。
经典的例子是Netflix的Chaos Monkey工具,会在生产环境随机杀进程,用来确保整个系统有强大的恢复能力。还有一个金句,“避免失败的最好办法是经常失败”,Martin Fowler也提出过,“If it hurts,do it more often”,如果某个事情让你感到痛苦,解决方案就是频繁的做。
回顾一下,今天DevOps拆书联盟活动第一期,首先介绍了《DevOps Handbook》这本书的知识体系,然后分析了DevOps的常见误区,以及理想的DevOps模式是什么样的。接下来,重点介绍了DevOps的三步工作法,分别是流动、反馈、持续学习和改进。三步工作法是DevOps实施过程所采用的底层原理和方法,后续所有的技术实践都将围绕三步工作法组织和展开。