您还未登录! 登录 | 注册 | 帮助  

您的位置: 首页 > 软件开发专栏 > 系统/运维 > 正文

全面解读DevOps相关基础概念与实践

发表于:2020-05-21 作者:陈峻编译 来源:51cto

在本文中,我们将主要讨论:什么是DevOps?它与敏捷有何不同?目前有哪些流行的DevOps工具?Docker、Kubernetes和Azure DevOps在DevOps中能起到何种作用?DevOps的重要指标与优秀实践。

什么是DevOps?

与许多围绕着软件开发的流行词汇一样,DevOps并没有公认的定义。有人可以用三言两语简单地对它进行定义,也有人需要通过一整本书进行完整复杂的诠释。如下是两种比较公认的定义:

  • AWS:DevOps是各种文化理念、实践和工具的组合,可以提高企业的适应力、并能够快速地交付出各种应用和服务。
  • L Leite的《DevOps概念和挑战调查》:DevOps是组织内部的跨职能协作,它旨在确保新的软件版本能够在确保正确性和可靠性的前提下,实现自动化的持续交付。

在了解了DevOps定义之后,我们来看看软件开发是如何演变成为DevOps的。

瀑布(Waterfall)模型

在软件开发领域的前几十年中,大家主要以瀑布模型为中心。就像建造一个桥梁那样,瀑布模型通过多个阶段来构建软件。这些阶段可能持续几周到几个月不等。

如上图所示,大多数瀑布项目都需要几个月的时间,才能让应用程序的有效版本初见端倪。那么在瀑布模型发展的几十年间,我们总结出了构建优秀软件的如下关键要素:

  • 沟通。
  • 反馈。
  • 自动化。

首先,由于软件开发是一项涉及多种技能的跨职能任务,因此人与人之间的沟通对于软件项目的成功是至关重要的。

虽然我们可以通过需求、设计、体系架构、以及与部署相关的上千页文档来进行书面交流。但是,在实际项目中,我们也需要通过内部沟通,来给团队协作赋能,并通过多种技能的开展,来实现跨职能团队(如上图所示)的紧密协作。

其次,快速、尽早的获得反馈,比起需要等待几个月才能得到最终结果要重要得多。据此,我们可以及时获悉应用是否满足了构建业务的期望,以及将来部署到生产环境中,是否会出现问题。基于快速、及时的反馈,我们就能够越早、越容易地解决问题。

再次,开发与部署人员都认识到,手动执行运营的速度不但慢而且容易出错。因此在软件开发和维护所涉及的各项活动中,我们需要引入如下图所示的自动化方式。

敏捷(Agile)的产生

基于上述三项需求,业界慢慢出现了敏捷的相关概念。它是指通过加强团队之间的沟通,及时获取反馈,并引入自动化来予以实施。

通过敏捷的方式,我们可以将业务团队和开发团队整合到一起,致力于通过小型迭代(通常称为Sprints)来构建出色的软件。

过去我们在开发的每个阶段上,都要花费几周甚至几个月的时间,而敏捷更关注几天、甚至一天中的整个开发周期内的处理过程。我们称之为用户故事(user stories)的各项小需求,如下图所示。

敏捷如何促进团队之间的沟通?

如上文所示,敏捷使得业务和开发团队聚集在一起。而业务代表(通常称为产品所有者)会经常出现在团队中,以确保团队能够清楚地了解业务目标。也就是说,当开发团队对于需求的理解有误时,产品所有者将协助纠正他们,以保证整个团队交付出的最终产品满足企业业务的目标。

此外,敏捷团队的跨职能技能主要体现在:编码技能(包括:前端、API和数据库)、测试技能和业务技能上。通过人员之间的沟通,以及软件设计、编码、测试和打包等环节的协作,出色的软件才能被构建出来。

敏捷与自动化

我们常常会碰到一些带有原生缺陷的软件产品,例如:产品本身带有技术上的缺陷,而无法正常运行;或是存在着代码质量的问题,且难以维护与修复。通常,敏捷团队希望通过专注于自动化来尽早发现和解决此类问题。

