实现DevOps的三步工作法
《凤凰项目-一个IT运维的传奇故事》是一本比较神奇的书,用讲故事的方式,展现了IT团队(开发、测试、运维)在开发效能低、系统交付慢的情况下,通过实践三步工作法,在团队中实现加快系统交付、提升开发效能,使团队走上DevOps之路。而且本书有一个值得称道的地方是,通过类比制造业的工作流程,可以直观发现技术团队工作过程中隐藏的问题。
这里需要提醒一下开发人员,看书的时候一定要佛系,因为这个故事是以运维角度展开的,有一些大骂开发的情节。如果是想找具体的DevOps工具的,建议不要看了,里面没有具体的工具介绍,是以最朴素的方式,讲述DevOps的优势和实践。
先说一下概念:
- 价值流:一个组织基于客户的需求所执行的一系列有序的交付活动。或者,为了给客户设计、生产和提供产品或服务所需从事的一系列活动,它包含了信息流和物料流的双重价值。
- 技术价值流:把业务构想转化为向客户交付价值的、有技术驱动的服务所需要的流程。流程的输入是需求,由开发部门完成开发,进行整体测试,部署到生产环境正常运行,并为客户提供服务,以产生价值。
- 前置时间:从需求确认(开发接收需求)开始计时,到工作完成时结束
- 处理时间:从实际开始处理工作开始计时,到工作完成结束
- 等待时间:从需求确认(开发接收需求)开始计时,到实际开始处理工作时结束
- 在制品/半成品:价值流里没有彻底完成的工作、处于队列中的工作。部分完成的工作会逐渐过期,随着时间推移到最终失去价值。
- 约束点:价值流中的瓶颈,即整个价值流流速的上限点。
第一步:流动原则
第一步流动原则是为了打通技术价值流通道,实现开发到运维的工作快速从左到右流动。通过加速技术价值流的流速,缩短满足客户需求的前置时间,提高工作质量和产量,并使企业具有更强的竞争力。相关实践包括:持续构建、集成、测试和部署,按需搭建环境,限制在制品数量,构建能够安全实施变更的系统和组织。
通过持续加强工作内容的可视化,减小批次大小和等待间隔,内建质量以防止缺陷向下游传递,
使工作可视
在制造业,原料或半成品的堆积、订单积压都是直观可见,产生阻塞的地方,就是约束点。但是在技术价值流中,很多问题是隐藏的,没有办法很明显的看到阻塞和约束点。同时,因为信息的不可见或者彼此信息不全,可能将问题传递到下一环节,甚至上线时才出现问题,或者根本没法交付。这就需要尽可能的将工作可视化,用来识别工作在哪里流动、排队、停滞。
一般,可以使用Kanban管理(来自日语,就是看板)或Sprint计划板作为工具。
可视化管理中有一个需要注意的地方,要着眼全局目标,而不是局部目标。全局目标是增加系统质量,提升开发效能,局部目标是开发的完成率、测试的缺陷数、系统的可用性等。不是说局部目标不重要,这些局部目标需要其他方式来优化,我们现在需要提升整体的效率,一旦我们陷入细节中,就是一叶障目不见泰山,没有办法把握全局了。也就是吉恩•金所说的“不允许局部优化造成整体性能下降”。
限制在制品数
工作可视化之后,就可以开始有素质的找茬了。
第一步,限制并行任务。为什么?因为如果有并行任务,我们就需要花时间切换任务。有一种说法,如果同时进行两个任务,会有20%的时间用于切换任务,比如理清思路、进入状态、恢复工作环境等。如果是三个,那就会有40%的时间用于切换任务。并行任务越多,用于切换任务所花费的时间越多,造成的人力浪费越多。并行任务减少之后,浪费的时间减少,花费在工作上的时间就增加了,整体的交付效率也相应的提升。如果是用的是看板管理,可以通过限制每一列或每个工作中心在制品(并行任务)数量,并把卡片数量的上限标记在每一列上。
减小批量大小
这个就是敏捷中提倡的小步快跑,先交付,先尝试,就可以先试错,先改错,有问题可以及早暴露,不至于最后集成一个大疙瘩,无力回天。
这里不得不提持续部署,相信很多团队在使用持续部署工具,比如Jenkins,代码提交之后,触发Jenkins工作流,开始进行编译、测试、部署和发布。我们要做的就是小批次的提交代码,这部分代码被编译、测试,如果有问题,能够尽早发现,如果没有问题,经过测试发布到正式环境,就能够及早的呈现给客户。
减少交接次数
在传统的IT团队中,代码从开发完成到部署上线需要经过N多个部门,每个部门有自己的KPI,有自己的任务排期,不同部门沟通需要成本,工单审批需要时间,这样就造成了交付时间的延长。另外,不同部门对于一个功能的认知有自己的认知陷阱,开发认为理所当然的时期,运维可能根本不了解。信息的隔离,可能造成一些已知的缺陷没有及时传递到下游,出现各种返工的情况。
为了减少这种交接,可以引入自动化方式完成大部分的操作,或者调整架构,让团队尽量少的依赖于其他人。
持续识别和改善约束点
约束点就是瓶颈,如果整个团队中存在约束点,交付工作流就会有瓶颈。随着工作的优化,约束点之前的工作会堆积到约束点,而约束点之后的角色因为任务还没有到达,可能出现等待的情况。想要提升整体的效能,必须找到约束点,并进行拓宽,才能增加任务的吞吐量,任何不针对约束点进行的优化都是假象。
一般按照下面的步骤拓宽约束:
- 识别约束点,任务队列最长的角色,就是约束点;
- 根据找到的约束点,找到拓宽约束点的方式;
- 根据2中的决定,考虑全局工作;
- 改善系统的约束点;
- 如果约束已经拓宽,整个工作流中会出现新的约束点,重复上面的步骤。
消除价值流中的困境和浪费
想要提升交付效率,除了开源,还需要节流。减少任何超出客户需求和他们愿意支付范围的任何材料和资源:
- 半成品:价值流里没有彻底完成的工作、处于队列中的工作。部分完成的工作会逐渐过期,随着时间推移到最终失去价值。比如没有确认的需求、等待评审的变更。
- 额外工序:在交付过程中执行的、并未给客户增值的额外工作。比如对下游没有使用过的文档,或者对输出结果没有增值的评审。
- 额外功能:在交付过程中构建那些组织和客户完全不需要的功能,还没有到镀金阶段,却要浪费时间在镀金上,镀金的功能会增加功能测试和管理的复杂度和工作量。
- 任务切换:将人员分配到多个项目或价值流中,因为会出现任务切换,会在价值流中耗费额外的工作流和时间。
- 等待:由于资源竞争产生的等待,这将增加周期时间,延迟向客户交付。比如等待其他部门配合。
- 移动:信息或数据在工作中心之间移动的工作量。比如对于那种需要频繁沟通的人员不在一地办公,人员移动就产生浪费了。或者工作交接也会产生移动浪费,需要额外沟通。
- 缺陷:由于信息、材料或产品的错误、残缺或模糊,需要一定的工作量来确认。缺陷的产生和被检测出来的时间间隔越长,解决问题就越困难。
- 非标准或手工操作:需要依赖其他人的非标准或手动的工作,比如手动部署系统
- 填坑侠:为了实现组织目标,不得不把有些人和团队置于不太合理的处境。
只有解决了上面的八种浪费,系统的改进,减轻或消除这些负担,实现快速流动的目标。
第二步:反馈原则
第一步工作法是为了使工作能够在价值流能够从左向右流动,第二步工作法是创建从右到左的每个阶段能够快速、持续获得工作反馈的机制。该方法通过放大反馈环防止问题复发,并能够缩短问题检测周期,实现快速修复故障。我们的目标是从源头控制质量,并在流程中嵌入相关知识;创造更安全的工作系统,在故障或事故发生前检测到并解决它;最终建立安全和可靠的工作系统。
一般来说,发现和纠正问题最好的时机是发生故障时,只有发现问题,才能够解决问题。通过在整个工作流和组织中建立高质量的反馈机制,就可以在规模比较小、成本比较低的情况下修复系统。在灾难发生前消除问题,并创造出组织性学习氛围。
在复杂系统中安全地工作
复杂系统的一个重要特征是无法将系统视为一个整体,系统中的各个组件之间通常是紧耦合且紧密关联的,不能仅仅依据组件的行为解释系统的行为。复杂系统中故障存在且不可避免,所以我们需要设计一个安全的工作系统,可以让工程师们在系统中无所畏惧的开展工作,也就是各种折腾,这样才能在灾难发生前,快速检测出错误。可以采取下面4项措施让负载系统更加安全:
- 管理复杂的工作,从中识别设计和操作的问题
- 群策群力解决问题,从而快速构建新知识
- 在整个组织中,将区域性的新知识应用到全局范围
- 领导者要持续培养有以上才能的人
及时发现问题
想要及时发现问题,一般有两种做法:被动等待、主动试错。
通常,我们会搭建监控系统、设置多维度指标,对系统进行监控,当系统发生故障时,相关人员会收到报警信息,针对报警信息开始定位解决问题。这种方式属于被动等待的做法,因为要等待故障发生,故障发生的时机不可控,可能发生在上班的时候,更有可能发生在晚上睡觉时、周末休息时、休假旅游时,还有的会在结婚交拜的时,但是这种方式又不能没有,被动等待所搭建的监控系统是主动试错的基础。
主动试错就是在安全的工作系统中,不断对设计和假设进行验证,这种方式两个关键词是主动、安全。如果我们验证过程中把生产系统弄瘫了,那就笑话了。这样做的目标是更早、更快、以最低的成本、从尽可能多的维度增加系统的信息流,并尽可能清晰的确定问题的前因后果。能排除的假设越多,定位和解决问题的速度就越快。同时,这个过程也是练兵的过程,能很好的学习和创新。
群策群力,战胜问题获取新知
这个是承接“及时发现问题”的,因为发现问题之后,需要解决问题,我们需要发动所有相关人员,群策群力,解决问题。出现问题的时候,最忌讳的是绕开问题或者用“时间不够”这类理由搪塞。我们要做的是不惜全面停产,也要把问题解决。
至于为什么要相关人员都参与到解决问题中,理由如下:
- 相关人员参与定位和处理问题,能够让大家更深入的理解系统,把无法规避、早期无知阶段变成学习的过程。
- 能够防止把问题带入下游环节,一旦进入下游环节,修复成本和工作量将呈指数增加,还会欠下技术债
- 阻止启动新的工作,问题不解决,就开始新的功能,就会引入新的问题
- 不解决问题,故障就会再次发生,修复成本更高
在源头保障质量
这点主要是针对QA和开发两个部门,有点类似国家政策:“谁污染谁治理”。在日常工作中,我们需要价值流中的每个人在他们的控制领域内发现并解决问题,通过这种方式,可以把质量控制、安全责任和决策制定都置于开展工作的场景里,而不是依赖于外围高层管理者的审批。
比如开发人员开发过程中,可以使用自动化测试,不依赖于测试团队,这样,开发人员就能够在任何需要的时候快速测试自己的代码,经过完善的自动化测试,就可以把代码部署到正式环境中。这样,自己对自己负责,同时也是对他人负责。
为下游工作进行优化
这点负责的是精益原则:我们最重要的客户是我们的下游,为下游优化我们的工作,需要我们对他们有同理心,更好的识别可能阻碍快速平滑流动的设计问题。比如开发需要为运维优化自己的工作,比如架构、性能、稳定性、可测试性、可配置性、安全性等一系列特性,这些优化工作,和给客户提供功能同样重要。
第三步:持续学习与实验原则
第一步建立从左到右的工作流,第二步建立从右到左的反馈机制,第三步就是要建立持续学习与实验的文化,通过提升个人技能,进而转化为团队和组织的财富。
这一步的核心是建立高度信任的文化,这种文化强调每个人都是持续学习者,在日常工作中,主动承担风险;通过安全的方法改进工作和开发产品,从成功或失败中积累经验,从而识别有价值的想法,摒弃无价值的想法。个人的努力带动整体的进化,帮助整个团队尝试和实践新技术、新方法。
必要的做法包括营造一种勇于创新、敢于冒险(相对于畏惧或盲目服从命令)以及高信任度(相对于低信任度和命令控制)的文化,把至少20%的开发和IT运维周期划拨给非功能性需求,并且不断鼓励进行改进
建立学习型组织和安全文化
在复杂系统中,精确预测出结果是不现实的。也就是说,无论我们怎么小心,故障总是会发生。
Westrum模型提出组织文化的三种类型:
- 病态型组织的特点是大量的恐惧和威胁,倾向于隐藏失败。
- 官僚型组织的特点是严格的规则和流程,每个部门各扫门前雪,在这种组织中,通过评判系统处理事故,采用恩威并施的手段。
- 生机型组织是积极探索和分享信息,在这种组织中,整个团队所有员工共同承担责任,对事故积极反思并找到根本原因。
第三步推崇的就是生机型组织,在故障发生时,团队关注的是如何设计安全的系统,防止事故复发,而不是追究人的问题。正如Etsy的工程师拜塞尼•马克里说的:“不指责,就没有恐惧;没有恐惧,就能够坦诚;坦诚能够有效的预防事故。”
将日常工作的改进制度化
在技术价值流中,为了防止灾难性事故的发生,团队会陷入实施各种临时解决方案的工作中,这样就没有时间去完成那些有价值的工作。所以,用临时方案解决问题的模式,会导致问题和技术债务的累积。所以,我们需要在日常工作中留出时间来改善日常工作,比如偿还技术债务、修复bug、重构和优化代码等,这就要求我们的团队在开发间歇中预留一段时间,可以让团队成员解决问题。一件事情的果总会是另一件事情的因。我们在把日常问题解决了,有助于发现和解决潜在风险,或者有更多的精力去做更多有意义的事情。
把局部发现转化为全局优化
局部发现转化为全局优化就是说要在团队中做到先富带动后富。单个团队或个人获得了某种独有的知识或经验,应该把这种隐性知识(难以通过文档或沟通方式传递的知识)转换为显性知识,建立全局知识库,形成集体智慧。当其他人做类似的工作时,只需要在知识库中搜索,就能够很快找到前辈的经验。
在日常工作中注入弹性模式
这样做的目标是为了给团队或系统增加弹力,提升抗脆弱性。想要抗脆弱,就要知道脆弱点在哪。根据前人的经验,我们可以通过缩短部署实践、提高测试覆盖率、缩短测试执行时间、系统解耦等方式,提升系统的弹力。我们可以通过故障演练,比如随机的拔网线、关电源、杀进程(比如Netflix的Chaos Monkey)等,能够验证系统的恢复能够力。我们还可以通过压测(单接口、全链路)来测试系统的瓶颈和上限。
领导层强化学习文化
这点是说给领导听的,优秀的领导力不是体现在做出所有的决定都是正确的,而是能够为团队创造条件,让团队在日常工作中感受到这种卓越。因为领导者不会亲自参与到一线工作,一线工作者也不了解大的组织环境或者不具备工作领域以外做出改变的权利,所以领导者与一线工作者之间是互补关系,必须互相尊重。
最后
DevOps三步工作法作为支撑DevOps的基础原则,也衍生出了DevOps的行为和模式。相信很多团队已经开始走DevOps之路了,下面列出来4个阶段:
- 只有Dev没有Ops,所有的事情开发自己搞定。
- 有Dev也有Ops,他们相互独立,Ops承接了开发代码之外所有的工作。
- Dev+Ops,Ops做了一些自动化的工具提升效率,但主要是给自己去用,开发不用。
- DevOps,在上游工作的开发愿意使用下游的运维提供的系统或平台,通过API自助、自动的完成相应的工作。
可以看下自己处于那种阶段,如果没有达到,可以参考上面的三步工作法,一步一步的实现DevOps。