DevOps 最佳实践: 第 1 部分. 通过 DevOps 开发可靠的软件



  • 简介

    软件系统已经影响我们生活的方方面面。从我们用于在线购物的基于 web 的门户网站到运行我们公司业务的大型企业系统,我们期待计算机系统来提供非常广泛的功能,来适应高峰使用量需求的规模,以及来了解我们的个人喜好以便它们能预测我们方方面面的需求。当我们与一个被很好编写的软件系统打交道时,我们将会逐渐习惯它的能力和灵活性,并且当发现其他软件系统并不能满足或超过相同的预期时,我们会感到惊讶。

    灾难性结果带来的计算机故障

    由于计算机在我们许多日常任务中担任了相关的角色,当我们所依赖的系统并不能百分之百的可靠时我们尤其会受其受影响。这篇文章将关注于可以适用于构建可靠软件系统的最佳实践,以及如何避免发生类似最近影响许多其他企业的重大突发事故。

    来自 Knight Capital Group 的一个例子

    在 2012 年 8 月,Knight Capital Group, Inc 因为一次灾难性的计算机故障而受到重创,该计算机系统被证实对于该公司作为一个独立组织存在而言至关重要。已发布的报告认为由于一次对 New York Stock Exchange (NYSE) Euronext 系统的相关软件升级的失败尝试,致使该公司无意中购买了被报道的七十亿美元他们并不想要的股票。
    Knight 不得不立即清算股票,这一行动导致了超过四亿四千万美元的损失。一些行业专家还声称,由于对该公司的能力失去信心,许多客户撤回了他们业务,从而进一步扩大了损失。Knight Capital 随后被另一家公司收购。公司的停业首要是因为该公司在管理软件升级方面缺乏恰当的流程。这一倍受广泛关注和戏剧性的事故仅仅是最近众多影响银行系统、交易公司、证券交易所,以及诸如纽约城市 911 应急系统等政府系统的软件灾难之一。

    股票市场的类似实例

    一组其他近期发生的软件灾难也有类似的显著后果。在 2013 年五月,Chicago Board Options Exchange (CBOE) 交易系统由于一次软件故障导致业务关闭,该故障被报道是与被要求延长交易日的相关系统配置的变更有关。这一事故致使 CBOE 系统被质疑是否能作为 S&P 500 指数及股票波动性 VIX 指数的唯一数据来源。这一事故的发生使得其他公司得以挑战 CBOE 管理这些交易指数的独占权利,并帮助演示了交易所并不适合继续作为这些指数数据来源的单一选项。
    一些业界专家还质疑由于大型计算机系统越来越复杂,以至于许多公司或组织根本不可能确保这些企业广泛使用系统的可靠性,以及确保不发生服务中断。这篇文章回答了此问题。我们确切知道如何开发完全可靠的大型任务关键系统。事实上,许多业界标准和框架建立了与 DevOps 相一致的行业最佳实践,可以帮助确保计算机系统高度可靠性。

    行业标准及框架

    IEEE、ISO 及许多其他被广泛认可的标准组织提供了关于如何开发可靠和安全系统的详细指南。使用这些行业最佳实践,您可以演示您拥有高效的 IT 控制来确保您的系统是可靠的,并且满足大多数联邦法规的要求。在这一系列中,我们将会基于相应的行业标准及框架的背景来探讨有用的 DevOps 最佳实践实现,并以实用和切实的方式来解释如何来实现必须的自动化流程,从而很自然地将最佳实践和原则与 DevOps 关联起来。
    例如,Information Technology Infrastructure Library (ITIL) 就是一组通过关注于将 IT 服务与业务需求取得一致,来支持 IT 服务管理(IT service management,ITSM)的最佳实践。ITIL V3,一个最流行的框架之一,提供了关于如何确保 IT 服务能在服务无中断风险的情况下被维护及升级的指南。ITIL 描述了配置管理系统(Configuration Management System,CMS)被用于追踪所有配置项(configuration item,CI)的变更。它同时还描述了配置管理数据库(Configuration Management Database,CMDB)如何通过提供关于运行系统上 CI 的状态的最新和准确的信息来支持 CMS。

    配置管理数据库需求支持

    CMDB 是 CMS 的一个核心组件,通过自动化发现过程提供最新和准确的信息。DevOps 通过建立成熟的构建过程来帮助使 CMDB 保持最新。在实践中,只有使用被嵌入和不可改变的版本 ID 时,应用代码才可能被发现和准确识别。因此,您的构建工程工作必须包括一个流程来在配置项中嵌入版本 ID,并嵌入版本 ID 到容器的资源配置文件中,例如代码被打包的 jar、war 或 ear 文件的资源配置文件中。
    DevOps 通过提供构建、发布及部署自动化来确保 CMDB 能提供关于 CMS 应用代码的准确信息,从而满足了这一要求。
    Knight Capital Group 的事故可以通过使用一个可以发现他们服务器上代码版本,并且可以针对 CMS 中期待版本进行验证的 CMDB 来避免。不过这些技术只有在开发和运维组织协同工作,以尽早在软件开发生命周期的早期构建和自动化这些环节时,才有运用的可能。

    通过发布工程实现 DevOps 构建质量

    发布工程提供了最有效的方式来构建和打包代码,使其可以在目标服务器上被验证。这一方式避免了最糟糕的故障,并业已成为当今金融服务行业的惯例。成功的实现依赖于开发和运维团队有效的协作:

    • 基于版本识别机制进行构建
    • 创建发现工具和流程,并由运维团队运行,使得得以:
      • 验证正确的代码被部署了
      • 验证没有非授权的变更由于恶意目的或人为错误得以发生

    每个团队都有特定的目的:

    • 运维团队关注:维护可靠的服务。
    • 开发团队关注:开发新功能。
    • DevOps 关注:确保在运维团队和开发团队之间的协作来使得这些自动化过程准备到位,从而防止由于片断代码的错误版本被部署到生产服务器而导致的软件灾难。

    使用一个 DevOps 方式来构建、打包和部署应用程序,来使得组织可以构建高质量的应用,这是最早由质量权威专家 W. Edwards Deming 所倡导的。如果我们已经知道该如何避免在 Knight Capital 发生的此类事件,为何更多的组织不能拥抱这些行业最佳实践呢?

    DevOps 确实省钱

    失败于建立所需要的 IT 控制的最常见原因就是这项工作花费巨大而且耗时。在许多组织中,挑战性的最后期限和交付新功能的压力导致了偷工减料,一个会最终直接导致软件缺陷的决定就是弥补缺失的需求,这往往会为代码基带来新的错误。注重质量确实带来开销,但交付包含有缺陷代码的代价也同样巨大,并且可以带来金融方面的损失,而且更加严重的,会使组织自身丧失自信力。
    DevOps 从一开始就将首要的注意力放在构建质量。这一关注对于交付软件用于支持商业业务的公司来说尤其关键。

    DevOps 减小了软件开发复杂性带来的影响

    另外一个导致糟糕质量的常见理由就是软件变得越来越复杂。
    软件系统确实提供了越来越复杂的功能。大多数大型软件系统无法被任何一个独立的技术专业人员所完全理解。我们都通过软件框架来工作,使我们可以更快地编写代码和交付更多的功能,但这些优势通常也带来使用组件所带来的开销,因为我们无法完全理解这些(由其他人编写)组件。
    然而,如果能开发自动化过程来进行构建、打包和部署应用程序,管理软件解决方案的每一件片断是可能的。这些过程可以创建用来验证运行时依赖性的接口,以确保环境被正确配置以支持所有必须的组件,包括构建和发布组件自身。通过为每一个组件开发自动化的构建、打包和部署过程,系统的整体复杂性可以被驯服并且可以被有效管理。

    DevOps 管理构建、打包和部署依赖

    实现自动化的构建、打包和部署过程是任何 DevOps 工作的核心关注点。许多软件开发人员完全埋头在他们的集成开发环境(Integrated Development Environments,IDE)中进行工作,例如 Eclipse 及 Visual Studio。
    问题是他们并不能真切地知道和理解他们所有的构建依赖。当这些开发人员转移到他们下一个项目,或者由于一次由于笔记本电脑崩溃而导致的意外,组织也许发现他们确实缺失了理解构建、打包和部署他们代码所必须的知识。仅仅特定了解他们自己的构建和运行时依赖,这对于开发人员来说非常常见。这就是构建工程师经常被行业法规规定为一个独立职责的现实原因,因为他通过捕获所需的知识并自动化构建和部署流水线,可以增强可靠性。

    DevOps 改善了可靠性和部署流水线

    脚本和自动化构建确保了编译和运行时依赖的核心知识可以被发现和被文档化。开发人员可能由于时间太久遗忘了被配置在 IDE 里的所有环境设定,但幸运的是,编写在 Ant、Maven 或 Make 中的构建脚本提供了关于构建、打包及部署代码核心配置的一个清晰和准确的视图。
    由于可以通过一个连贯的方式进行可靠地构建、打包和部署,这对于确保系统可以在不被意外和严重后果影响的前提下被支持和修改。除了可以可靠地构建代码之外,我们还需要确保我们可以验证正确的代码被部署了,以及更加重要的,任何来自恶意目的的非授权变更或人为错误都能立即被识别出来。

    正确的部署依赖于加密技术和代码基线的使用

    在应用代码被编译和打包之后,对于部署工程师来说最重要的就是验证代码是否被正确部署。但问题也会由于许多原因在此处被引入。有时候,这些代码并未被部署到预定的目标机器上,或因为权限因素又或是低级人为错误。
    虽然我们测试所编写的应用代码,并验证它满足了最初始的需求和设计,但许多部署工程师忘记了验证被构建的代码是否确实被成功复制到目标机器上。处理这一问题正确的方式是通过使用诸如加密技术来验证被构建的代码确实被部署到目标机器上。加密技术还可以用于识别和侦测任何未授权的变更,而此类变更最有可能导致系统停机。

    向上游转移构建、打包和部署功能

    这篇文章所描述的技术要求付出一些工作努力和技术性专门知识。许多公司尝试在部署完代码到生产环境中后来实现这些控制,然而这一时间点在流程上已经太晚了。
    DevOps 在应用开发生命周期的早期就将合适的关注力放在实现自动化部署流水线上。这一决定使所写的代码可以被验证,从流程的最初始就将质量建立到流程当中,这是高效 DevOps 的一条根本性的原则。
    组织通常都会在软件开发生命周期的最开始就拥有负责自动化应用构建、打包和部署的构建工程团队。代码,例如本文前面所提及的嵌入不可改变的版本 ID 的代码,应当被写入到自动化工作的设施当中。不幸的是,一些组织错误地放任开发人员从软件开发生命周期的最开始就自行处理他们的应用构建。这是一个错误的做法。如果构建团队从开发测试环境的最开始就进行自动化构建、打包和部署代码方面的工作,代码开发人员则可以尽情享受这些实践带来的好处并更快地编写代码。质量保证和测试组也同样可以从应用构建、打包和部署任务的自动化中得益,因为这些自动化技术也确保了代码是经过测试的,与已被部署的代码是相一致的。此外,自动化部署任务还帮助确保应用程序得以工作,而且可以不被潜在影响系统可靠性的缺陷所影响。DevOps 将供应任务(provisioning task)考虑为代码工作的一部分。
    DevOps 正确地识别基础架构的供给任务(以及在基于云环境的服务器的供给)作为代码可开发工作的任务之一。此外,以安全和可靠的方式配置服务器的任务也是一个代码工作。
    在一个类似的主题里,认为管理开发流水线任务是一个软件和系统开发工作,它应当包括属于自己的生命周期。DevOps 将正确的关注点放在部署自动化上,并作为其自身的核心开发工作。这一方式要求 DevOps 工程师需自行验证 DevOps 过程。

    DevOps 自身验证 DevOps 过程

    无论是供给(provisioning)一台服务器或部署一个应用程序,DevOps 工作应当被作为一个开发生命周期来看待,并以创建自动化的开发流水线作为目标。许多 DevOps 实践者使用敏捷实践来贴近这一任务,以迭代的方式改善部署过程自身。
    事实上,许多早期的 DevOps 爱好者参考了这些实践作为敏捷系统管理的实践,这一阶段既具能说明问题而且也是恰当的,虽然我们当中的许多人同样使用这些方法学来支持瀑布式开发工作。无论您的组织正在使用敏捷、瀑布式,或混合敏捷与瀑布式方式,软件方法论是根本性的。

    实践的软件方法学

    应用生命周期管理(Application Lifecycle Management,ALM)定义了任务和过程,被成功实现任何软件或系统开发工作的所有参与利益相关者所采用。被很好定义的 ALM,使用工作流工具进行自动化,帮助提供必要的核心声明,以便每一个利益相关者都能理解他们所负责的任务,并为便利沟通提供透明性。

    结论

    开发人员关注于创建新的功能。运维团队关注于提供可靠的系统。DevOps 工程师提供了原则、实践和实操过程来开发软件,这些都已在软件和系统以及交付生命周期中被验证。这些实践与在许多行业标准和框架中被广泛关注的最佳实践相一致。创建可靠系统要求这些实践和原则作为 DevOps 革新的一部分而逐渐新兴起来。

    原文链接: http://www.ibm.com/developerworks/cn/rational/d-develop-reliable-software-devops/index.html


登录后回复
 

与 青云QingCloud 社区 的连接断开,我们正在尝试重连,请耐心等待