DevOps
第 1 章 认识 DevOps
第 1 章将介绍 DevOps 的概要以及 DevOps 相关的关键词。在阅读完本章之后,读者将掌握DevOps 相关的基础知识,了解什么是DevOps,并可以自己去查找相关的方法和技术资料。下面,我们就来介绍一下 DevOps 诞生的背景,以及支撑 DevOps 的方法和工具。
1-1 DevOps出现的背景
假设你正在参与某一产品或者服务的开发。如果要求你提高产品和服务的商业价值,你要怎么去应对呢?提高商业价值的开发又是什么呢?也许你会有一些对策,不过如果有一种工作方式可以通过迅速、持续的改善来不断增加新功能,以此打败竞争对手,或者能够灵活地对不够完善的措施进行修正,你觉得怎么样呢?
DevOps 指的是通过 Dev(开发)和 Ops(运维)的紧密合作来提高商业价值的工作方式和文化。通过开发和运维之间的协作,DevOps 能够减轻不同团队之间的消耗(overhead),提高开发速度,并通过互相理解来增强变更的灵活性。DevOps 不仅是一种工作方式,还涉及团队建设和开发流程的设计等,可以说越想深刻理解 DevOps,就越需要更广泛、更深奥的知识。
即使在网上仔细搜索,也很难找到能一针见血地说出“什么是 DevOps”的内容,也没有明确的定义来说明做某种特定的事情就是在实践 DevOps。
DevOps 之所以包含如此广泛的思想,和它产生的复杂背景有着紧密的关系。
伴随开发方法和工具的发展,出现了很多支持持续改善开发的工具。然而开发和运维的分离导致了很多问题,为了解决运维层面的问题,这些工具又得到进一步发展。因此,我们会先介绍 DevOps 出现的背景,以便读者能够更深刻地理解为什么 DevOps 会包含如今的这些工具和方法。
本书共分为 6 章,第 1 章介绍 DevOps 的概要和背景,第 2 章介绍如何从个人开始进行 DevOps 实践,第 3 章介绍如何在团队内展开 DevOps,第 4 章之后以实践和运用为基础,介绍如何阶段性地实施 DevOps。因此,我们先在第 1 章概述 DevOps,然后从第 2 章开始介绍如何着手去实践 DevOps。
1-1-1 DevOps诞生的背景
DevOps 思想不是突然出现的,而是有着复杂的背景。在经过长时间的发展而成熟起来的持续开发(continuous development,以敏捷开发为代表的开发方法)的基础上,如何才能更加高效地开发,如何才能实现持续改善,相信很多人都对此烦恼过。而对这些困扰大家的但又必须采取措施解决的问题加以整理后,就演进到了现在的 DevOps。那么,DevOps 的根本问题到底是什么呢?我们先来介绍一下 DevOps 诞生的土壤,大致有以下两点。
以敏捷开发为代表的持续开发方式的出现
持续开发带来的运维问题
敏捷开发(图 1-1)等持续开发方式衍生的各种工具和方法,以及由此带来的运维方面的问题,促使 DevOps 思想的诞生,这也是现在 DevOps 的概念、方法和工具的支撑。首先,我们按顺序来看一下这两个要素。
图 1-1 传统的开发方式和敏捷开发
1-1-2 以敏捷开发为代表的持续开发方式的出现
在 20 世纪 80 年代,瀑布模型开始在软件开发中广泛使用。
如图 1-2 所示,瀑布模型中划分了明显的开发阶段,在一个开发阶段没有结束之前就不能开始下一个阶段的工作。开发阶段的划分方法各式各样,大体上说包括计划、需求分析、设计、实现、测试、发布和运维这几个阶段,像瀑布一样从上一级向下一级移动。为了提高系统整体的质量,每个阶段都会形成明确的产出物,所以会耗费很多时间。在瀑布模型中,每一阶段都以前一个阶段的完成为前提,因此在设计或实现完成之后,几乎不会再对这些阶段进行变更。即使有变更,由于测试之前的各个阶段的需求都已基本确定,而且在发布之前就已经耗费了很长时间,所以要在各个开发阶段中增加新的需求,大多数情况下都是不可能的,不过这也要视开发规模而定。
图 1-2 瀑布模型和敏捷开发
另一方面,现在的网络服务都要求能在短时间内发布新功能以及进行改善。对于那些灵活性要求很高的开发,比如在短时间内需求不断变化,或者需要反复进行细微变更的,瀑布模型就显得捉襟见肘了,于是原型法和敏捷开发等开发方式应运而生,形成了支持在短时间内进行周期性开发的基础。原型法是一边运营服务一边汲取服务反馈的方法。敏捷开发是指以小规模团队为前提,每次只发布最低限度的功能集,然后听取客户的反馈,进行持续改善。
敏捷开发和瀑布模型不同,会频繁添加新的功能。为了能够应对在瀑布开发等传统开发方式中难以想象的高频率更新,进行持续改善,开发人员创造了很多提高持续性和效率的开发方法和工具,持续集成方法就是其中之一。关于持续集成,我们会在第 3 章进行说明。
开发人员在自己的工作范围内不断推进自动化和高效化,创造了持续集成等方法,提高了最终产品的生产效率,但同时也开始意识到运维方面还有很多问题需要解决。
1-1-3 持续开发带来的运维问题
开发者想要解决运维方面的问题,于是开始思考基础设施相关的构建和配置如何才能变得更高效。其实,很早以前就出现了用于使基础设施的构建和配置自动化的工具。随着敏捷开发的普及,这些自动化工具也逐渐被用到提高效率和进行持续开发上来。
开发团队和运维团队,特别是和基础设施团队之间本来就有很多问题,2008 年,这些问题开始受到敏捷开发实践者的关注。
在 Agile 2008 Conference(敏捷大会 2008)上,帕特里克·德布瓦(Patrick Debois)发表了题为“Agile Infrastructure & Operations”(敏捷基础设施与运维)的演讲。
在这一演讲中,德布瓦提到了“IT people, Operations separated from Dev. by design”(人为地将运维团队从开发团队中分离)这一现状,并在幻灯片中以这一现状导致的问题为例对存在的主要问题进行了说明。另外,在“Infrastructure, Development and Operations”(基础设施、开发和运维)中,他也列举了基础设施团队并不关心应用程序的例子。
该演讲还指出运维方面积累了很多技术负债,比如因为不知道会有什么影响而不敢使用补丁进行更新,硬件的支持期限即将到期,通过重启脚本使服务恢复正常,迁移(migration)操作执行到一半不能继续执行,等等。
当然,开发方面也有很多问题:团队成员都是专家,不做其他人的工作;本应罗列所要添加的新功能和改善事项的待办事项列表最后积累的都是 TODO 项目;不了解应用程序的内部构造;由于各个团队都有独立的团队经理,比如产品经理和运维经理,于是出现了多个产品负责人(product owner),从而导致无法发现真正的需求,等等。在“Agile Infrastructure And Development”(敏捷基础设施和开发)中,德布瓦指出了开发者只关注功能性需求,却忽略了监控、冗余、备份和操作系统等非功能性需求的问题。
在这个演讲中,德布瓦并不只是简单地抛出问题,同时也提出了几种解决方法。
对于运维方面的问题,可以通过名为 daily scrum 的每日会议来解决,根据团队成员的兴趣程度进行优先级排序,或者以结对(pair)的方式完成任务。在演讲中,德布瓦还提出了信息辐射(information radiation)的必要性,指出要形成信息的自然传播。
这里需要着重说明的是开发问题的解决方法。德布瓦在幻灯片中介绍了包含基础设施团队在内的敏捷开发模式,即跨功能型团队(cross functional team)这一解决方案,建议在开发初期就尽早将基础设施方面的需求可视化,如果有问题的话需要明确解决问题的负责人。
这个演讲之后,在 Agile 2009 Conference(敏捷大会 2009)上,安德鲁·谢弗(Andrew Shafer)发表了题为“Agile Infrastructure”(敏捷基础设施)的演讲。
在这个演讲中,谢弗将 Web 开发中出现的开发和运维之间的混乱称为“混乱之墙”(wall of confusion),并指出开发和运维需要跨过这堵墙,进入到对方的领域。针对这一点,谢弗介绍了用基础设施即代码(Infrastructure is code)的方法来实现敏捷基础设施(类似于敏捷开发的基础设施运维)。另外,演讲中也提到了本书将要介绍的通过基础设施即代码的方法来推进 Web 开发的相关内容。
在版本化管理(versioning everything)的例子中,谢弗还提到了除软件之外还要引入配置管理来对基础设施进行管理的方法,以及一站式部署(one stop deploy)、监控和基础设施的持续集成等内容。
此外,作为信息共享的基本思想,该演讲中还提出为了让开发和运维在同一个地方能看到相同的内容(Dev and Ops see the same thing, in the same place),可以将配置信息代码化,保存到同一个软件管理系统的仓库(第 2 章)中实现可视化,同时也介绍了分支使用原则(第 3 章)中从主分支进行发布的方法,以让全员明确所使用的版本。
就像上面介绍的那样,持续开发带来的运维问题促使 DevOps 思想的土壤逐渐形成,作为该问题的解决对策,开发和运维通过信息共享的可视化过程,加速了基础设施代码化,形成了基础设施即代码的世界。
在介绍 DevOps 出现之后的情况之前,我们先来回顾一下伴随着 DevOps 土壤的形成而逐渐发展起来的基础设施即代码的历史。
用于解决运维问题的 provisioning 工具
作为解决运维问题的方法之一的基础设施代码化,是由对服务器、存储和网络等基础设施进行配置的 provisioning(服务提供)工具发展而来的。 provisioning 这个词汇有很多含义,不同的工具对基础设施进行设置的内容也不统一。在 Velocity 2010 大会上,李·汤普森(Lee Thompson)发表了题为“Provisioning Toolchain”(服务提供工具链)的演讲,在这个演讲中,作者将服务器的 provisioning 工具分为 3 层,如表 1-1 和图 1-3 所示。
表 1-1 provisioning 工具的 3 层
层 |
说明 |
相关工具的例子 |
---|---|---|
编排 |
负责部署或者节点之间的集群管理等,对多个服务器进行设置和管理 |
Capistrano、Func |
配置管理 |
对操作系统或者中间件进行设置 |
SmartFrog、CFEngine |
引导 |
创建虚拟机、安装操作系统等 |
Kickstart、Cobbler |
图 1-3 provisioning 架构图
最底层的引导(bootstrapping)层负责创建虚拟机或者安装操作系统。
比如在 IaaS(Infrastructure as a Service,基础设施即服务)这一提供基础设施环境的云服务中,这一层指的就是启动虚拟机或者创建容器的工作。从用户的角度来看,相当于基础设施运维人员在硬件上安装操作系统时使用的工具。现如今虚拟机和 Docker 之类的容器都已经是很普遍的技术了,通过创建服务器的镜像作为虚拟机模板,并以镜像为基础进行后续的配置变更,基础设施工程师所负责的工作范围就逐渐从硬件偏向了软件,引导层的工作量也会逐渐减少。现在已经出现了能连贯地完成创建虚拟机、配合使用 Kickstart 安装客户端操作系统以及做成模板这一整套工作的工具,比如 HashiCorp 公司的 Packer,它能完成安装操作系统、变更配置并进行模板化管理等一连串的工作。
接下来的配置管理(configuration)层负责在完成引导的服务器上进行操作系统的配置变更和中间件的安装配置等工作。
编排(orchestration)层负责将开发完成的应用程序一次性部署到多台服务器上,并对多台服务器进行统一的配置管理。
最近随着 Puppe、Chef 和 Ansible 等工具的出现,配置管理层和编排层的界限变得越来越模糊,比如这些工具可以根据用途等将服务器分为 Web 服务器组、数据库服务器组等,并对各服务器组进行设置或执行某些命令(图 1-4)。
图 1-4 近年来的 provisioning 架构图
基础设施即代码和 DevOps
基础设施即代码是指将基础设施代码化,包括使用上面提到的 provisioning 工具将所有配置进行代码化、信息化的全部内容。其中非常重要的一点是,所有基础设施的构建、配置变更都需要根据基础设施的配置信息来进行,所有成员都可以访问配置信息,按照配置信息完成的配置也会反映在实机上。
使用 provisioning 工具,特别是配置管理工具,无须人工直接访问目标服务器,通过在定义文件中编写服务器或者中间件的配置信息,即可由这些工具按照定义文件的要求完成配置变更。这些工具也是解决“持续开发带来的运维问题”的核心工具集。通过编写定义文件,基础设施的配置就可以以声明的方式来描述,也就不再需要用来消灭不同基础设施平台间差异的专业知识了。因此,即使是应用程序工程师,也可以通过编写配置信息来构建基础设施。
如上所述,基础设施即代码可以通过将基础设置的配置代码化,从而将基础设施引入软件领域,使软件开发的方法也同样适用于基础设施的构建和配置。为了进行配置变更,我们可以像写代码一样编写配置信息,并像应用程序开发一样使用测试工具来对配置信息进行测试,并将通过测试的配置信息和代码一样进行版本管理。像这样,在基础设施的构建和运维中就可以使用开发部门的敏捷开发等持续开发方法。不仅如此,正如基础设施即代码的字面意思那样,基础设施可以用代码来描述,不过编写这种代码并不需要高级的编程知识。大多数配置管理工具采用了比通用编程语言学习成本低很多的领域专用语言(DSL),即使是对程序设计不是很熟悉的基础设施工程师,通过付出类似掌握一般中间件配置的学习成本,也都可以编写基础设施的配置文件。因此,不管是基础设施工程师还是应用程序工程师,都可以在基础设施的配置和运维方面进行深入合作。
在通过开发和运维的紧密合作来提高商业价值的 DevOps 中,应用程序开发工程师能够从软件开发的角度来理解基础设施的运维,或者直接对基础设施的配置进行变更,这种基础设施即代码的思想是非常重要的。
配置管理工具的历史和特点
如今各种新的工具不断涌现。下面我们就以配置信息的处理方式为中心,看一下配置管理工具的历史和特点。
现代配置管理工具的鼻祖 CFEngine 是 1993 年由马克·伯吉斯(Mark Burgess)以开源软件形式发布的。CFEngine 采用 C 语言编写,优点是非常轻量。另外,它还有一个更吸引人的优点,那就是可以用 DSL 来描述配置信息,而非用 C 语言扩展的形式来消除不同系统之间的差异。
2005 年卢克·坎尼斯(Luke Kanies)在 Puppet Labs 公司发布了使用 Ruby 语言开发的 Puppet。Puppet 可以在被称为 Manifests 的配置信息文件中用自己的 DSL 对配置进行声明。和采用 C 语言编写的 CFEngine 相比,使用 Ruby 语言开发的 Puppet 具有更好的可移植性。
2009 年亚当·雅各布(Adam Jacob)发布了使用 Ruby 和 Erlang 编写的 Chef。Chef 采用以 Ruby 语法为基础的 DSL 在配置信息文件 Recipe 中描述配置信息,它的优点是可以在配置文件中直接使用 Ruby 的语法。
2012 年迈克尔·德哈恩(Michael DeHaan)发布了使用 Python 编写的配置管理工具 Ansible。它的特点是配置信息采用 YAML 语言描述,但真正在实机上执行配置管理工作的模块可以用各种语言描述。我们将在 2-3-2 节中具体介绍 Ansible 这款和基础设施即代码兼容性非常好的配置管理工具。
采用 Ansible 等配置管理工具,可以得到以下好处。
省时省力:通过自动化进行快速设置
声明式:通过配置信息可以对当前配置对象的具体状态进行明确描述
抽象化:不需要根据细微的环境差异分开描述配置信息,尽量消除代码执行的专业性
收敛性:不管对象的状态如何,最终都会达到期望的状态
幂等性:不管执行多少次,都能得到相同的结果
Ansible 充分发挥了上面这些特点和长处,可以在基础设施中反复使用代码,也可以根据需求的变化反复进行配置变更。
1-1-4 DevOps 的诞生和历史
如 1-1-2 节和 1-1-3 节所述,采用敏捷开发方式会不断地对开发进行改善,在此过程中,运维方面的问题就逐渐暴露出来。2008 年和 2009 年的敏捷大会针对这类问题提出了相应的解决对策,DevOps 诞生的土壤逐渐形成。下面,我们就来看一下 DevOps 诞生的来龙去脉。
DevOps 的萌芽
在 2009 年由 O'Reilly 主办的 Velocity 大会上,来自 Flickr(当时属于 Ludicorp 公司,后被美国 Yahoo! 公司收购)的两名工程师发表了题为“10+ Deploys Per Day: Dev and Ops Cooperation at Flickr”(每天部署 10 次以上:Flickr 公司里 Dev 与 Ops 的合作)的演讲。
该演讲幻灯片的最开始部分,有以下内容。
Dev versus Ops
开发部门 vs 运维部门
该演讲指出,传统组织中的开发部门和运维部门是相互对立的。开发部门出于商业目的,希望对服务进行变更,而运维部门则对变更表示抵触。运维部门的任务是确保系统稳定运行,因此不想对系统做任何变动。更为严重的是,一旦开始出现负面的无限循环,两个部门之间的隔阂就会变得更深(图 1-5)。可以说,该演讲形象地描述了 DevOps 诞生之前的运维问题。
图 1-5 开发部门和运维部门之间负面的无限循环
关于服务中围绕着运维出现的负面循环,幻灯片中有如下内容。
Because the site breaks unexpectedly
对运维部门来说服务会出现预想不到的错误
Becasue no one tells them anything
开发部门并没有告诉运维部门变更的内容
Because They say NO all the time
运维部门总是说“NO”(所以开发部门就未经允许进行变更)
以下不断循环
尽管这个负面循环非常浅显易懂,但是用文字表述后,我们就会更加深刻地认识到这是一个多么奇怪的机制。此外,演讲也提及了运维部门的任务,如下所示。
Ops'job is NOT to keep the site stable and fast
运维部门的任务不是确保系统稳定、快速地运行Ops'job is to enable the business (this is dev's job too)
运维部门的任务是确保商业的有效性(开发部门也是一样)
为了应对外部世界的变化,开发部门需要相应地进行商业性的变更,而运维部门想要确保系统稳定,不想实施改变,也是出于商业目的。回过头来想想,其实两者的根本目的是一致的。那么,是选择畏惧变化并不断逃避,还是按照要求做出改变呢?答案当然是后者,该演讲做了如下阐述。
Lowering risk of change through tools and culture
通过工具和文化来降低变化带来的风险
该演讲也提出了一些应对变化的工具和文化。
用于应对变化的工具
Automated infrastructure(基础设施自动化)
Shared version control(版本管理共享)
One step build and deploy(一步式构建和部署)
Feature flags(通过配置项来管理应用中的某一功能是有效还是无效)
Shared metrics(共享指标数据)
IRC and IM robots(互联网中继聊天、即时通信机器人)
用于应对变化的文化
Respect(尊重)
Trust(信任)
Healthy attitude about failure(正确认识失败)
Avoiding Blame(避免指责)
虽然该演讲没有详细说明具体的实现方法,但每天实现 10 多次部署在当时是一件无法想象的事情,因此该演讲还是给所有开发人员留下了深刻的印象。
DevOps 的诞生
2009 年 10 月 30 日,IT 咨询师德布瓦参加了在比利时召开了 DevOpsDays Ghent 2009 大会,由此出现了 DevOps 这个词汇。之前介绍的几个演讲,特别是“10+ Deploys per Day”,虽然给 IT 行业带来了一定的冲击,但是保持传统开发文化的企业还是抱有消极看法,认为开发和运维的合作不太可能实现,或者即使能实现也没有什么现实意义。实际上,创造 DevOps 这一词汇的德布瓦在博客中也提到过自己差一点就放弃了这一理念,因为最开始的时候很多人都表示否定,认为开发和运维合作简直太荒谬了。
如此说来,企业的 IT 开发部门和运维部门之间的鸿沟还是很深的。不过,不管开发和运维之间的鸿沟有多深,在这个万物都在迅速变化的时代,企业只有在业务上实现各部门齐心协力,才能在竞争中处于领先地位。
1-1-5 小结
本节我们学习了 DevOps 诞生的背景,包括以敏捷开发为代表的持续开发方式的出现,以及持续开发带来的运维方面的问题,而 DevOps 的出现则是开发人员思考如何解决运维问题的结果。从下一节开始,我们将正式开始学习 DevOps 的相关内容。
1-2 认识 DevOps
1-2-1 以迅速满足商业需求为目标
DevOps 要求开发部门和运维部门紧密合作,采用各种方法和文化来缩短改善产品或者服务的时间,快速满足商业需求。通过反复改善来实施新的措施,或者通过迅速调整之前进展不顺的地方,为商业活动提供支撑。 DevOps 不仅用于开发新的服务或者增加新的功能,对于已有服务来说,还可以从开发和运维两个方面快速改善服务,使其发展壮大,这一点是非常重要的。
1-1-4 节提到的 Velocity 这个大会名称就形象地体现出了迅速满足商业需求的思想。这里 Velocity 指的是单位时间内对商业的贡献度,而 DevOps 就是探求如何才能迅速实现商业价值的成果之一。
想要通过开发和运维的紧密合作来改善服务,关键就在于要互相承认对方的专业性,做到互相理解。我们已经介绍了几种支持开发和运维紧密合作的工具,包括基础设施自动化和版本管理共享等,这里我们再来介绍一下这些工具所具备的几种要素。
支持开发和运维紧密合作的工具所具备的要素
抽象化 | 对所有资源进行抽象化,消除不同平台之间的差异,降低专业难度和复杂度 |
---|---|
自动化 | 通过自动化的方式使用抽象化的资源,降低专业难度,减小开发、运维人员的工作压力 |
统一管理 | 通过统一的版本管理系统和沟通工具使信息可视化,构建开发和运维之间紧密的关系 |
持续集成 | 通过统一开发部门和运维部门的开发及构建方法,大幅提升系统改善的速度 |
监控 | 对资源信息进行集中管理和可视化,构建开发和运维的紧密合作关系 |
另外,前面我们也介绍了支持开发和运维紧密合作的文化——尊重、信任、正确认识失败和避免指责,那么形成这些文化的要素又有哪些呢?主要有以下几点。
支持开发和运维紧密合作的文化所具备的要素
目的意识 | 如果开发和运维有相同的目标,即共同创造服务、迅速满足商业需求,则更容易实现紧密合作 |
---|---|
同理心 | 开发和运维团队互相考虑对方的感受,接受对方,建立紧密的关系 |
自主思考 | 开发部门和运维部门不互相依赖,能自主开展工作,以此来不断接近共同目标 |
以上这些要素主要是为了消除专业性和复杂性,减少工作量,同时使信息可视化。这样一来,团队中的任何成员都可以基于相同的信息迅速展开工作,还可以通过自动化和持续集成来大幅缩短进行改善所需要的时间,迅速达成目的。另外,这些要素也是为了使开发和运维拥有超越各自任务的共同目标,互相理解对方,并自主思考和行动,从而实现满足商业需求这一共同目的。
围绕 DevOps 的各种文化的观点和工具由各种各样的要素构成,这些观点和工具都有一个共同的目标,那就是实现开发和运维部门的紧密合作,采用各种各样的方法和文化,缩短改善产品或服务所需要的时间,迅速满足商业需求。
1-2-2 PDCA循环和DevOps
PDCA 循环是现代质量管理之父爱德华兹·戴明(Edwards Deming)提出的一种管理方法,主要用于在企业活动或商业活动中进行持续的生产改善和采取相应的控制措施。这一方法将业务分为 Plan(计划)→ Do(执行)→ Check(检查)→ Act(处理)四个阶段来进行,在执行改善措施之后,又回到 Plan(计划)阶段,如此循环往复(图 1-6)。
图 1-6 PDCA 循环
PDCA 的要领在于执行完一个 PDCA 循环之后,会为下一个循环设定一个更高的目标。那么在 DevOps 中该如何实现这一循环呢?
DevOps 由支撑 DevOps 的各种思想、改善对策和工具组成,缺少哪一部分都不能构成完整的 DevOps。 DevOps 用于平日里的改善和实践,而不是为了一次性完成所有的改善。实施 DevOps 需要以 PDCA 的方式循环进行,持续集成等方法也是用 PDCA 的方式来对服务进行持续改善的。由此, DevOps 和 PDCA 循环就形成了不可分割的关系。
在 DevOps 中,敏捷开发方法是实现 PDCA 循环的方法之一。此外还有一种称为持续集成的方法,通过连续执行可交付物的构建、测试以及结果反馈,可以说实现了以提高可交付物质量为目标的 PDCA 循环。除此之外,开发部门和运维部门之间的沟通、系统环境中所有信息的监控等也都采用了 PDCA 的方法进行持续改善。
1-2-3 抽象化
接下来,我们对支撑开发和运维紧密合作的工具所具备的各个要素进行说明。
抽象化是指对所有资源进行抽象,消除不同平台之间的差异性。基础设施的抽象化包括对操作系统、服务器、存储和网络等的抽象。抽象化可以降低专业性和复杂程度。DevOps 需要开发和运维紧密合作,而通过采用抽象化的方式消除基础设施相关的专业性和复杂性,开发人员就可以完成基础设施的构建和配置等相关工作(图 1-7)。
图 1-7 抽象层的作用
如果进一步对抽象化进行分解,我们就可以得到两层含义:一个是“标准化”,即可以用相同的标准或者规则对一个或多个不同的程序和设备进行调用;另一个是伪装成实际并不存在的事物,我们称为“虚拟化”。
标准化和虚拟化也应用在操作系统、服务器、存储和网络等领域,个别硬件技术正逐步在软件领域中普及。为了能够消除基础设施的专业性,让开发人员也参与到基础设施配置的工作中,支撑 DevOps 的技术无可避免地将迎来标准化和虚拟化。
操作系统的抽象化可以追溯到 1979 年,当时为了满足人们在同一操作系统上同时构建多个应用程序的需求,出现了可以使文件系统隔离的 chroot,它就是操作系统虚拟化的原型。与只能对文件系统进行隔离的 chroot 不同,2000 年在 FreeBSD 操作系统上诞生的 Jail 机制可以隔离一部分系统变更权限(root 权限)。2001 年,在 Jail 机制的基础上,Linux 开始开发 Linux-VServer,并由此产生了一个新的构想——对一台服务器上的 CPU 时间、内存和网络等资源进行隔离,使多个虚拟的 Linux 服务器同时运行。2005 年,Solaris Containers 诞生。2008 年,Linux 操作系统中出现了 LXC(Linux Containers),它通过命名空间技术以独立进程为单位实现资源隔离,由此,容器这一概念作为虚拟化的实现方式逐渐普及。2013 年 dotCloud 公司(现已更名为 Docker 公司)开源了使用 LXC 实现的容器技术 Docker,这项技术一经推出便迅速普及开来。现在的 Docker 采用 Go 语言单独实现,大大提高了在不同平台之间的可移植性,使操作系统的抽象化又前进了一步。在开发和运维紧密合作的 DevOps 中,无论是用软件对基础设施配置进行集中管理,还是基于基础设施即代码对配置进行变更,操作系统的抽象化都是最常用的技术之一。在本书的第 3 章,我们将会对 Docker 进行介绍。
我们再来看一下操作系统层以下的物理服务器的抽象化。基于在计算机上创建虚拟计算机的想法,VMware 公司在 1999 年发布了 VMware 1.0。 VMware 1.0 可以使用软件来模拟所有的物理硬件,在一个操作系统上运行其他操作系统。虚拟化的硬件被称为虚拟机,而作为虚拟机运行载体的操作系统被称为 Hypervisor(图 1-8)。Hypervisor 有两种实现方式:一种是在安装完 Linux 或者 Windows 等操作系统之后,将 Hypervisor 软件安装在操作系统中;另一种是直接在物理硬件上安装 Hypervisor 软件(也称为 Bare Metal Hypervisor 方式)。举例来说,2003 年出现了将 Linux 内核作为 Hypervisor 的 Xen 技术,2006 年出现了 KVM 虚拟化技术,2007 年 KVM 的代码被合并到了 Linux 内核,从此 Linux 发行版开始内置服务器的虚拟化技术。2009 年发布的 VMware vSphere 作为轻量的专用虚拟化操作系统而倍受瞩目,实际上也被大企业采购和使用。现在,为了结合上述操作系统和服务器的抽象化的优点,在虚拟机上运行容器的混合型部署方式正在受到关注。谷歌公司就于 2015 年发布了代号为 Borg 的容器型架构。由于这一架构是在硬件抽象化虚拟机上运行容器,所以不必在意硬件资源的限制,可以通过容器来最大限度地利用硬件。像上面这样,通过服务器的虚拟化,就可以在服务器或者基础设施配置的设计中摆脱硬件资源的物理束缚。如今,需要关注物理硬件的场景已经大幅度减少,只有基础设施工程师才掌握的知识也变得越来越少。
图 1-8 虚拟化方式
那么存储的抽象化又如何呢?可以在一台物理存储设备上创建多个逻辑存储设备,或者可以根据具体的策略决定操作内容以及进行内容分发的存储设备,我们称为 SDS(Software Defined Storage,软件定义存储)。 EMC 和 NetApp 等厂商的很多存储设备专用的操作系统都提供了可以通过软件进行控制的 API(Application Programming Interface,应用编程接口),与软件的亲和性变得越来越高。以前,我们都需要专业的工程师来计算各服务所需要的存储大小,然后确定数据的配置或制订添加磁盘的计划,而开发人员对基础设施工程师所做的工作是一无所知的,但如今根据 SDS 的思想,我们可以用软件来对虚拟化存储进行控制,开发和运维也更容易开展合作了。
VLAN(Virtual Local Area Network,虚拟局域网)是很早以前就为人所知的一个网络抽象化的方法,诞生于 1994 年,是一种把一个物理交换机分离成若干逻辑交换机的技术。尽管在一个系统中设置多个交换机的情况很常见,但这同时也存在一些问题,比如不对交换机进行统一设定网络就不能正常工作,以及对大规模的网络进行灵活变更的需求正在逐渐增加,等等。作为解决这些问题的方法,SDN(Software Defined Network,软件定义网络)被推上了台面。SDN 有几种实现方式,这些实现方式的共同点就是将交换机分成 Control Plane(配置等管理功能)和 Data Plane(数据包转发功能)两个层面。其中 Control Plane 是用软件实现的,开发人员可以低成本地掌握软件知识,从而对网络的配置进行修改。防火墙和负载均衡器这种以前只有专业工程师才能接触到的设备也可以通过软件来控制,因此就算不是基础设施工程师,也可以理解这些设备的配置信息,并进行配置变更。
1-2-4 自动化
自动化是指不需要人为操作,由程序来机械地进行控制的过程。应用程序的构建和测试等操作往往需要重复进行,在这种情况下,就可以对这些操作进行编程,由程序来实施这一连串的操作。
因为抽象化、代码化的基础设施的配置也融入了软件领域,所以是可以实现编程的。那些很早之前就开始应用容器和虚拟化等技术的服务器和操作系统,当然也支持编程。现在存储和网络等硬件一般也都开始提供被称为 REST API 的 API,REST API 可以用 URL 表示资源,通过 HTTP 协议来获取资源的状态或者变更资源的配置。使用 REST API 将资源状态的变更操作按照顺序编写为程序,就不需要像以前那样先编写更新手册,再按照手册内容来进行手工操作了,所有工作都可以机械地自动完成。
抽象化、代码化的操作系统、服务器、存储和网络正在逐渐变得可以根据指定的参数来进行自动化配置,比如想要增加一台服务器时,就可以使用容器等技术自动完成启动操作系统、设置存储和分配网络设备等一连串操作。
自动化也可以通过组合使用各种开源软件来实现,之后我们将介绍的持续集成就是自动化的一个典型例子。
1-2-5 统一管理
问题跟踪系统
沟通工具的统一是在敏捷开发中发展起来的,对 DevOps 中开发和运维的协作意义重大。
信息的统一和可视化是开发和运维紧密合作不可欠缺的要素。
现在也出现了很多旨在不仅使开发部门和运维部门能顺利沟通,还能在运维方面方便对系统进行管理的工具。
比如,问题跟踪系统(Issue Tracking System,ITS)也被称为 ticket 管理工具,当关闭一个记载了问题的 ticket 时,它会立即向聊天工具等沟通工具发送问题关闭的通知,其中比较知名的包括 JIRA、Redmine 和 Trac 等。另外,还出现了 PagerDuty 服务,当发生故障时,PagerDuty 可以将服务器上发生故障的组件的详细信息自动添加到问题跟踪系统中,实施故障(incident)管理并通知相关人员。我们会在第 4 章对问题跟踪系统进行更加详细的说明。
不管是 JIRA、Redmine 还是 Trac,都支持敏捷开发。这些工具既支持敏捷开发中的订单(backlog)管理,也支持缺陷(bug)管理和待办事项(todo)管理,当然也支持敏捷开发中用于记录新添加功能的用户故事(user story)。还有一些工具可以使用 GUI 来支持敏捷开发中应用便签管理任务进度(未开始、进行中和已完成)的看板方法,或者和版本管理系统集成,以了解哪个用户故事是由哪部分开发负责的。还有些工具支持用拖曳的方式对订单列表中的订单进行排序,或者根据在团队内表示故事开发规模的故事点数(story point)来制作图表。特别是 JIRA 强化了仪表盘(dashboard)的制作图表和掌握开发现状的功能,这样在团队开发的管理工作中就不需要再去编写很多资料,可以直接从集中管理团队成员在实际开发中参照的任务和需求的地方获取当前真实的进度。从这一特点来说,在迭代(iteration)或冲刺(sprint)这种短的开发周期内进行的持续开发,与采用电子数据灵活对问题进行管理并设置优先级的问题管理系统的契合度非常高。还有一种被称为 ticket 驱动开发的方法,该方法提倡无论是提交应用程序还是基础设施的代码,所有的任务都需要先创建一个 ticket,然后再开始工作。我们会在第 4 章详细介绍这种开发方法。
设计文档和平日会议记录要不要统一管理呢?各团队都会用文本文件或者 Excel 来逐个记录这些信息,然后保存到需要设有权限的共享文件夹中。如果我们将这些以传统方式保存的设计文档和会议记录放到以 Wiki 为代表的网站上进行统一管理,那么不同的团队就可以在更大的范围内共享信息,也更加便于搜索,同时还可以支持多人同时编辑以及对修改记录进行管理。这种方式的代表工具有 Redmine 的 Wiki 和 Confluence。这些工具和问题追踪系统一样,在设计上支持和外部系统进行集成,可以将更新信息发送到和外部的沟通工具,也可以通过直接共享 URL 来访问指定的信息。
沟通工具
关于沟通工具,现在网络聊天的方式越来越普遍了。开发部门和运维部门使用同一沟通工具,使双方更容易根据共同的信息来展开沟通。不过,如果将 ticket 管理系统和会议记录等信息网络化,那么就可以根据 URL 和相关人员进行信息交换。早前的沟通工具有 IRC,现在比较有代表性的工具是 Skype、Slack 和 ChatWork 等,很多公司都在工作中采用了这些工具。最近比较引人注目的是将机器人(robot,简称为 bot)接入了聊天工具中。在聊天工具中添加机器人账号之后,就可以解决聊天工具难以和系统集成的问题。比如,将故障检测系统和添加了机器人账号的聊天工具进行集成,在发生故障时,机器人就能识别出来是哪个系统发生了故障。机器人也并不仅限于不同系统之间的集成,还可以代替人来完成简单的工作。我们可以通过编程的方式,让机器人对聊天中的某个词语做出反应,并根据发言的内容来进行操作,这样一来,在团队对话的环境下,就可以根据指定的短语来完成重启服务或者添加服务器这样的工作。这样我们不仅可以实时地看到谁进行了什么操作,还能减少操作之前所需要的步骤,进一步提高效率。聊天工具和机器人的集成,不仅可以实现不同系统之间的集成,还能替代人的手工作业,具备多重效果,因此被特别地称为“ChatOps”。在本书的第 4 章和第 5 章,我们会使用 Slack 来对 ChatOps 和系统之间的集成进行说明。
软件配置管理工具
信息的统一管理不仅限于沟通。利用软件配置管理工具(Software Configuration Management,SCM),我们可以将用代码、软件方式实现的基础设施的配置信息保存到软件配置管理工具中。通过对变更内容和变更者进行版本管理,开发和运维人员就可以根据相同的信息来变更配置或者对变更结果进行确认。这样就可以废弃涉及多个文件的操作手册和不再被维护的配置信息。
软件配置管理工具也包含了支持版本管理和发布管理等功能的系统,其中版本管理工具有 Git、Subversion 和 Perforce 等。在本书的第 2 章和第 3 章,我们将会以 Git 和提供 ASP 服务的 GitHub 为主进行讲解。
1-2-6 持续集成
在敏捷开发中,持续集成(Continuous Integration,CI)是指频繁并持续地实施代码构建和静态测试、动态测试等工作。持续集成有很多优点:可以在早期发现代码导致的问题;减少构建和测试相关的工作成本;测试结果的可视化,等等。如果和基础设施即代码思想相结合,就可以让应用程序和基础设施双方的交付物(代码)按照持续集成的构建、测试和发布的流程进行,使开发和运维共享彼此的意见,提早发现潜在问题。另外,如果使用持续集成工具,就可以使构建和测试之类的工作以自动化的方式重复执行,从而加快从服务改善到可以发布的速度。这样一来就会大大减少交付时间,为 DevOps 的目标——迅速提高商业价值做出贡献。
第 5 章我们会以开源的持续集成工具 Jenkins 为例对持续集成进行介绍。另外,还有很多云的持续集成工具服务,比较有名的有 Travis CI 和 CircleCI 等。在搭建云计算基础设施的情况下,使用这些外部服务可以快速构建持续集成环境。
在完成从构建到测试的任务(job)之后,就可以随时准备在生产环境中发布了,这就是持续交付。这一方法也延续了 DevOps 提高商业价值的思想。在实施服务的改善工作后,可以通过持续交付的方法,以最快的速度将改善结果交付给最终用户。为了能实现生产环境的自动部署,我们还需要采用第 4 章中介绍的蓝绿部署方法来确保部署的安全性,这就需要高级一些的系统架构实现。
我们会在 3-2-4 节对持续集成进行详细介绍。
1-2-7 监控
监控能实时并正确地获取系统运行状态,是实施 PDCA 循环中的 Check(检查)环节所必需的。同时,监控也为下一步的 Action(处理)环节的计划提供了重要依据。
监控的最初目的是实时把握资源的使用情况和服务的死活状态,但是为了进行持续改善,监控开始用于获取和分析商业活动所需要的各种数据。指标监控(metric monitoring)系统不仅用于监控,还可以持续获取资源的使用情况并将其可视化。在这一监控系统中,可以通过将服务器的负载情况(CPU 和内存等的使用量)以及网站用户的 Web 页面访问量数值化,来进行定量分析,从而获取可以方便使用的数值,比如通过这些数值来观察新推出的促销活动的效果,或者强化下次促销活动的基础设施,等等。
我们再来看看和商业联系更加紧密的监控的例子。比如,通过监控购买商品的人数在网站访客中的占比情况,即监控网站转换率,来检测改善的效果。用 A/B 测试将改善后的页面和改善前的页面进行对比,确认改善效果,通过观察各自的页面访问数和用户从哪个页面退出,来思考下一步的改善策略。这里就需要用到监控。
另外,监控还用于其他方面,比如通过监控 CPU 或内存的使用率,以及磁盘 I/O 的资源消耗率等指标,来对系统性能进行优化,达到持续改善的目的(图 1-9)。
图 1-9 充分利用监控结果
知名的监控工具有很多,比如 Zabbix、Munin、JP1 和 Hinemos 等。没有监控就不能进行持续改善,所以监控是 DevOps 中非常重要的一个组成部分。
如果想要将日志作为监控指标的信息来源,则可以考虑通过组合不同的中间件来实现。这些中间件分为 3 类:用于日志收集的中间件、从收集到的日志中检索有用信息的中间件,以及用于将收集结果可视化的中间件。现在,用于服务的服务器数量要比以前多很多,增减服务器也没那么麻烦了,在这种情况下,之前沿用下来的日志收集方式就开始跟不上变化,日志量暴增,因此就很难在一个系统中完成日志的收集、检索和加工等操作。正因为如此,最近采用最合适的中间件组合来完成日志的相关处理的方式成为了主流。
比如 Elasticsearch(日志的全文检索)、Logstas(日志的收集)和 Kibana(日志的可视化)的组合,这个组合简称为 ELK 栈,现已被广泛使用,并且正逐渐成为主流。5-2 节中我们会对 ELK 组合进行详细介绍。
另外,最近比较流行的监控可视化工具有 Grafana 等,用于日志收集的有 Fluentd。
1-2-8 目的意识、同理心和自主思考
接下来,我们来看一下支撑开发和运维紧密合作的文化所具备的要素。
在 DevOps 中,开发和运维需要紧密合作,因此拥有共同的目的意识就显得格外重要。一直以来,开发都以增加新功能为目的,而运维则以服务的不间断运行为目的。举个例子,开发为服务添加了新的功能,并想发布上线,但是在需要确保已有系统稳定运行的运维方看来,新功能可能会导致系统不稳定,追加新功能对双方来说都是比较大的负担。但如果开发和运维将共同目标定为通过服务运营来快速满足商业需求,那么开发部门添加新的功能,然后和运维部门合作将新功能发布上线,完成服务的持续运营,这对开发和运维双方来说就成了自然而然的事情,开发和运维都会深入思考如何才能实现这一共同目标。
开发和运维即使朝着共同的目标运营服务,也不可以在不了解彼此工作的前提下随意开发新功能,或者随意对系统进行维护。开发和运维需要互相体谅对方团队的心情,需要在很多方面达成共识,比如什么样的变化会给双方带来什么样的负担,怎么做才算是对双方都有利,怎么做才能更好地改善服务,等等。
在具备了同理心之后,开发部门和运维部门就不会互相等待对方为自己做些什么了。运维部门的人不会等待开发人员的要求,开发部门的人也不会等待运维人员的意见,双方都会通过自主行动来不断接近共同的目标。
1-2-9 小结
所谓 DevOps,就是开发部门和运维部门紧密合作,采用各种各样的方法和文化,缩短改善产品或服务所需要的时间,迅速满足商业需求。工具和文化是支撑 DevOps 的两个方面。在工具方面,我们了解到采用满足抽象化、自动化、统一管理、持续集成和监控等要求的工具,可以消除专业性或者使信息可视化,从而促进开发和运维紧密合作。在文化方面,我们了解到共同的目的意识、同理心和自主思考等文化的形成,将有助于实现 DevOps 的目的。
DevOps 需要通过 PDCA 循环来进行持续改善。我们可以通过组合使用网络聊天工具、问题跟踪系统、版本管理工具、持续集成工具、基础设施自动测试工具和监控工具,来实现 PDCA 循环。
1-3 组织和 DevOps
1-3-1 DevOps能解决组织、团队中的什么问题
前面我们讨论了 DevOps 的意义,也从工具和文化两个方面讨论了构成 DevOps 的基本要素,那么 DevOps 具体能为我们解决什么问题呢?下面我们就来讨论一下 DevOps 能带来什么样的效果。
消除对个人的依赖
如果一项工作特别依赖某一个人,相关技术只有那个人懂,或者那个人不在的话工作就难以进行,就会阻碍 DevOps 开发和运维的紧密合作。从运维的角度来看,对个人的依赖更加致命。如果有些配置方法和部署方法只有某一个人知道,或者更新了只有某一个人了解的服务,在这种情况下,团队信息共享会变得非常脆弱,甚至会给服务的持续运营带来威胁。
这种信息无法共享的问题,从前就只有一种方法可以解决,那就是将服务器、存储和网络等基础设施资源的配置步骤总结成操作手册,然后将所有信息都记录进去。但是现在这些问题有了其他的解决方式——通过配置管理工具使操作步骤可视化。由于这一方法是通过代码实现的,所以也可以描述带有条件判断的工程,对于以前那些必须由人来判断并进行作业的工程,现在不管拥有什么技术背景的人,都可以重复执行了。
本书中介绍的配置管理工具 Ansible 的首席开发者德哈恩就配置管理工具在消除对个人依赖方面所取得的成效做了如下论述。
这是一个能让这个会议室中的所有人都轻易进行滚动更新的工具。
滚动更新(rolling update)是一种更新升级方式,是指在由多个组件构成的系统中,每次只更新其中的一部分组件,从而在不停止系统的前提下实现整个系统的更新。一般来说,进行滚动更新需要较高的知识水平,专业性比较强,因此很难在团队中进行知识共享,要实现团队全员都能完成这样的工作也比较困难。但是,配置管理工具的出现解决了这个难题,使团队内的任何人都可以完成这样高难度的工作,也由此消除了对个人的依赖。
降低团队之间的损耗
在你们公司,团队是按照专家组的形式建立起来的吗?
如果不是,那么请试着想象一下,开发部门在发出构建服务器的请求时,会涉及多少个团队呢?如果涉及服务器组、网络组和存储组等多个团队的话,那么毋庸置疑,这个公司在服务改善的过程中存在着损耗(overhead)过高的问题。如果一个公司由多个专业团队构成,那么团队之间的交流成本就会远高于一个团队的情况,比如需要编写各种文档使团队之间可以进行信息交换,需要各种各样的审批,各团队在实施计划时都会预留一部分的缓冲时间,等等。
开发团队和运维团队的紧密合作,就是要消除上面所说的损耗,形成一种大家一起讨论项目,互相检查,在了解对方工作状况的基础上不断对服务进行改善的关系。支撑开发和运维紧密合作的工具有很多,比如使用版本管理工具或基础设施配置管理工具,可以对开发团队和运维团队所需要的配置信息进行统一管理,实现信息共享,消除专业壁垒,从而有利于人才的流动,从结果来说也有助于组织结构的精简。
另外,如果采用了聊天工具或通用的问题跟踪系统,那么开发部门和运维部门各自的工作、配置管理信息以及系统状态等所有信息都可以被统一管理,不管是谁都可以获得并理解这些信息,从而可以减少团队间沟通交流的成本,构建出能迅速实施改善对策的机制。
提高质量
假设有些信息只有开发团队或运维团队才有,而两个团队之间完全没有共享任何信息,那么在发布新增加的功能时需要最新版本的中间件的情况下,就可能会出现一些问题,比如新功能发布之后不能正常工作等。
我们再来看一个例子。根据市场部门的要求,开发团队在基础设施运维团队不知情的情况下上线了一个促销活动的功能,但事实上这个新功能有 bug,会消耗与访问数不匹配的很多服务器资源,结果服务器的负载异常暴涨,服务陷入了瘫痪的状态。由于运维团队对这次修改并不知情,在访问数没有明显变化的情况下,面对服务器负载突然升高的问题,运维团队也找不出原因。即使从访问日志中找到了出问题的 URL,但由于促销活动功能已经嵌在了网站首页里,所以无法找出问题的根源。最后,运维团队在走过多条弯路之后,终于查明了问题的根本原因,并联系了开发团队,之后开发团队对 bug 进行了修正。从问题的发生到解决,中间花费了近半天的时间,而这期间服务处于完全不可用的状态。那么如何才能解决类似问题呢?如果开发团队和运维团队能共享发布的时机和内容,掌握发布可能影响的范围,一起对服务进行监控,那么就可以在更早的阶段找到问题出现的原因,及早修复 bug。
不光是故障,性能也是一样。如果开发团队只考虑应用程序的开发,运维团队只考虑基础设施的运维,双方分别以这种方式来进行开发和基础设施构建的话,就会出现双方预想的连接池数不匹配,性能发挥不出来的情况。开发和运维一起对服务进行设计是非常重要的,有很多方面需要一起考虑,比如估算访问量、对中间件或者网络进行相应的配置、确定服务器数量,以及对数据库的使用方法进行审查(review)等。如果开发团队只是在需求管理申请表上记录这些工作然后交给运维团队,让运维团队来配置的话,那么运维团队就会在对应用程序的重点需求一无所知的情况下,按照开发团队自己衡量的值进行设置,最终导致失败。在互相了解对方的基础上,在各自擅长的领域中工作是非常重要的。
你是否在认真考虑运维这件事?发生故障时,调查的出发点就是日志。但是,应用程序开发人员可能只会将自己需要的调试信息以调试级别输出到日志文件,而另一方面,运维团队则会计算日志容量,将日志输出级别调整为警告级别。这样一来,在进行故障分析时,日志文件中可能就没有输出任何故障时系统发生的事件,也就导致无法进行故障分析。
在 Web 服务、手机应用程序的开发和游戏开发等各种开发中,组建适合 DevOps 的体制,可以使运维团队和开发团队共享信息,在设计时互相审查,深入了解对方的工作内容,从而不断提高交付成果物的质量。
1-3-2 康威定律
本章我们介绍了什么是 DevOps,以及使用 DevOps 相关的工具能为组织解决什么问题等内容。但是,通过改变开发思想,或者通过引入工具来改变服务系统的配置和结构,就能使组织形式发生变化吗?这个疑问其实很早以前就出现了。1967 年,计算机科学家同时也是一名程序员的梅尔文·康威(Melvin Conway)提出了组织和系统架构的关系法则,也就是现在我们所说的康威定律。
康威定律的大意为:设计系统的组织,其产生的设计等同于组织的沟通结构。
按照这个定律来看,如果一个组织内有开发团队、服务器团队、网络团队和存储团队等多个团队,那么系统也会遵循高度专业化的规则,形成各个功能相互分离的状态。
就像前面所说的那样,专业性越强的团队,损耗就会越大。对于产生这种损耗的组织结构来说,是先进行系统的设计,还是先进行组织结构的设计,在这一点上还存在一定的争议,但是通过引入 DevOps 这一开发和运维紧密合作的观念,以及使用支撑 DevOps 的各种工具,使系统架构和组织结构同时发生变化,将为组织带来不少积极的影响。
1-3-3 小结
要想实施 DevOps,不仅需要工具,还需要文化方面的改变。通过前面的学习,我们了解到实践 DevOps 可以消除对个人的依赖、减少团队之间的损耗、提高品质等。企业在尝试践行 DevOps 的同时,通过对工具和开发方法做出改变,可以更接近 DevOps 提高商业价值的思想。关于在实际工作中如何在组织中引入 DevOps,我们会在第 6 章进行介绍,各位读者也可以结合第 6 章一起阅读。
现在我们来回顾一下本章内容。随着“以敏捷开发为代表的持续开发方式的出现”,出现了“持续开发带来的运维问题”,这就是 DevOps 诞生的背景。为了解决这些问题,出现了基础设施配置管理工具,以及基于基础设施即代码思想的利用软件对基础设施进行管理的工具。
在这样的背景之下,DevOps 诞生了,通过开发和运维的紧密合作来提高商业价值这一新的思想开始普及。各类工具通过抽象化、虚拟化、自动化和监控支撑着 DevOps 通过持续进行 PDCA 循环来提高商业价值。将这些工具和沟通工具结合使用,可以构建出开发和运维更加紧密的关系。
DevOps 不仅需要上面提到的那些工具,还需要在组织层面做出很多努力,比如在文化方面有所改变、消除对个人的依赖、减少沟通成本、创建提高质量的体制等。正如康威定律所说的那样,要着眼于系统架构和组织结构之间的关系,通过这一点我们就能明白需要在系统和组织这两方面同时做出努力。
至此我们学习了 DevOps 的背景、思想、文化和工具,想必各位读者对于什么是 DevOps 这一问题已经有了自己的答案,不过对于如何在自己的组织或团队中实践 DevOps 可能还抱有疑问。在第 2 章,我们将学习从个人环境开始实践 DevOps 的方法。