通过自动化测试,敏捷团队可以编写出测试带有各种方法和类的单元测试用例;能够编写出测试模块和应用的集成测试用例。而通过使用诸如SONAR之类的工具,敏捷团队还可以评估应用程序的代码质量。

如上图所示,提交版本的控制,各类测试,以及代码质量的检查,都可以通过持续集成管道来自动化执行。在敏捷的早期,最受欢迎的CI/CD工具便是Jenkins。

敏捷如何促进即时的反馈?

正如前文所述,有了敏捷的方式,企业无需再等待数月才能看到最终产品,而是在每次sprint结束时,目标产品的版本都能够被演示给所有利益相关者,包括软件架构师和业务团队。在对下一次sprint的用户故事进行优先级排序后,所有反馈都能够被得到处置。这样构建和交付出来的最终产品才是企业真正想要的东西。

由敏捷方式带来的持续集成为即时反馈创造了有利的条件。假设我们将一段代码提交到了版本控制系统中,那么在30分钟内,如果该代码会导致单元测试的失败、或集成测试的失败,我们就能得到及时的反馈;而如果该代码不符合代码质量标准、或者在单元测试中没有足够的代码覆盖率,那么我们同样也能得到相应的反馈。

微服务架构的演变

随着开发模式的演变,微服务的架构开始出现了。开发团队趋向于构建许多小型的API,而不是那些大型的单体应用程序。与此同时,运营也变得更加重要。如下图所示,我们每周都可能需要进行进行数百个小型微服务的发布,而不是积累到一个月后发布一个单体应用。因此,调试微服务中的问题,并了解微服务中发生情况也是非常重要的。

DevOps的出现

在软件开发与产品交付的过程中,整个团队时常会碰到如下两个有关开发与运营团队之间的沟通问题:

  • 我们如何能够使得部署更加容易?
  • 我们如何能够让运营团队的工作相对于开发团队更具有可视性?

这时,DevOps就应运而生了。在许多成熟的企业中,开发和运营团队往往是一个团队。他们共享着相同的目标,也试图了解另一个团队所面临的各种挑战。因此,在DevOps的早期阶段,运营团队的代表可以直接参与Sprint的standups和retrospectives。

除了敏捷的核心领域(如:持续集成和测试自动化),DevOps团队还应当致力于协助多个运营团队活动的自动化,例如:配置服务器,在服务器上配置软件,部署应用程序,以及监控生产环境等。在此,我们会时常看到各种关键术语,它们包括:持续部署、持续交付和基础架构即代码。

持续部署就是要在测试环境上持续部署新版本的软件。在Google、Facebook这样的成熟组织中,为了将软件持续地部署到生产环境中,它们每天都可能有数百次生产环境的部署。

而基础架构即代码就是将基础架构视为应用程序的代码。您可以通过配置,以自动化的方式创建诸如:服务器、负载平衡器和数据库等基础架构。此外,通过对基础架构进行版本控制,我们还可以跟踪基础架构在一段时间内的变化。

DevOps如何促进即时反馈?

前面我们已经提到了运营和开发团队通过沟通与协作,共同应对如下问题:

  • 任何运营问题都会得到开发人员的及时关注。
  • 上线软件时遇到的任何挑战都会引起运营团队的早期关注。

那么通过采用DevOps的方式,运营和开发团队就能够通过持续集成、持续交付和基础架构作为代码等领域,实现如下两方面的及时反馈:

  • 凭借着持续交付,如果代码或配置的更改,可能破坏测试或暂存环境的话,那么我们会在几个小时之内获悉。
  • 凭借着“基础架构即代码”,开发人员可以自行配置环境,部署代码并自行查找问题,而无需运营团队的任何帮助。

其实,大家可能也注意到了:敏捷和DevOps在目标上有着相似之处,都包括:

  • 促进业务、开发和运营团队之间的沟通和反馈。
  • 通过自动化来缓解痛点。

