本文将介绍《DevOps Handbook》全书的核心:三步工作法。《DevOps Handbook》全书就是从三步工作法的思路出发,进行知识体系的组织和实践的编排。
简单说一下拆书联盟的活动,目前有几位小伙伴一起做拆书活动,首先由我做来第一期,然后是石雪峰,他是乐视配置管理和持续交付部门总监,他会给大家带来第二期拆书活动,后面还有王磊、大梁、景韵、赵班长等同学,都会参与到读书分享过程中。如果大家有兴趣可以联系我们,继续扩大阵容。
三步工作法是什么?如何通过三步工作法来指导DevOps的整体实施?以及它的核心思路和基础原则?
一、DevOps与其他管理运动
我们再来看一下DevOps与精益、敏捷和其他的管理运动的关系。
精益首先是精益,它是源自1980年代的丰田管理系统(TPS),关键实践包括价值流、看板和统一生产率维护方法等,目标是提升效率、减少浪费,通过小批量的工作缩短整个Lead Time。精益的原则聚焦在如何通过系统思考为用户创造价值。
敏捷再来看下敏捷,2001年提出了《敏捷宣言》,敏捷里强调轻量级软件开发,小批量、增量式的发布,小的团队提升组织的效率。然后是2009年Velocity大会,这个会上Flickr公司提出Dev和Ops如何做更好的协作,实现每天10次线上发布。很多人包括Gene Kim、Patrick、John Willis都参加了这次大会,然后组建起来DevOps阵营。
持续交付持续交付是2009年由Jez Humble和David Farley共同提出的,把持续集成做逻辑上的延展,形成持续交付的新方法。持续交付的核心概念是部署流水线,就是我们经常讲的Pipeline,Pipeline可以让我们确保代码和基础设施一直处于可部署的状态,所有签入到Trunk的代码都可以在安全的环境里部署。
-
持续改进还有一个运动大家提得比较少,是2009年的TOYOTA KATA运动,这里面提出一个困惑,这么多公司去学习丰田,但是没有一个学习丰田精益实践的组织能够复制丰田工厂观察到的高效。大家都在学丰田,为什么我们回来用他们的方法实践,却达不到丰田的高度呢?实际上我们遗漏了一个最重要的实践:improvement kata,就是改进的模式。
丰田之所以成功,因为他把改进作为日常工作的一部分,我们如果只是静态学习,别人有什么实践,我学习什么实践,这样不能达到卓越,我们需要保持持续改进。
DevOps本身的方法以及它的技术、架构、文化实践都参考了这些优秀的管理方法、管理运动、管理哲学,DevOps是以上这些方法的集大成者。
二、IT价值流与三步工作法
下面我们来具体看看如何提升效率,在说具体方法之前先解释一个概念,什么叫做价值流。图中左边是生产价值流,指的是生产制造领域中设计、开发和交付产品所需要的活动,包括信息和材料的双重流动。聚焦在创造平顺和流式的工作,关注小批量,避免返工,减少在制品等。
右边是技术的价值流,也就是IT的交付过程,从需求提出到开发、测试、部署、发布、运营整个的过程。我们认为技术的价值流同样可以采用在生产制造价值流中经过验证有用的技术。技术价值流关注从商业的假设提出,到把它转化成技术辅助服务,最终交付价值给用户。
技术价值流的重点在于如何聚焦和缩短部署的前置时间,这里面有两个部分。首先是上游,设计、开发的部分。其次是下游,测试、运营的部分。
我们认为在设计、开发部分是精益产品开发过程,特点是高度的易变性和不确定性,需要有深度创新的工作。下游的测试和运营,我们希望它有更好的预测性和机械性,以最小的易变性完成工作。
怎么达到这个目标?有两个核心方法:
一个是避免大批量工作从设计、开发价值流传递到测试、运营价值流,如瀑布流程或长分支。
另外一个是,让测试、运营与设计、开发同时进行,确保价值流快速流动和高质量。
如何加快速度,我们要关注Lead Time和Process Time。
Lead Time是前置时间,从需求提出到需求被满足的整个周期。Process Time是从开始工作到工作结束,不包含在队列里等待的时间。Lead Time和Process Time之间的比率是非常重要的衡量效率指标,快速流动和缩短前置时间最重要的一个抓手就是要缩短队列中的等待时间,这可能是我们日常工作中非常容易忽略的。
下面是两个常见的场景:
-
一个是传统的项目管理场景,大型复杂组织,紧耦合、单体应用,很稀有的集成测试环境,很长的测试和生产环境Lead Time,高度依赖手工测试,有特别多的审批流程。
类似这种的大型项目基本结果都是一样的,整个周期时间很长,普遍数周甚至数月。
-
另外一个场景,被认为是DevOps的典范,就像很多互联网公司做到的一样,在分钟级就可以完成从代码提交到上线的整个过程,包括从提交到自动化构建、自动化测试、手工探索性测试以及生产部署,所有这些事情可以很快完成。
如何做到?需要开发提交代码之后快速收到验证反馈,可以让这个反馈更快的指出什么地方被破坏了、什么地方存在问题,可以持续将小批量代码签入代码库,执行自动化测试,可以自动化做发布、自动化部署。
又因为整个系统模块都充分解耦,所以小团队可以高度自治,可以快速完成端到端流程。今天谈的是比较高阶的思路,如何从更宏观的角度去解决问题,我刚才提到的每个部分,包括如何做技术架构解耦,如何做自组织的适配,如何做到开发的自服务,这些内容在后面的分享里都会有详细的展开。
下面我们进入到三步工作法最核心的部分。整个DevOps实施可以分解为三步:
第一步是从左到右快速流动
第二步是从右到左快速反馈
第三步是在整个过程中持续学习。
每个部分我都做了一张总图,把核心思路做了梳理。
三、三步工作法的核心思路
3.1、三步工作法核心思路-Flow
第一部分是Flow,让价值快速流动,其中有六个实践,分别是:可视化、限制在制品、减少规模、减少交接数量、持续识别和拓展约束,以及在价值流中消除浪费。
3.1.1 让工作可视化
让工作可视化。技术价值流和生产制造价值流的区别是工作不可视,工厂里面有物料的流动和堆积,如果发现大量堆积,说明这里有瓶颈、有排队。而IT交付价值流里看不到显而易见的堆积,很多问题被隐藏掉,直到最后爆出更大的问题。
在DevOps领域里,包括敏捷、精益的理念,都在提可视化,通过可视化去管理价值流动。
图中左下角是一个典型的看板,看板里把整个软件的生命周期分成需求调研、需求就绪,开发进行中、开发完成,测试过程中、测试完成,以及UAT测试、准生产、发布等不同的列。通过这些列的划分,管理工作单元的流动,快速发现问题和解决问题。
通过看板可以让工作可视化、管理流动,并度量整个交付周期,看板一定要跨越整个价值流。
在这里推荐一本书,何勉老师最近编写的《精益产品开发》,前一个月刚上市,我认为是在国内做看板比较权威和完整的理论与实践相结合的书,强烈推荐大家阅读,里面会讲很多看板的方法和原则,如何建立、如何实践。
这里还要强调,做工作的可视化要考虑全局而不是局部,如果仅仅度量开发的完成率、度量测试发现了多少缺陷、度量系统的可用性,这些都是局部的目标。
我们更关注全局、端到端的价值流动,如何整体加快从需求提出到生产部署的时间,去增加服务的可靠性和质量。精益里讲全局的改进大于局部的优化。这是可视化的概述,看板也有很多方法和实践,后面的分享里再逐步分解。
3.1.2 限制在制品
限制在制品。刚才讲了很多Handbook里面的内容,下面讲两个小的故事,来理解在制品的概念。
-
第一个故事是“束水攻沙”,黄河千年以来都是由上游流下来很多泥沙,因为上游主要是在黄土高原,植被稀疏,泥沙不断流入黄河,导致黄河的河床不断抬高,所以我们叫黄河地上河,经常会有洪灾。
明朝时一个很有名的水利专家叫潘季驯,提出“束水攻沙”的治黄方针,通过收紧河道,利用水的冲击力去冲击河底的泥沙,从而达到清淤防洪的目的。更科学的理解,如果我们把河道的横截面收窄,水流的量是固定的,河流的河道收窄,河流的速度会加快,会提升水流携带沙的能力,解决泥沙淤积的问题。
“束水攻沙”,约束河道宽窄,把泥沙冲走,加快流速。在看板里很关键一个实践就是限制在制品,通过限制并行的任务数量,可以加速价值流动速度,并且帮助我们快速发现和解决问题。
-
第二个故事是“水落石出”,这个词最早出现在苏轼的一首诗里,另外我们也可以把它演绎成湖水岩石效应。当一个湖里有很多水,水面很高,湖中的石块都被这些水覆盖,这时即使有大的暗礁人也看不到。当水量逐步减小,一些大的石块暴露出来,如果水量进一步减少,中等石块、小石块也逐步被发现。
举一个亲身的例子,几年前我去一个银行参加他们新一代核心系统建设的工作,当时要求所有人996工作制,全银行包括外包都是怎么做的。但在具体执行的时候,虽然工作确实是早9点到晚9点,有些员工中午吃饭后去散散步,晚上去游游泳,保证时间跨度是在12个小时,但实际产出是不一样的。
从领导的角度来讲,要求所有的员工996,可能很难看到哪块有瓶颈、哪块有问题,因为从表面上看所有人都很忙。
更好的思路也许是稍微降低一下工作的负荷,从996加班慢慢恢复到一个正常水平,之后可能会发现有的部门比较轻松正常的完成工作,有的部门还在不断的堆积工作,在主动的加班,这时候瓶颈就发现了。我们叫“水落石出”,意思是说你降低了水面,问题自然就暴露了。
限制WIP的概念给我们一个启示,如果限制了我们正在并行处理工作的数量,可能自然而然会产生排队,可以看到问题到底在哪里。今天这两个故事“束水攻沙”和“水落石出”,希望大家能够更形象的理解,对大家去实施看板里的限制在制品会有一些帮助。
我们来看一个实际的看板,为什么要限制在制品?因为我们的工作来自于很多渠道,尤其是那些共享的职能部门,比如开发中心、测试中心、运维中心,我们有正常的任务,有工单、有邮件、有电话,也有老板临时派下来的紧急任务,日常工作经常会被打断,切换成本非常高。
以前有过一个大致的统计,如果同时做两个任务,每个任务所花的时间并不是50%,而是40%,因为有20%在做任务的上下文切换。
如果同时在做三个任务,花在每个任务上的时间只有20%,因为有40%的时间在做任务的切换。参照“束水攻沙”的思路,限制在制品,增加流速,让整个流动速度加快,并且更快的发现问题。
参照“水落石出”的故事引申,因为限制了在制品,会发现某些下游环节(可能是测试、或者部署等)发生排队,发现了阻塞就可以针对性的去解决问题。图中右上角还有一些tips,如果已经产生堆积,这时候你处理的策略是什么?这里面有非常经典的一句话,”Stop starting,Start finishing”,我们要暂缓开始、聚焦完成。
我前一阵在北京的望京工作,这边有个大山子十字路口,这个路口经常会堵车,那么如果交警发现双向车道已经堵死,他会怎么处理?我相信交警第一步处理的动作是暂缓开始,所有的车不要再进入这个路口,然后他要把中间已经堆积的车一辆一辆疏通掉。这就是一个暂缓开始、聚焦完成的例子。
3.1.3 减少批量规模
减少批量规模。这里面有一个简单的实验,如果有十封信要发,每封信制作需要四个步骤,分别是折纸、插入信封、封口、贴邮票。
有两种制作的方式:
第一种方式是大批量,先折完十张纸,把十张纸统一插入信封,统一封口,再把十个封口的信封统一贴上邮票。这么做下来,所有事情完成是310秒。但如果后期发现错误,比如在第200秒要做第四个步骤的时候,才发现与之前的步骤不匹配,那么这个时候前面所有的东西都要返工。
第二种方式,小批量策略,第一封信做完四个步骤再开始制作第二封信,以此类推,那么第一封信全部做完所有步骤只花费40秒时间,比方式一第一次完成交付要快8倍。如果第四个步骤发现前面的步骤有错,只需要把第一个信封的几个步骤重做,就可以在代价非常小的情况下修正错误。
所以很多人认为敏捷是一种快速交付软件的技术,其实并不是很准确,应该说它是一种能够更早交付价值的技术,让我能够更早的交付软件、灵活应对变化。
图中右上角有一些tips,小批量给我们很多好处,更快的前置时间,更快的发现错误和解决问题,更少的返工。通过这个小的实验,类比到IT交付价值流里,我们关注的方法叫做单件流,持续部署就是单件流的一种实现,只要代码提交入库,就自动做编译、测试、部署与发布,只要在我们的流水线里完成了所有验证,我们就认为这是一个潜在的可发布的版本。我们要减少批量的规模,频繁提交代码、频繁集成和验证,才能更早的进行交付。
3.1.4 减少交接数量
减少交接数量。这也是非常关键的一个实践,代码从提交版本库到运行在生产环境要经历很多过程,有很多部门要跨越。
部门之间交接是非常痛苦的事情,交接意味着有人要发出请求,有人要去响应,要做很多解释、说明,要做排期、排序,要解决冲突、做测试验证等等,整个过程是非常耗时并且痛苦的。
过多的交接一定会导致整体效率的下降,只要压力一上来,各个部门都是满负荷运作,一定会出现排队,就会导致前置周期加长,为了按时交付就需要向上升级,找到老板干涉项目,临时调整优先级,这会造成更多混乱。
DevOps怎么解决这个问题?最有效的方法是右下角这个图,即实现自服务,我们要建设一个自服务的平台赋能给开发。要提高整体生产效率,开发需要通过API和自服务的方式,自助完成常见的场景,比如申请环境、部署上线等。
在技术价值流里关注两个词,自动和自助,自动是系统或平台自动化的帮你完成日常操作,自助是给上游的开发人员赋能,让他愿意用运维做的系统或平台完成一些任务。
之前看到一个挺不错的文章,说DevOps分成四个阶段:
第一个是只有Dev没有Ops,所有的事情开发自己搞定。
第二个阶段是有Dev也有Ops,他们相互独立,Ops承接了开发代码之外所有的工作。
第三个阶段叫Dev+Ops,Ops做了一些自动化的工具提升效率,但主要是给自己去用,开发不用。
第四个阶段才是DevOps,在上游工作的开发愿意使用下游的运维提供的系统或平台,通过API自助、自动的完成相应的工作。
这个描述非常容易理解,大家可以记住右下角这张图,通过自服务和自助化,破解过多交接带来的消耗。
3.1.5 持续识别和拓展约束
持续识别和拓展约束。为了缩短前置时间并增加吞吐量,我们需要找到瓶颈点,只有在瓶颈点处的改进才是真正有效的。
我们来看一个视频,这个视频在模拟日常工作场景,每个人有不同的容量,有的人工作容量高,有的人低一些。经常会发现工作会堆积在整个价值流里工作容量最低的那个人或者部门头上,比如这里的3号工作人员,他的在制品不断堆积,他是整个价值流的瓶颈。到了第五天时,这个人最终崩溃了,无法继续完成工作。
这是约束理论带给我们的启示,我们需要找到和解决瓶颈,一般分为如下步骤:
第一步,识别瓶颈。找到队列最长那个人,刚才讲到的可视化、限制WIP都是找到瓶颈的关键方法。
第二步,考虑如何拓宽约束。找到能够拓宽约束点的办法,挖尽潜能。比如在瓶颈点人员很疲惫的时候有替代人员支持,或者通过自动化,人休息了但机器不停歇等。
第三步,协调整个组织配合上述决策。如果有了工作堆积,按刚才讲的策略是暂缓开始、聚焦完成,上游不要再急于推过来新的工作,而是把已经堆积的工作逐步完成。
第四步,提升系统约束。比如在最薄弱的环节增加资源,从本质上拓宽约束。
第五步,如果这个约束解决,回到第一步,但不允许惰性导致系统约束。就是说当一个约束点解决,下一个约束点可能就暴露出来,要持续解决约束。
上面是约束理论中解决约束的方法,我们再结合实际情况,看一下IT价值流中如何解决约束。在IT价值流中,约束一般按以下四个阶段演进。
首先是环境的约束。比如测试和生产环境通常需要向另外一个团队申请,可能数天数周才能搭建好。那么解决这个约束的对策,就是按需、完全自动化、自服务的方式申请环境。
如果环境问题解决了,大多数情况下第二个约束会到代码的部署,经过很多手工、易错的过程才能完成代码的部署。解决这个约束的对策,就是自动化部署,目标是实现部署过程的自服务化。
瓶颈点逐步转移,环境问题、部署的问题解决之后,通常瓶颈会转移到测试,测试有时候是由另外的质量控制部门去做,有可能花两周时间去准备环境和数据,然后再花另外四周做手工回归,这是无法满足快速交付要求的。解决这个约束的对策是自动化测试,让测试速度跟上代码部署速度,并且能平行进行。后面会讲到,通过持续集成、持续交付流水线,每次代码提交都会触发一个流水线的实例,这个实例运行自动化测试的时候可以并行做下一个功能的代码开发,尽量让测试的过程自动化,并且能够跟开发过程并行。
测试瓶颈解决之后,可能约束点就转移到了紧耦合的架构,代码的变更都需要工程师找到经理的审批,因为大家的代码是紧耦合的,一处变更可能会影响别人,所以需要整体控制。解决这个约束的对策是架构解耦,让变更以独立、自治的方式安全进行,从而提升开发效率。架构解耦、自组织团队是DevOps里非常关键的环节,虽然之前大家谈得更多是怎么实现自动化环境配置、自动化部署、自动化测试,实际上,解耦才是大型企业处理复杂问题的前置要素。
3.1.6 在价值流中排除浪费
在价值流中排除浪费。传统的制造业里有七种浪费,分别是传输浪费、动作浪费、过度生产浪费、过度加工浪费、等待浪费、库存浪费和缺陷浪费,后来又增加了一个创造力浪费。
在价值流里要提升效率,就要看到软件交付过程中的浪费。这里也列举了八种:
第一是部分完成的工作,比如未评审的需求文档和变更单。
第二是额外的流程,比如下游不使用的文档或者不增值的审批流程。
第三是额外的功能,精益创业里面有一句话,软件开发过程中最大的浪费就是构建没有人在乎的东西,也就是说范围镀金会增加不必要的复杂性、带来浪费。
第四是任务切换,前面为什么说要限制在制品,因为要尽量减少任务切换的浪费。
第五是等待浪费,包括等待工作所需要的资源等,这增加了周期时间。
第六是动作浪费,包括需要频繁沟通的人不在一地办公。之前我走访过一些企业,有的组织启动敏捷转型的一个必要条件,就是团队的成员必须要集中在一起办公,最大化的消除异地沟通中的浪费。
第七是缺陷浪费,如错误、缺失、不清晰的信息导致的缺陷。
第八是非标准的工作,比如手工操作、不可重建的环境等。在价值流中要识别和解决八种浪费,才能加快价值流的流动速度。
3.2、三步工作法的核心思路-Feedback
刚才把三步工作法的第一步 — 流动原则讲完了,下面来看第二步 — 反馈原则。这里有四个实践:
第一是在出现问题时及时发现
第二是密集解决问题、构建新的知识
第三是将质量向源头推进
第四是为下游工作进行优化。
先给大家一个背景的认知,我们工作在复杂系统之上。Cynefin框架描述了组织所处的环境。组织所处环境有五种类型,分别是简单、繁杂、复杂、混沌、失序。
简单是指,因果关系是清晰可见的。繁杂是指,因果关系明确,但是需要专家研究和解决。复杂是指,因果关系可以被回溯,但不可能提前预知,这是绝大多数企业所处的状态,这里有一个关键词是Emergent,翻译过来是浮现,即解决方案是慢慢浮现出来的,而不是一次性就明确的,所以需要不断探索、不断试错、不断迭代。
我们所处的环境就是复杂的环境,出现问题是不可避免的,我们要做的是在问题发现时,快速发现和解决问题。
3.2.1 及时发现,密集解决问题
左边的图指出,需要持续测试我们的设计和运营假设,要不断做验证,提升问题发现的速度,增加恢复能力。
要建立向前的反馈循环,比如原来采用瀑布模型,有可能花费一年的时间开发一个产品,到最后一个月测试才发现有重大问题,这种反馈是非常慢的。
我们建议的方式是快速迭代,持续集成、持续交付的方式。代码提交之后几分钟就能得到一个反馈,这次提交的代码如果存在错误,能快速发现、快速解决。
右边的图是密集解决问题,最典范的例子是安灯拉绳,丰田在生产汽车之前生产了丰田的织布机,丰田织布机里一个非常有用的装置就叫做安灯拉绳,也就是说发现问题的时候及时通报并解决问题。
在精益生产过程中都会有安灯拉绳的装置,参观汽车生产线时,可以看到有的车架上会有一个安灯拉绳装置,出现问题时可以被触发,立即发现问题而不是绕开问题。因为如果选择绕开问题,修复成本会几何上升,不断提升的技术债,让下游工作更难完成。