导言:展望DevOps新世界
- 在现实中,系统经常被破坏,服务和产品总是不尽如人意,团队的潜力无法得到正常发挥;在现实中,开发和IT运维是对立的,测试和信息安全活动总是在项目晚期才进行,这导致即使发现 了问题也来不及修复;在现实中,产品和服务交付中的关键活动往往全都需要手动操作和互相交接,我们总是要等待其他人的工作完成才能进行自己的工作;在现实中,特性交付的周期一次次被拖延,质量也频频出现问题,特别是与生产环境部署相关的部分,进而对客户和业务造成了负面影响。结果,不仅是我们的工作无法按预期完成,整个公司也对IT部门的业绩不满意,甚至导致预算被削减,IT员工没有成就感,感觉无力改变流程及其结果。怎么办?我们需要改变工作方式,没错,DevOps能够给我们指引方向。Pxvii
- 在制造业革命前(20世纪80年代的制造业革命),制造厂的平均交货周期为6周,能按时交货的订单不到总量的70%。随着精益实践的广泛实施,到2005年,产品的平均交货周期缩短到3周以下,按时交货的订单超过总量的95%。而那些没有实施精益实践的厂商,不但渐渐失去了市场,有的甚至破产了。
到21世纪初,由于技术的快速发展以及敏捷原则和实践的应用,新功能开发所需的时间已经从几年缩短至几个月,但是部署到生产环境仍然需要几周甚至数月,而且部署过程中还总是伴随着大量不可预知的状况。到2010年,随着DevOps的出现,以及硬件、软件和公有云的不断商品化,任何特性(甚至整个公司的创建)都可以在几个星期内完成,并在几小时或几分钟内部署到生产环境中。Pxviii - 在几乎所有的IT公司中,开发部门和IT运维部门之间都存在一种固有冲突,这会让公司业 绩下滑,进而导致新产品和新功能的上市时间拉长、质量下降、服务中断时间增加,甚至导致技术债务量与日俱增。Pxix
- “技术债务”这个术语是Ward Cunningham首次提出的。类似于金融债务,技术债务是指我们当前所做出的决定会导致一些问题,而这些问题随着时间的推移会越来越难解决,未来可采取的措施也越来越少。即使我们审慎地承担技术债务,也依然会产生利息。Pxix
- 开发部门和IT运维部门的目标是对立的,这通常是产生技术债务的一个因素。IT公司需要负责的事情很多,其中包括下面两个必须实现的目标:Pxix
- 对变化莫测的市场做出反应;
- 为客户提供稳定、可靠和安全的服务。
开发部门通常负责对市场变化做出响应,以最快的速度将新功能或者变更上线。而IT运维部门则要以为客户提供稳定、可靠和安全的IT服务为已任,让任何人都很难甚至无法引入可能会危害生产环境的变更。这种配置方式让开发部门和IT运维部门的目标和动因之间存在巨大的冲突。称这种配置为“根本的、长期的冲突”——公司对不同部门的考核和激励不同,阻碍了公司全局目标的实现。
- 绝大多数投资项目都在某种程度上依赖于信息技术。俗话说:“想要做出一个不会带来任何IT变更的商业决策几乎不可能。”Pxxi
- 许多心理学家认为,创建一个让人感觉无能为力的系统,是我们能对人类同胞做的最具破坏性的一件事——我们剥夺了他人控制自己成果的能力,甚至营造了一种文化,让人们因为害怕遭受惩罚、失败或危及生存而不敢做正确的事。这创造了“习得性无助”的环境,人们变得不愿或 无法采取行动来避免未来遇到同样的问题。Pxxii
- 自动化测试可以帮助开发人员快速发现错误(通常在几分钟之内),实现更快速的修复以及6真正的学习。如果错误是在6个月后的集成测试中发现的,那时相关的记忆和因果关系早已消退,想从中学习是不可能的。自动化测试使技术债务不再积累,问题在发现之后就立即被修复了。如果需要,这还可以调动整个公司参与问题的处理,因为总体目标高于局部目标。Pxxiii
- 在出现问题时,我们进行不指责的事后分析,这并不是要惩罚某人,而是为了更好地理解导致事故的原因,以及如何防止事故再次发生。这个方法强化了我们的学习文化。我们还通过举办 内部技术研讨会来提高技能,保证所有人不是在教就是在学。Pxxiv
- 应用了DevOps的高绩效公司在以下方面的表现远超低绩效同行:Pxxv
- 吞吐量指标;
- 代码和变更部署次数(频繁30倍);
- 代码和变更部署前置时间(快200倍);
- 可靠性指标;
- 生产环境部署(变更成功率高60倍);
- 平均服务恢复时间(快168倍);
- 组织性能指标;
- 生产力、市场份额以及营业目标(大约2倍以上);
- 市值增长(3年内高出50%)。
- Frederick Brooks 在其著名的《人月神话》一书中强调过这一点。他解释说,当项目延迟时,增加更多的开发人员不仅降低了单个开发人员的生产力,而且也降低了整体的生产力。Pxxv
第一部分 DevOps介绍
- DevOps的三步工作法:流动、反馈及持续学习与实验。P1
- 流动原则:它加速了从开发、运维到交付给客户的流程。
- 反馈原则:它使我们能建设出更安全可靠的工作体系。
- 持续学习与实验原则:它打造出一种高度信任的文化和一种科学的工作方式,并将对组织的改进和创新作为日常工作的一部分。
- DevOps和它所产生的技术、架构及文化实践,体现了哲学和管理学原则的融合。P1
- DevOps基于精益、约束理论、丰田生产系统、柔性工程、学习型组织、安全文化、人员优化因素等知识体系,并参考了高信任管理文化、服务型领导、组织变动管理等方法论。把所有这些最可信的原则综合地应用到IT价值流中,就产生出DevOps这样的成果。将它贯彻于整个技术价值流中,涉及产品管理、开发、QA、IT运维和信息安全专员等不同角色,在更低的成本和努力下,保障产品的高质量、可靠性、稳定性和安全性。P1
- 精益的两个主要原则包括:坚信前置时间(把原材料转换为成品所需的时间)是提升质量、客户满意度和员工幸福感的最佳度量指标之一 ;小批量任务的交付是缩短前置时间的一个关键因素。P2
- 在敏捷宣言中,一个重要的原则是“频繁地交付可工作的软件,交付周期可以是数星期也可以是数月,推荐更短的周期”,并强调使用小批量任务进行增量发布,而非大规模的作业和瀑布流程的发布。同时,强调建立自组织的小团队,让成员在高度信任的环境中愉悦地工作。P2
- 精益社区中大多数企业都没有抓住精益的核心——改善套路(Kata)。 他解释说,所有企业都有日常的工作流程,而这些日常工作决定了最终的产出。通过设定目标, 制订每周的详细计划,并持续改善日常工作,如此循序渐进,才能达到优化和改进的目的。P3
第1章 敏捷、持续交付和三步法
- Value Stream Mapping 一书中把价值流定义为“一个组织基于客户的需求所执行的一系列有序的交付活动”。在 DevOps 中,我们通常将技术价值流定义为“把业务构想转化为向客户交付价值的、 由技术驱动的服务所需要的流程”。P4
- 在第一个阶段中,工作主要包括设计和开发,它和精益产品开发有很多相似之处:都具有高度的变化性和不确定性,不仅需要创意,某些工作还可能无法重来,这导致无法确定总体处理时间。在第二个阶段中,工作主要包括测试和运维,它类似于精益制造。相比前一个阶段,它需要创造性和专业技能,力求可预见性和自动化,将可变性降到最低(如短的和可预测的前置时间,接近零缺陷),并满足业务目标。P5
- 前置时间在工单创建后开始计时,到工作完成时结束;处理时间则从实际开始处理这个工作时才开始计时,它不包含这个工作在队列中排队等待的时间。因为前置时间是客户能够体验到的时间,所以我们把重点放在缩短前置时间而不是处理时间上。P5
- 技术价值流中的第三个关键指标是完成时间和精确的总花费时间的百分比(%C/A)。该指标反映了价值流中的每个步骤的输出质量。P7
- 三步工作法:DevOps的基础原则。P7
- 第一步,实现开发到运维的工作快速地从左向右流动。为了最大程度地优化工作流,需要将工作可视化,减小每批次大小和等待间隔,通过内建质量杜绝向下游传递缺陷,并持续地优化全局目标。
- 第二步,在从右向左的每个阶段中,应用持续、快速的工作反馈机制。该方法通过放大反馈环防止问题复发,并能缩短问题检测周期,实现快速修复。通过这种方式,我们能从源头控制质量,并在流程中嵌入相关的知识。这样不仅能创造出更安全的工作系统,还可以在灾难性事故发 生前就检测到并解决它。
- 第三步,建立具有创意和高可信度的企业文化,支持动态的、严格的、科学的实验。通过主动地承担风险,不但能从成功中学习,也能从失败中学习。通过持续地缩短和放大反馈环,不仅能创造更安全的工作系统,也能承担更多的风险,并进行试验帮助自己比竞争对手改进得更快, 从而在市场竞争中战胜他们。
第2章 第一步:流动原则
- 通过持续加强工作内容的可视化,减小每批次大小和等待间隔,内建质量以防止缺陷向下游传递,从而增强流动性。通过加速技术价值流的流动,可以缩短满足内部客户和外部客户需求的前置时间,进一步提高工作质量,并使我们更加敏捷,能够比竞争对手更为出色。P9
- 技术行业的工作内容是不可见的,这是其与制造业价值流相比的一个显著差异。另一方面,技术工作的流转通过单击一次鼠标就可以完成,譬如将工单重新指派给另一个团队。由于点击的操作太过容易,所以不同团队可能会因为信息不完整而将工作“踢来踢去”,存在的问题也会被传递到下游工序,而这些问题完全是不易察觉的,直到无法按时向客户交付产品,或者应用程序在生产环境中出了问题。P9
- 通过限制在制品数,还能更容易地发现工作中的阻碍。P10
- 在精益中,一个重要的经验是:为了缩短前置时间和提高交付物质量,应当持续不断地追求小批量模式。理论上,最小的批量是单件流,也就是每次操作只执行一个单位产品的处理。P12
- 一项工作在团队之间交接时,需要大量的沟通——请求、委派、通知、协调,而且经常需要排优先级、调度、消除冲突、测试和验证。这些工作可能还需要使用不同的工单系统或项目管理系统,编写技术规范文档,用会议、电子邮件或电话的形式进行沟通,可能还涉及文件共享服务器、FTP服务器和Wiki页面的使用。
为了减少这类问题的出现,要么努力减少交接次数,要么用自动化方式执行大部分操作,要么重新调整组织结构,让团队不必依赖其他人就可以独立地为客户提供价值。因此,要通过减少队列中的等待时间以及非增值工作的时间来增加流动性。P13 - 在任何价值流中,总是有一个流动方向、一个约束点,任何不针对此约束点而做的优化都是假象。P14
- 识别系统的约束点;
- 决定如何利用这个系统约束点;
- 基于上述决定,考虑全局工作;
- 改善系统的约束点;
- 如果约束点已经突破了,请回到第一步,但要杜绝惯性导致的系统约束。
- 在DevOps的转型过程中,如果希望前置时间从月或季度缩短为几分钟,那么一般需要依次优化下面的约束点。P14
- 环境搭建。
- 代码部署。
- 测试的准备和执行。
- 紧密耦合的架构。
- 精益中对浪费的常用定义是“使用了超出客户需求和他们愿意支付范围的任何材料或资源的行为”。P15
- 浪费和困境是软件开发过程中导致交付延迟的主要因素。关于浪费和困境的部分类型。P15
- 半成品:它指的是价值流里任何还没有彻底完成的工作。
- 额外工序:在交付过程中执行的、并未给客户增值的额外工作,可能包括那些在下游工10作中心从没使用过的文档,或是对输出结果做出的并不增值的评审或审批。
- 任务切换:将人员分配到多个项目和价值流里后,他们需要进行上下文切换,并管理工 作之间的依赖关系,这会在价值流中耗费额外的工作量和时间。
- 等待:由于资源的竞争而在工作之间产生了等待,这将增加周期时间,延迟了向客户交付价值。
- 移动:信息或数据在工作中心之间移动的工作量。
- 缺陷:由于信息、材料或产品的错误、残缺或模糊,而需要一定的工作量来确认。缺陷 的产生和被检测出来的时间间隔越长,解决问题就越困难。
第3章 第二步:反馈原则
- 反馈回路是学习型组织和系统思维的重要组成部分。反馈和前馈回路让系统内各部件之间的关系增强或抵消。P18
- 在制造业,如果缺乏有效的反馈机制,往往会酿成重大质量和安全问题。有这样一个典型的案例:通用汽车的弗里蒙特制造厂既没有有效的流程来检测装配过程中的问题,也没有明确的步骤来解决问题。结果导致了各种问题,比如发动机倒置,汽车缺少方向盘或轮胎,甚至是由于根本无法启动,不得不把汽车拖出装配流水线。P19
- 反馈回路不但能让问题的快速探测和修复成为可能,而且还能告诉我们如何防止问题复发。这样做不但提高了工作系统的质量和安全性,还创造了组织性知识。P19
- 群策群力的原因如下:P20
- 防止把问题带入下游的处理环节,否则不但修复的成本和工作量会呈指数级增加,而且还会欠下技术债;
- 防止工作中心启动新的工作,那样可能会在系统中引入新的错误;
- 如果问题还没有得到解决,那么工作中心在下一次操作(如55秒后)中,可能还会遇到相同的问题,需要更高的修复成本。
- 全民总动员是“实时的问题识别、定位和处理(在制造业称为对策或纠正措施)循环的一部分。这就是休哈特提出的循环(即PDCA环)——计划(Plan)、实施
(Do)、检查(Check)、改进(Act),后来由爱德华兹·戴明推广并得到了迅猛发展”。P20
第4章 第三步:持续学习与实验原则
- 技术价值流的核心是建立高度信任的文化。它强调每个人都是持续学习者,必须在日常工作中承担风险;通过科学的方式改进流程和开发产品,从成功和失败中积累经验教训,从而识别有价值的想法,摒弃无用的想法。另外,所有局部的经验都会快速转化为全局性的改进,从而帮助整个组织尝试和实践新技术。P23
- 企业文化中安全和绩效重要性的鼻祖之一。他曾指出,在医疗机构中,患者的生命安危高度依赖于医疗机构的“生机”文化。他定义了三种类型的文化。P24
- 病态型:病态型组织的特点是组织中存在大量恐惧和威胁。由于政治原因,个体为了保全自身利益,通常会隐瞒真相或者歪曲事实。在这种组织中,故障和事故经常被隐瞒。
- 官僚型:官僚型组织的特点是规则和流程僵化,所有部门通常都“自扫门前雪”。在这种组织中,通过评判系统处理事故,结果往往恩威兼施。
- 生机型:生机型组织的特点是积极探索和分享信息,让组织更好地履行使命。在这种组织中,整个价值流中所有的员工共同承担责任,对事故进行积极反思,并进行真正的根因调查。
- 如果不指责,员工就没有了恐惧,没有了恐惧,就能够做到坦诚,而坦诚能够有效预防事故。消除指责能够有效实现学习型组织,使“组织自我诊断和自我优化,并能熟练地定位和解决问题”。P25
- 领导力的优秀并非体现在做出的所有决定都是对的。相反,更卓越的领导力其实是为团队创造条件,让团队能在日常工作中感受到这种卓越。换句话说,这需要领导者和员工们共同的努力,每个人都相互依存,缺一不可。P28
- 清晰地描述出要解决的问题,对解决方案所做的假设,验证假设的方法,对结果的解释,以及如何利用经验进行下一个迭代。P28
- 上一步做了什么?发生了什么?
- 你从中学到了什么?
- 现状如何?
- 下一个目标条件是什么?
- 当前工作有什么阻碍?
- 下一步做什么?
- 期望的结果是什么?
- 什么时候能进行复查?
第二部分 从何处开始
第5章 选择合适的价值流作为切入点
- 我们必须认真挑选转型项目,因为在遇到困难时,我们并没有退路。必须仔细挑选和保护那些最有可能改善组织现状的重点转型项目。P32
- 他们的第一个目标,是提高发布速度或实现按需发布,从而拥有更强的迭代能力和对客户反馈的响应能力。为此,他们专门组建了一个为移动端应用提供支持的产品团队,让这个团队能够独立地开发、测试并向客户交付价值。通过这种方式,该团队不再需要依赖内部的其他团队,也不再需要与它们协作。此外,将一年一次的规划改为持续规划。这样一来,他们便能根据客户需求为移动端应用制作一份独立的优先级工作清单,从而避免由于同时支持多个产品而导致的优先级冲突。P33
- 软件服务或产品常被分为绿地项目和棕地项目,这两个术语最初用于描述城市规划和建设项目。绿地项目是指在未开发的土地上建设的项目,而棕地项目则是指在以前用于工业生产的土地上建设的项目,这样的土地可能受到有毒物质或污染物的侵蚀。P34
- 应用的年龄并不是影响性能的主要因素;相反,性能取决于应用架构在当前(或重构后)是否具有可测试性和可部署性。P35
- 高德纳公司近年来帮助双模IT(bimodalIT)这一概念得到普及。双模IT指的是企业能够支持各种类型的服务演进。在双模IT中,传统的记录型系统是指类似于ERP的系统,它的交易和数据的正确性是至关重要的;交互型系统则是指面向客户或员工的可交互系统,例如电子商务系统和办公软件。记录型系统的变化速度通常较慢,称这种系统为“类型1”,侧重于“做得正确”。交互型系统的变化速度通常较快,因为它需要快速响应反馈,通过实验找到最能满足客户需求的方式。称这种系统为“类型2”,侧重于“做得快速”。P36
- 所谓跨越鸿沟,是指客户困难并找到比创新者和早期采用者更大的群体。P36
- 扩大DevOps范围。P37
- 发现创新者和早期采用者:一开始,把重点放在真正有意愿改进的团队上。这些同事与我们志同道合,他们是探索DevOps的第一批志愿者。这些同事最好受人尊重,并对组织中的其他人有着很大的影响力。他们的支持有助于提升创新的可信度。
- 赢得沉默的大多数:在下一阶段,力求将DevOps实践扩展到更多的团队和价值流,目标是建立更稳固的群众基础。通过与接受DevOps的团队合作,即便他们并不是最有影响力的团队,也能对扩大群众基础有所帮助。有了更多的成功之后,就会产生从众效应,进一步增强影响力。需要谨慎避免与唱反调的人发生冲突。
- 识别”钉子户”:所谓“钉子户”,是指那些高调的、有影响力的反对者。他们最有可能抵制(甚至破坏)DevOps计划。一般来说,只有在获得大多数人的支持并建立起足够稳固的群众基础后,才考虑如何应对这个群体。
- “小鱼在小池塘里成为大鱼。”通过谨慎地选择DevOps转型的切入点,我们在组织的某些领域内进行实验、学习并创造价值,但不会给整个组织带来不可逆的后果。同时,通过这种方式,我们能够建立稳固的群众基础,赢得在组织中推广DevOps的机会,从而获得更多支持者的认可和感激。P38
第6章 理解、可视化和运用价值流
- 在选择好DevOps试点应用或服务后,必须确定价值流的所有成员,他们有责任共同为客户创造价值。确定了价值流的相关成员之后,下一步是深入理解工作方式,并用价值流图进行记录。在价值流中,最初的工作是确定客户需求或进行业务构思,这由产品负责人完成;然后,开发团队接手,他们通过编程实现相关功能,并将代码提交到版本控制系统中;接下来,在类生产环境中对功能进行集成和测试,最后部署到(理想情况下)能为客户创造价值的生产环境中。P40
- 绘制价值流图的目标并不是记录所有的步骤和细节,而是识别出阻碍价值流快速流动的环节,从而缩短前置时间和提高可靠性。根据价值流参与团队所提供的全部信息,应该重点分析和优化下面两类工作:P41
- 需要等待数周甚至数月的工作,例如准备类生产环境、变更审批流程或安全审查流程等;
- 引发或处理重大返工的工作。
- 价值流图的初始版本应该只包含重要的流程模块。即使是针对复杂的价值流,参与小组通常也可以在几个小时内绘制出包含5~15个模块的价值流图。每个模块至少应包括工作项的前置时间和处理时间(分别为图 6-1 中的 LT 和 VA2),以及由下游消费者测量的%C/A。P41
- 应该组建专门的转型团队,并使之独立于负责日常运作的部门(他们称前者为“专职团队”,称后者为“绩效引擎”)。最重要的是,这个团队应该负责实现明确定义的、可度量的、系统级的目标(例如,将“从提交代码到部署至生产环境”这一过程的前置时间减少50%)。为了做到这一点,应该采取以下措施:P43
- 转型团队的成员专门执行DevOps转型工作(而不是让他们继续做之前的工作,但要花 20%的时间来做DevOps转型);
- 选择熟悉多个领域的通才作为团队成员;
- 选择与其他部门长期保持良好关系的人作为团队成员;
- 如果可能,为团队找一个独立的办公区域,使各位成员尽可能多地相互交流,并和其他部门保持适当的距离。
- 在任何 DevOps 转型项目中,都需要保持小跨度的改进计划,正如创业公司做产品开发或客户开发一样。应该努力在数周内(最差也应该在数月内)获得可度量的改进成果或者可用的数据。通过缩短计划跨度和迭代间隔,可以做到以下几点:P44
- 具备重新计划和更改优先级的能力和灵活性;
- 减少工作从实施到生效的延迟时间,从而加强反馈回路,这将更有可能强化期望的行为——初步成功有利于加大投入;
- 从迭代中更快地获得经验,并将其用于下一次迭代;
- 能够更省力地获得改进;
- 在日常工作中更快地实现有意义的差异化改进;
- 降低项目还没有取得成果就被终止的风险。
- 为了积极地管理技术债务,要确保至少把20%的开发和运维时间投入到重构、自动化工作、架构优化以及非功能性需求(有时也称为“质量属性”)上,例如可维护性、可管理性、可扩展性、可靠性、可测试性、可部署性和安全性等。P44
- 产品负责人和工程师之间的协作是这样的:产品负责人需要考虑把团队20%的资源分配给与工程相关的活动,用于重写或重构代码库中有问题的部分,或者工程师认为有必要改进的部分,从而避免有一天他们对团队说:“我们需要停下来重写所有代码。”如果情况已经非常糟糕了,那就可能需要投入30%甚至更多的资源。然而,如果发现团队认为他们不需要20%的资源就能做这些事情,我会感到非常担心。P44
- LinkedIn 的“反转行动”(Operation InVersion)在两个月内,停止所有特性开发,并对计算环境、部署和架构进行全面的优化。P45
第7章 参考康威定律设计组织结构
- 康威在他的论文中写道:“在对工作难度和工作时间进行了初步评估以后,其中5人被分配到了COBOL开发小组,剩余3人被分配到了ALGOL开发小组。结果是,COBOL编译器有5个执行阶段,ALGOL编译器则有3个。”之后,康威提出了著名的康威定律:“软件的架构和软件团队的结构是一致的,说白了就是‘如果让4个团队开发同一个编译器,那么编译器最后会有 4 个执行阶段’。”P50
- 在决策科学领域,主要有3种组织结构类型:职能型、矩阵型和市场型。P51
- 职能型组织结构注重提高专业技能、优化分工或降低成本。这些组织以专业技能为中心, 有助于促进职业发展和技能发展,并且通常具有多层次的组织结构。运维部门通常采用这种组织结构(即服务器管理员、网络管理员和数据库管理员等都被划分成单独的小组)。
- 矩阵型组织结构试图结合职能型和市场型。然而,正如许多管理矩阵型组织或身处其中的人所看到的那样,这种组织结构通常都非常复杂。例如,一名员工可能需要向两个甚至更多的经理汇报。有时,矩阵型组织既实现不了职能型结构的目标,也实现不了市场型结构的目标。
- 市场型组织结构注重快速响应客户需求。这种组织往往有着扁平化的结构,由多个跨职能的部门组成(例如市场营销部门和工程技术部门等),整个组织可能往往存在冗余现象。很多实施DevOps的杰出组织采用了这种结构。举两个极端的例子。在亚马逊和 Netflix,每个服务团队不仅要负责特性的交付,而且还要负责服务支持。
- 执行工作的人通常都不太理解自己的工作与价值流目标有什么关系(“我之所以要配置这台服务器,是因为别人要我这么做”)。这样就无法让员工发挥创造性和主动性。P52
- 如果运维部门的每个职能团队都要同时服务于多个价值流(即多个开发团队),那么问题更是雪上加霜,因为所有团队的时间都很宝贵。为了使开发团队及时完成工作,运维部门常常不得不将问题反映到管理层,从经理、总监一直到决策者(通常是总经理),再由决策者按照组织的全局目标(而不是局部目标)为工作安排优先级。然后,决策再逐级下达至各个职能部门,最后调整局部的优先级,而这又会降低其他团队的速度。每个团队都在加速工作,而最终的结果却是所有项目都以同样缓慢的速度向前推进。P52
- 以市场为导向的团队不但要负责特性开发,而且在整个应用生命周期中还要负责测试、安全、部署和生产环境的运维。这些跨职能团队可以独立运作——能够设计和开展用户实验,构建和交付新特性,在生产环境中部署并运行服务,不依赖于其他团队就能修复任何缺陷,从而加快行动的步伐。亚马逊和 Netflix 正是采用了这种模式,这也是亚马逊快速发展的一个主要原因。P53
- 只要服务团队能够快速(最好是按需)从运维团队获得可靠的帮助,那么集中式的职能型运维组织也可以实现高效运转,反之亦然。包括谷歌、Etsy和GitHub在内的许多著名DevOps公司都保留了职能型运维团队。P53
- 在谈到开发和运维的共同目标时,Ticketmaster的首席技术官Jody Mulkey说:“在过去近 25 年的时间里,我一直用美式橄榄球比赛来比喻Dev和Ops。其中,Ops是防守组,试图阻止对方得分;Dev则是进攻组,其目标是尽全力得分。而有一天,我突然意识到这个比喻并不恰当,因为Dev和Ops从来没有在同一时间出现在球场上,他们实际上不属于同一个团队!”。他继续说道:“我现在用的比喻是,Ops是进攻内锋,Dev则负责重要位置(如四分卫或外接手)。Dev的工作是持球冲锋,Ops的工作则是保证Dev有足够的时间向前冲。”P55
- “两个比萨原则”保持团队规模小型化——两个比萨够团队的所有成员吃,这样的团队通常有5~10人,这种规模限制有以下 4 个重要作用。P57
- 它确保团队成员对系统有清晰、相同的理解。当团队规模变大时,如果要让所有人都了
解系统状况,需要沟通的信息量就会成倍增加。 - 它限制正在开发的产品或服务的增长率。通过限制团队的规模,系统的发展速度也受到限制,这也有助于保证团队成员对系统有相同的理解。
- 它分散权力并实现自主。每个“双比萨”团队都尽可能地自主工作。团队负责人直接向管理层汇报,由他决定团队负责的关键业务指标(又称适应度函数),并将其作为团队实践的总体评估标准。然后,团队能够自主采取行动来最大限度地提升该指标。
- 领导“双比萨”团队是让员工获得领导经验的一种方式。在这样的环境中,即使失败了也不会有灾难性后果。亚马逊的策略有一个关键要素,即“双比萨”团队的组织结构与面向服务架构之间的联系。
- 它确保团队成员对系统有清晰、相同的理解。当团队规模变大时,如果要让所有人都了
第8章 将运维融入日常开发工作
- 大鱼游戏公司的 DevOps 转型,展示了集中式运维团队如何取得以市场为导向的成果。以下是3个通用的策略:P62
- 构建自服务能力,帮助开发人员提高生产力;
- 将运维工程师融入服务团队;
- 如果运维工程师人数紧张,则可以采用运维联络人模式。
- 运维部门若想取得以市场为导向的成果,一种做法是创建一套集中式的平台和工具集服务,让所有开发团队都能够通过使用这套平台和服务来提高生产力,例如搭建类生产环境、部署流水线、自动化测试工具、生产环境遥测控制台等。P62
- 运维提供的所有平台和服务应该是全自动化的,并且能按需提供,不需要开发人员提交工单,然后再等待运维团队手动处理,这能保证运维不成为客户的瓶颈。P62
- “以支持工程团队的创新和速度为先。我们不为这些团队构建、打包或部署任何产品,也不为他们管理配置。相反,我们构建自助工具。他们可以依赖我们的工具,但不能依赖我们的劳动力。”P63
- 由于各种原因(如成本或者资源不足),可能无法给每个产品团队都分派运维工程师,但可以给每个产品团队指定一位运维联络人。运维联络人也要参加团队的站会,把团队的需求纳入整体的运维计划,并且在必要的时候执行相关任务。在发生资源竞争或优先级冲突时,团队依赖运维联络人推进问题的解决。派遣的运维工程师的责任是理解下列内容:P64
- 新产品的功能是什么,为什么要开发这个产品;
- 它是怎样工作的,可运维性如何,可扩展性和监控能力如何;
- 怎样监控和收集指标,如何确认应用的功能正常;
- 架构和模式是否与以往的做法不同,这样做的理由是什么;
- 是否对基础设施有额外的需求,它的使用对基础设施容量的影响如何;
- 特性的发布计划。
- 每日站会的目的是在整个团队范围内分享信息,同时了解所有正在做和将要完成的工作。通过让团队成员相互分享信息,可以发现面临难题的任务,然后用互助的方式找到解决方法,从而从整体上推进工作。P65
- 看板图是工作可视化管理的理想工具。可视化是将运维工作融入产品价值流的关键。如果在这方面做得好,不管组织结构如何调整,我们都能取得以市场为导向的成果。P67
第三部分 第一步:流动的技术实践
- 将QA人员和运维人员的任务集成到团队的日常工作中,能够减少救火、困境以及琐事的发生,让团队成员的工作高效且充满乐趣。这不仅能提升团队的工作质量,也能增强组织的竞争力。P69
第9章 为部署流水线奠定基础
- 为了使工作快速可靠地从开发流向运维,应当保证价值流的每个阶段都使用类生产环境。此外,这些环境必须能用自动化的方式进行搭建。在理想情况下,应该使用脚本和存储在版本控制系统中的配置信息按需搭建,而不需要依赖运维团队进行手动操作。部署流水线的目标就是能够基于版本控制系统中的信息重复搭建整套生产环境。P70
- 在过程中保证质量,而不是事后检查质量。P70
- 导致软件发布变得混乱或具有破坏性甚至灾难性结果的一个主要原因,是在发布过程中才首次看到应用如何在类生产环境中处理真实的数据。P71
- 可以使用自动化的方式完成以下操作:P72
- 复制虚拟化环境(如 VMware 虚拟机镜像、执行 Vagrant 脚本,以及启动 Amazon EC2 虚 拟机镜像文件);
- 构建“裸金属物理机”的自动化环境搭建流程(例如,使用 PXE 方式通过基线镜像进行 安装);
- 使用“基础设施即代码”的配置管理工具(例如 Puppet、Chef、Ansible、SaltStack、CFEngine 等);
- 使用操作系统自动化配置工具(例如 Solaris Jumpstart、Red Hat Kickstart 和 Debian preseed);
- 使用一组虚拟镜像或容器(例如 Vagrant 和 Docker)搭建环境;
- 在公有云(例如 Amazon Web Services、Google App Engine 和 Microsoft Azure)、私有云或其他 PaaS(平台即服务,如 OpenShift 和 Cloud Foundry 等)中创建新环境。
- 版本控制系统记录了对系统中的文件或文件集合所做的变更。可以进行提交、对比、合并以及从仓库中还原出以前修订版本的对象。版本控制系统还能通过把生产环境中的对象回滚到之前版本来降低风险。将所有的源文件和配置文件都纳入版本控制系统后,它就变成了唯一精确体现系统预期状态的代码仓库。P73
- 为了确保即使在发生灾难性事故时,也可以重复且精确地(最好还能快速地)恢复生产环境, 必须把下列资源也纳入版本控制系统:P73
- 应用的所有代码和依赖项(例如库、静态内容等);
- 任何用于创建数据库模式的脚本、应用的参考数据等;
- 所有用于搭建环境的工具和工件;
- 任何构建容器所使用的文件;
- 所有支持自动化测试和手动测试的脚本;
- 任何支持代码打包、部署、数据库迁移和环境置备的脚本;
- 所有项目工件(例如需求文档、部署过程、发布说明等);
- 所有云平台配置文件;
- 创建支持多种基础设施服务(例如企业服务总线、数据库管理系统、DNS区域文件、防火墙配置规则和其他网络设备)所需的任何其他脚本或配置信息。
第10章 实现快速可靠的自动化测试
- 如果没有自动化测试,那么我们编写的代码越多,测试代码所花费的时间和金钱也会越多。在大多数情况下,这种商业模式对于任何技术组织而言都是无法扩展的。P77
- 团队不接受任何没有通过自动化测试的变更。他们搭建了持续集成流水线,同时设置了测试覆盖率监控指标,确保逐渐提高测试覆盖率,并编写了测试规范和指南,坚持让团队内部和外部的相关人员都照章执行。P78
- 正确的持续集成实践总是可以确保代码处于可部署和可交付的状态。P79
- 在任何时候,构建和测试流程都能够运行,无论工程师的个人工作习惯如何。
- 独立的构建和测试流程确保工程师能理解构建、打包、运行和测试代码所需的全部依赖
项(即消除“应用在开发人员的笔记本电脑上能运行,但是在生产环境中不行”的问题)。 - 将应用的可执行文件和配置打包,并可以在环境中重复安装。
- 将应用打包到可部署的容器中,而不是把程序代码打包。
- 以一致、可重复的方式进行类生产环境的配置。
- 有了部署流水线基础设施之后,还必须有持续集成实践,这需要以下3个方面的配合:P81
- 全面且可靠的自动化测试套件,用于验证可部署状态;
- 一种在验证测试失败时,可以“停掉整条生产线”的文化;
- 开发人员在主干上工作,并小批量提交变更,而不是在生命周期很长的特性分支上工作。
- 自动化测试从快到慢分为如下几类。P82
- 单元测试:通常独立测试每个方法、类或函数。
- 验收测试:通常整体测试应用,确保各个功能模块按照设计正常工作。
- 集成测试:保证应用能与生产环境中的其他应用和服务正确地交互,而不再调用打桩的接口。
- 可以得出一个推论:最快速的测试应该尽可能多地发现错误。P83
- 搭建性能测试环境很可能比为应用准备生产环境还要复杂。因此,可能需要在项目启动时就搭建性能测试环境,并确保能够为尽早、正确地搭建准备好所需资源。P86
- 我们认为团队目标高于个人目标——在帮助他人推进工作的同时,也帮助了整个团队。这包括帮助他人解决构建或自动化测试的问题,甚至进行代码审查。P88
第11章 应用和实践持续集成
- 开发人员在自己的分支上独自工作的时间越长,就越难将变更并入主干。事实上,当分支个数和每个分支上的变更数同时增加时,合并难度会骤增。P90
- 尽管分支策略有很多种,但是可以分为以下两类。P92
- 提高个人生产力:所有人都在自己的分支上工作。每个人都独立地工作,并且不能干扰其他人;然而,代码合并将是一场噩梦。协作将变得相当困难,每个人都不得不谨小慎微地合并代码,即便是完成系统里最小的部分也是如此。
- 提高团队生产力:所有人都在同一个区域里工作。并没有分支,只有一条很长、不可被中断的主干;也没有规则,因此代码的提交过程很简单。但是,任何一次提交都有可能破坏整个项目,同时导致项目中断。
- 大批量合并的另外一个副作用是,合并难度越大,开发人员就越不可能(也越不愿意)改进和重构代码,因为重构很可能导致其他所有人返工。在这种情况下,人们就更不愿意去修改那些在整个代码库中都有依赖项的代码。不幸的是,这样的代码往往价值最高。P93
第12章 自动化和低风险发布
- 当完整记录目前的部署流程以后,下一步的目标便是尽可能地简化和自动化手动步骤,举例 如下:P98
- 将代码打包成便于部署的格式;
- 创建预配置的虚拟机镜像或容器;
- 将中间件的部署和配置自动化;
- 将安装包或者文件复制到生产服务器;
- 重启服务器、应用或者服务;
- 基于模板生成配置文件;
- 通过执行自动化冒烟测试,确保系统能正常运行,并且配置正确;
- 运行各种测试程序;
- 将数据库迁移工作脚本化和自动化。
- 为了更好地促进工作,需要一个可以由开发人员或运维人员来执行的代码发布流程,并且在理想情况下,应该不需要任何手动操作或工作交接。这个流程的步骤如下。P101
- 构建:部署流水线必须基于版本控制系统构建可部署到任何环境(包括生产环境)的软件包。
- 测试:任何人都应该能够在他们的工作站上或测试系统中运行任何一个自动化测试套件。
- 部署:任何人都应该能够将这些软件包部署到具有访问权限的任何环境,通过执行(已提交到版本控制系统中的)脚本来完成部署。
- 金丝雀发布,Facebook为了采用这种发布模式而创建的运行环境组。P108
- A1组:仅向内部员工提供服务的生产环境服务器。
- A2组:仅向一小部分客户提供服务的生产环境服务器,在软件达到某些验收标准后部署(自动化部署或手动部署均可)。
- A3组:其余的生产环境服务器,软件在 A2 组中达到某些验收标准后再部署。
- 集群免疫系统扩展了金丝雀发布模式,将生产环境的监控系统和发布流程联系起来,并在面向用户的生产系统的性能超出预定范围时(如新用户的转化率低于15%~20%),自动回滚代码。P108
- 黑启动技术成为可能——先把所有特性都部署到生产环境中,然后对客户不可见的特性执行测试。对于大规模或高风险的变更来说,黑启动过程往往持续数周,从而保证在正式发布之前使用类生产负载安全地进行测试。P110
第13章 降低发布风险的架构
- 紧耦合架构不仅会降低生产力,还会影响安全变更的能力。接口定义清晰的松耦合架构则与20之相反,它优化了模块间的依赖关系,提高了生产力和安全性,让小型且高产的“双比萨”团队可以执行小的变更,并能安全和独立地进行部署。因为每个服务都有一个定义明确的API,所以更容易测试,团队之间的服务等级协议条款也更容易确定。P115
第四部分 第二步:反馈的技术实践
- 通过放大日常工作中的反馈信号,可以在问题发生的时候,立刻识别并解决它们,同时将工作系统打造得更加安全,让我们有信心在生产环境中实施变更的同时开展产品实验,确信能够快速探测和修复故障。为了达到以上效果,需要探索和落实如下工作:P123
- 建立能定位和解决故障的遥测系统;
- 使用监控更好地预测故障,感知业务目标的达成情况;
- 将用户研究和反馈融入到研发团队的工作中;
- 为开发和运维提供反馈,让他们能安全地部署应用;
- 用同行评审和结对编程的反馈方式,提高工作质量。
第14章 建立能发现并解决问题的遥测系统
- 遥测被广泛定义为“一个自动化的通信过程,先在远程采集点上收集度量数据,然后传输给与之对应的接收端用于监控”。P125
第15章 分析遥测数据以更好地预测故障和实现目标
第16章 应用反馈实现安全部署
- 通过建立服务发布指南,有助于确保用整个组织的集体智慧,特别是运维团队所累积的经验, 去帮助每一个产品开发团队。服务发布指南和要求可能包括以下内容。P155
- 缺陷计数和严重性:应用程序是按设计运行的吗?
- 告警的类型/频率:在生产环境中应用程序所产生的告警数量是否太多,无法得到支持?
- 监控覆盖率:监控覆盖的范围是否够大,能够为恢复故障服务提供足够的信息?
- 系统架构:服务松耦合的程度是否足以支持生产环境中高频率的变更和部署?
- 部署过程:在生产环境中代码部署的过程是不是可预测的、确定性的和足够自动化的?
- 生产环境的整洁:是否有迹象表明生产习惯已经足够好,可以让其他任何人提供生产
支持?
- 要求产品团队在生产环境中管理自己开发的服务,会促使开发人员转换到运维的工作视角,但这是在LRR和HRR的指导下进行的,这不仅使服务转换变得更容易、更可预测,而且有助于在上游与下游工作中心之间建立同理心。P158
第17章 将假设驱动的开发和A/B测试融入日常工作
- Jez Humble指出:“验证业务模式或产品理念的最低效的方法,是构建完整的产品以查看设想中的需 求是否真实存在。”P160
第18章 建立评审和协作流程以提升当前工作的质量
- 丰田生产系统的核心理念之一是“最了解问题的人通常是离问题最近的人”。让距离工作越来越远的人来做相关审批的步骤,这实际上可能会降低工作成功的概率。P169
- 保持小批量尺寸的原则也适用于代码评审。变更的批量越大,评审工程师理解这些工作需要花费的时间就越长,他们的负担也越大。正如Randy Shoup所说:“变更的批量与整合这个变更的潜在风险之间存在着非线性的关系——从10行代码的变更到100行代码的变更,发生错误的风险不止高出10倍。“请程序员来审查10行代码,他会找到10个问题。请他审查500行代码,他会说看起来都不错。”P171
- 代码评审的指导原则如下。P171
- 每个人在将代码提交到主干以前,必须要有同行来评审他们的变更。
- 每个人都应该持续关注其他成员的提交活动,以便识别和审查出潜在的冲突。
- 定义哪些变更属于高风险的变更,从而决定是否需要请领域专家(例如数据库变更、安全性敏感的身份验证模块等)来进行审查。
- 如果提交的变更尺寸太大了,以至于让人很难理解——换句话说,阅读了几遍代码还无法理解,或者需要提交者进行解释——那么这个变更就需要分解成多个较小的变更来提交,使之一目了然。
- 代码评审有如下几种形式。P171
- 结对编程:程序员结对地在一起工作。
- “肩并肩”:在一名程序员编写了一段代码后,评审程序员接着就逐行阅读他的代码。
- 电子邮件送审:在代码被签入到代码管理系统中后,系统就立刻自动向评审者们邮寄一份代码。
- 工具辅助评审:编码者和审阅者都使用专门用于代码评审的工具。
- 在Gerrit代码评审流程中观察到的问题是,开发人员通常需要等待整整一周的时间,才能得到他们所需要的评审结果。更糟糕的是高级开发人员的感受:“即使是一个简单的变更,也无法迅速地进入代码库,这是令人非常沮丧和崩溃的体验,因为我们无意中创造了一个让人无法忍受的瓶颈。有能力对变更评论‘+1’的人都是高级工程师,他们还有许多其他职责,所以通常对初级开发人员所做的修复或生产力不太关心。P175
第五部分 第三步:持续学习与实验的技术实践
第19章 将学习融入日常工作
- Netflix团队通过运行“捣乱猴”(Chaos Monkey)不断地将故障注入到预生产和生产环境中,从而实现了运维上的恢复性目标。P181
- 如果对待事件和事故的反应被认为是不公正的,就可能阻碍安全调查,从而在从事安全关键性工作的人员中引发恐惧而非正念,使组织更加官僚而不是更加小心谨慎,并且诱发职业性保密、逃避和自我保护。P181
- 人为错误并不是问题的原因;恰恰相反,人为错误是我们提供的工具存在设计问题而造成的后果。P181
- 有两个有效的实践有助于创造公正的学习型文化:一是不指责的事后分析;二是在生产环境中引入受控的人为故障,用于创造机会针对复杂系统中不可避免的问题进行练习。P182
- 在不指责的事后分析会议上,我们会做以下事情:P182
- 构建时间表,从多个角度收集关于故障的所有细节,保证不会惩罚犯错误的人;
- 通过让所有工程师详细说明自己如何导致了故障,使他们能够提高安全性;
- 允许并鼓励那些犯错误的人成为教育他人以后不会犯同样错误的专家;
- 营造一个自由决策的空间,让人们决定是否采取行动,并且把对所做决定的评判放在
事后; - 制定预防类似事故的对策,并确保记录这些对策、目标日期和负责人,以便进行跟踪。
- 组织唯一的可持续竞争优势就是比对手更快的学习能力。P189
第20章 将局部经验转化为全局改进
- 在聊天室中自动化执行操作具有许多优点(和通过命令行运行自动化脚本相比):P190
- 每个人都能看到发生的一切;
- 新来的工程师也可以看到团队的日常工作及其执行方式;
- 看到其他人互相帮助时,人们也会更倾向于寻求帮助;
- 建立起组织学习,知识得到快速积累。
- 将自动化运维和聊天室集成在一起有助于记录和分享我们的观察和问题解决过程,使其成为日常工作中不可分割的一部分。这还加强了透明、协作的文化,有益于我们所有的工作。P191
- GitHub创造的协作环境能够将在局部学习到的知识转化为整个组织的经验。P191
第21章 预留组织学习和改进的时间
- 改善闪电战经常采取的形式是,一个小组聚在一起,专注探究一个存在问题的流程......改善闪电战通常持续几天,目标是优化流程,方法则是集中地让流程之外的人给通常在流程里的人提建议。P198
- 我们每隔几个月就举行一次黑客马拉松,每个人都为自己的新想法设计原型。最后,整个团队聚在一起,检阅所有已经完成的工作。P200
- 为了全面提升谷歌内部的自动化测试实践,他们使用了改善闪电战、内部教练,甚至内部认证计划。P203
第六部分 集成信息安全、变更管理和合规性的技术实践
- 我们不仅要提高安全性,而且还要创建更易于审计、能证明控制有效性的流程,以遵从监管义务和合同义务。相关的举措如下:P205
- 使安全成为每个人工作的一部分;
- 将预防性的控制代码集成到共享代码库中;
- 将安全性与部署流水线集成;
- 将安全性与监控集成,从而更好地检测和恢复;
- 保护部署流水线;
- 将部署活动与变更审批流程集成;
- 减少对职责分离的依赖;
第22章 将信息安全融入每个人的日常工作
- 当涉及信息安全和合规性时,我们发现在项目结束时解决项目阻塞比开始阶段更加昂贵,其中信息安全阻塞的成本最高。在此过程中,‘用演示证明合规性’成为了我们尽早消除所有复杂性的一个惯例。P208
第23章 保护部署流水线
- 几十年来,我们将职责分离用作减少软件开发过程中欺诈或犯错风险的主要控制手段之一。 大多数软件开发生命周期都已经接受的做法是:要求将开发人员变更提交给代码库管理员接受审 查和批准变更,然后由IT运维将变更部署到生产环境。P
224