实际上,在Netflix、Amazon和Google等创新型企业中,他们日复一日地发生着这样的DevOps故事:

  • 团队中的开发人员登录GitHub存储库,快速签出某个项目。
  • 快速地创建本地环境,并对代码进行修改。
  • 对修改部分进行自动化单元测试,并提交代码。
  • 以电子邮件形式告知已将该代码部署到了质量检查模块。
  • 在完成了自动化集成测试之后,质量检查小组按需进行手动测试,并批准代码的更新请求。
  • 新的代码在几分钟之内,被导入生产环境。

从字面上说,DevOps=开发+运营,它是开发的工具、框架、以及自动化的结合。DevOps主要专注于人员、流程和产品。其中“人员”是有关文化和树立良好的思维模式。也就是说,它是一种促进开放式沟通,重视快速反馈,以及聚焦软件质量的文化。

虽然前文的敏捷方式已经能够弥合业务团队与开发团队之间的沟通鸿沟。开发团队在了解业务优先级的基础上,与业务团队合作,提供有价值的“故事”。但是,开发团队和运营团队并不能保持一致,他们有着各自不同的目标:

  • 开发团队的目标是将尽可能多的新功能投入生产环境。
  • 运营团队的目标是保持生产环境尽可能地稳定。

可见,如果开发人员和运营人员无法保持一致,软件产品就很难投入生产环境。而DevOps恰好旨在使两个团队实现共同认同的目标。它能够使得开发团队与运营团队开展合作,以了解和解决运营的相关难题。而运营团队则可以通过Scrum(译者注:一种迭代式增量软件开发过程,通常用于敏捷软件的开发),来了解开发时所涉及的各项功能。也就是说,在那些成熟的DevOps企业中,开发与运营都属于同一Scrum团队,他们彼此分担对方的部分责任。但是,如果您的企业处在DevOps的早期阶段,那么如何才能使得开发与运营拥有共同的目标,并能“欢乐地玩耍”呢?通常,您可以采用如下方面的尝试:

  • 您可以在一开始便让开发团队去分担运营团队的部分职责。例如,让开发团队在部署到生产环境后的第一周内负责新版本的发布工作。这将有助于开发团队了解在发布新版本时运营团队所面临的挑战,进而共同寻找解决方案。
  • 您也可以让运营团队的代表参与到Scrum的standups和retrospectives等活动中。

DevOps用例

上图展示了Kubernetes和Docker,两个简单的DevOps工作流程,即:

  • 使用Terraform和Azure DevOps,来配置Kubernetes集群的基础架构即代码。
  • 使用Azure DevOps的持续部署微服务,构建Docker镜像并部署到Kubernetes群集中。

让我们首先来讨论:使用Azure DevOps和Jenkins进行的DevOps持续部署。当开发人员将代码提交到版本控制系统中之后,会立即执行如下步骤:

  • 单元测试。
  • 代码质量检查。
  • 集成测试。
  • 通过Maven、Gradle、以及Docker等工具,打包应用程序,以构建出应用程序可部署的版本。
  • 应用程序的部署,即启用新的应用程序,或是应用程序的新版本。
  • 给测试团队发送测试应用程序的电子邮件。
  • 一旦获得测试团队的批准,该应用程序将立即被部署到下一个环境中(Next Environment)。

这就是持续部署。如果您是部署到生产环境的话,则称为持续交付。目前最受欢迎的CI/CD工具是Azure DevOps和Jenkins。

下面我们再来看看使用Terraform将DevOps的基础架构作为代码。说道基础架构即代码(IaC),您需要理解的是:

  • 基础架构团队能够更专注于增值工作(而不是那些例行的工作)。
  • 出现更少的错误,并可以从故障中快速地恢复。
  • 具有服务器的一致性,避免了配置上的偏差(Configuration Drift)。

上图展示了基础架构即代码的基本步骤,主要包括:通过模板来配置服务器(或启用云端服务),安装软件,以及配置软件等。通常,配置工具可用于准备和提供具有联网功能的新服务器。目前,最受欢迎的基础架构即代码工具有Ansible和Terraform。

通过Terraform,您可以预配置服务器、负载平衡器、数据库、以及网络等基础架构的其它部分。您可以使用Packer和Amazon Machine Image(AMI)等工具来为那些服务器预创建的镜像。

目前,比较流行的配置管理工具有Chef、Puppet、Ansible和SaltStack,它们能够在现有的服务器上安装和管理各种软件。

Docker和Kubernetes在DevOps中的作用

我们既可以使用Java,也可以使用Python,还可以使用JavaScript,来构建各种微服务。而不同的微服务针对不同的应用程序,也可能采用不同的方式被部署到服务器上。这些都给运营团队的工作带来了不小的困难。那么,我们该如何采用类似的方式来部署多种类型的应用呢?答案是:容器和Docker。如上图所示,通过Docker,您可以摆脱语言和基础架构的限制,以相同方式去构建和运行微服务的不同镜像。这将大幅简化运营的开销。

同时,作为补充,Kubernetes通过协调不同类型的容器,实现了在集群上的部署。如下图所示,Kubernetes还能够提供:服务发现,负载均衡,以及集中配置等服务。

可见,Docker和Kubernetes能够使DevOps变得更加容易实现。

重要的DevOps指标

下面是您需要在一段时间内持续跟踪和改进的重要DevOps指标。

  • 部署频率 - 将应用程序部署到生产环境中的频率是多久?
  • 面市时间 - 从程序编码到生产环境,大概需要花多长时间?
  • 新版本的失败率 - 有多少个版本失败了?
  • 修复用时 - 需要多长时间进行生产环境的修复,以及发布到生产环境需要多久时间?
  • 平均恢复时间 - 从出现重大问题到恢复生产环境,需要花费多长时间?

DevOps的优秀实践

简单而言,DevOps的优秀实践包括:

  • 标准化
  • 具有跨职能技能的团队
  • 关注团队文化
  • 自动化
  • 恒定的基础架构
  • 开发和生产等价(Dev Prod Parity)
  • 版本控制一切
  • 自行配置(Self Provisioning)

DevOps的成熟度标志

那么我们该如何衡量DevOps实施的成熟度呢?请参考如下重要方面:

开发

  • 每次提交都会触发自动化测试和自动化代码质量检查吗?
  • 代码是否能够被持续交付到生产环境中?
  • 使用到了结对编程(pair programming)吗?
  • 使用了测试驱动开发(TDD)和行为驱动开发(BDD)吗?
  • 可重复使用的模块多吗?
  • 开发团队可以自行配置环境吗?
  • 需要多长时间能够快速修复生产环境?

测试

  • 是否能够通过高质量、类似生产环境的测试数据,来开展完全自动化的测试?
  • 在自动化测试失败时,构建也会失败吗?
  • 测试周期短吗?
  • 有自动化的NFR测试吗?

部署方式

  • 是否具有开发和生产等价?
  • 是否使用了A/B测试?
  • 是否使用了金丝雀部署?
  • 是否可以一键式部署?
  • 是否可以一键式回滚?
  • 是否可以一键式配置和发布基础架构?
  • 是否用到了基础架构即代码和版本控制?

监控

  • 团队是否使用了集中式监控系统?
  • 是否可以一键式让开发团队访问到日志?
  • 如果在生产环境中出现了问题,团队是否能够收到自动警报?

团队与流程

  • 团队是否能够不断地寻求改进?
  • 团队是否具备业务、开发和运营所需的全部技能?
  • 团队是否能够跟踪关键的DevOps指标,并对其进行改进?
  • 是否营造了接受本地发现(Local Discoveries),并利用其进行全局改进(Global Improvements)的文化?

向DevOps转换的优秀实践

  • 最重要的是领导愿意“买单(Buy-in)”
  • 准备好各项前期成本(Upfront Costs)
  • 设置专业知识中心(Center of Expertise,COE)以协助团队
  • 选择合适的应用程序和团队
  • 从小处开始动手
  • 通过实时通讯、沟通、以及COE等方式分享学习
  • 以探索和自动化的思维方式鼓励团队
  • 能够真正认可DevOps团队

彩蛋:免费知识拓展资料

  • 十步学习Docker - https://links.in28minutes.com/in28minutes-10steps-docker。
  • 十步学习Kubernetes - https://links.in28minutes.com/in28minutes-10steps-k8s。
  • 十步学习AWS - https://links.in28minutes.com/in28minutes-10steps-aws-beanstalk。