Close

如何实践 DevOps

为希望实施 DevOps 的团队提供的分步指南

Krishna Sai 的头像
Warren Marusiak

高级技术传播者


您的软件开发生命周期是不是充斥一堆混乱的工具和工作流程?您的团队和项目是孤立的吗?如果您对其中一个问题的回答是肯定的,那么现在是考虑 DevOps 的最好时机。DevOps 通过创建新的软件开发生态系统,帮助简化和优化开发和部署工作流程。

但您是如何实现 DevOps 的呢?DevOps 的主要挑战之一是没有标准流程,因为每个团队的需求和目标都各不相同。数量庞大的 DevOps 工具和资源可能导致“分析瘫痪”,从而抑制其采用。以下步骤可以帮助您的团队实施 DevOps。

为什么选择 DevOps?


简短的答案是,DevOps 允许开发人员做自己最擅长的事情,从而提高工作效率:构建出色的软件,而不是手动执行诸如手动检查日志文件之类的低价值工作。DevOps 实践可自动执行重复性工作,例如运行测试和部署、监控生产软件是否存在问题,以及构建具有问题弹性的部署方法。开发人员能够进行构建和实验,从而提高工作效率。

DevOps 有很多定义。在本文中,DevOps 意味着团队拥有软件的整个生命周期。DevOps 团队设计、实施、部署、监控、修复问题并且更新软件。DevOps 团队拥有代码和运行代码的基础架构。不仅对最终用户体验负责,还要对生产问题负责。

DevOps 的宗旨是构建一个能够预测问题并使开发人员能够有效应对问题的流程。每次部署后,DevOps 流程应为开发人员提供有关系统运行状况的即时反馈。问题发现的越早,问题造成影响就越小,团队就能越早进入下一个工作。如果可以轻松部署变更并从问题中恢复过来,开发人员便可以试验、构建、发布和尝试新想法。

DevOps 的本质并非是技术。如果您只是购买了 DevOps 工具就将其称为 DevOps,那就是本末倒置。DevOps 的本质是建立责任共担、透明和加快反馈的文化。技术只是实现这一目标的一种工具。

组织徽标
相关资料

免费试用

奖杯图标
相关资料

详细了解 DevOps 最佳实践

免责声明


鉴于每个团队都有独特的起点,因此以下某些步骤可能不适用。此外,此列表并不详尽。此处介绍的步骤旨在作为帮助团队实施 DevOps 的起点。

在本文中,DevOps 被用作一个包罗万象的术语,指的是使 DevOps 发挥作用的文化、流程和技术。

实现 DevOps 的 8 个步骤


DevOps 循环

第 1 步 - 选择一个组件

第一步是从小处着手。选择当前正在生产的组件。理想的组件具有简单的代码库,几乎没有依赖关系和最少的基础架构。该组件将成为团队在实施 DevOps 时起步训练的试验场。

第 2 步 - 考虑采用像 Scrum 这样的敏捷方法

DevOps 通常会搭配敏捷工作方法,例如 Scrum。没有必要采用与某种方法(如 Scrum)相关的所有仪式和做法。Scrum 的三个要素通常易于采用并能快速提供价值:待办事项冲刺冲刺规划

DevOps 团队可以在 Scrum 待办事项中添加工作并确定其优先级,然后将该工作的一部分提取到冲刺中,这是完成特定工作部分的固定时间长度。冲刺计划是决定哪些任务从待办事项转到下一个冲刺的过程。

第 3 步 - 使用基于 Git 的源代码控制

版本控制是 DevOps 的最佳实践,它可以加强协作和缩短发布周期。像 Bitbucket 这样的工具允许开发人员共享、协作、合并和备份软件。

选择分支模型。本文概述了这个概念。对于刚接触 Git 的团队来说,GitHub Flow 是一个很好的起点,因为这个概念易于理解且易于实现。基于 Trunk 的开发通常是首选,但需要更多的纪律,这使得首次尝试 Git 变得更加困难。

第 4 步 - 将源代码控制与工作跟踪相结合

将源代码管理工具与工作跟踪工具集成。通过在一个集中位置查看与特定项目相关的所有内容,开发人员和管理层将节省大量时间。以下是来自基于 Git 的源代码管理存储库更新的 Jira 事务的示例。Jira 事务包括一个开发部分,其中汇总了在源代码管理中针对 Jira 事务所做的工作。这个事务有一个分支、六个提交、一个拉取请求和一个生成。

将源代码控制与工作跟踪集成的屏幕截图

您可以深入查看 Jira 事务的开发部分,以了解更多详细信息。“提交”选项卡列出了与 Jira 事务相关的所有提交。

将源代码控制与工作跟踪集成的屏幕截图

本部分列出了与 Jira 事务相关的所有拉取请求。

将源代码控制与工作跟踪集成的屏幕截图

与此 Jira 事务相关的代码已部署到“部署”部分列出的所有环境中。这些集成的工作方式通常如下所示:添加 Jira 事务 ID(在本例中为 IM-202)来提交与 Jira 事务相关的工作的消息和分支名称。

将源代码控制与工作跟踪集成的屏幕截图

代码选项卡提供指向与项目相关的所有源代码控制存储库的链接。它可以帮助开发人员在将自己分配给 Jira 事务时找到他们需要处理的代码。

将源代码控制与工作跟踪集成的屏幕截图

第 5 步 - 编写测试

CI/CD 管道需要测试来验证部署到各种环境的代码是否正常运行。首先为代码编写单元测试。虽然宏伟的目标是 90% 的代码覆盖率,但这在刚开始时是不现实的。为代码覆盖率设置较低的基准,并随着时间逐步提高单元测试覆盖率的标准。您可以将工作项目添加到待办事项来解决这个问题。

修复生产代码中发现的缺陷时使用测试驱动的开发。发现一个缺陷时,编写单元测试、集成测试和/或系统测试,这些测试会在存在缺陷的环境中失败。然后修复缺陷,观察测试现在是否通过。随着时间的推移,此过程将系统性地增加代码覆盖率。如果错误是在测试或暂存环境中发现的,则测试将让您确信代码在升级到生产环境后可以正常运行。

如果从一开始就进行,这个步骤很费力,但也很重要。最终用户接触到这些代码更改之前,测试使团队能够看到代码更改对系统行为产生的影响。

单元测试

单元测试将验证源代码是否正确,并且应作为 CI/CD 管道中的第一步运行。开发人员应针对绿色路径、有问题的输入以及已知的极端情况编写测试。在编写测试时,开发人员可以模拟输入和预期输出。

集成测试

集成测试验证两个组件之间的通信是否正确。模拟输入和预期输出。在将 CI/CD 管道在部署到任何环境之前,都必须首先进行这些测试。这些测试通常需要比单元测试更广泛的模拟才能让组件正常运行。

系统测试

系统测试可验证系统的端到端性能,并确保系统在每个环境中都能按预期运行。模拟组件可能接收的输入并执行系统。接下来,验证系统是否返回了必要的值并正确更新系统的其余部分。应在部署到每个环境后运行这些测试。

步骤 6 - 构建 CI/CD 流程来部署组件

在构建 CI/CD 管道时,考虑部署到多个环境。如果团队构建仅部署到单个环境的 CI/CD 管道,则会对某些内容进行硬编码。为基础设施和代码构建 CI/CD 管道非常重要。首先构建 CI/CD 管道,在每个环境中部署必要的基础架构。然后,再构建一个 CI/CD 管道来部署代码。

管道结构

该管道首先运行单元测试和集成测试,然后再部署到测试环境。系统测试在部署到环境后执行。

将源代码控制与工作跟踪集成的屏幕截图

上面的粗略模板可以通过多种方式进行扩展。在单元测试和集成测试之前,最好是添加一些额外步骤,比如代码校验、静态分析和安全扫描。代码校验可以强制执行编码标准,静态分析可以检查反模式,安全扫描则可以检测是否存在已知漏洞。

将源代码控制与工作跟踪集成的屏幕截图

用于部署基础设施和代码的 CI/CD 管道可能有所不同。基础设施的 CI/CD 管道通常没有单元测试或集成测试。将在每次部署后运行系统测试,以确保系统没有停止运行。

基础设施

环境之间基础架构的差异使得在某一环境中运行的软件难以在另一个环境中正确执行。防火墙规则、用户权限、数据库访问和其他基础架构级组件必须采用已知配置,这样软件才能正常运行。手动基础架构部署可能很难正确重现。由于此过程涉及许多步骤,因此依靠记忆力来使用正确的参数以正确的顺序执行每个步骤,这可能会导致错误。必须尽可能在代码中定义基础架构,以缓解这些问题以及其他问题。

可以通过各种工具在代码中定义基础设施,这些工具包括 AWS CloudFormation、Terraform、Ansible、Puppet 或 Chef。

编写多个管道来部署基础架构。与编写代码一样,保持基础架构部署的模块化也很有帮助。尽可能将所需的基础设施分解为不相交的子集。假设 A、B、C 和 D 是可以相互依赖的基础架构组件的抽象。例如,A 可能是 EC2 盒子,B 可能是 S3 存储桶。基础架构组件 A(仅有 A)依赖组件 B 的依赖关系应该一起保存在同一 CI/CD 管道中。A、B 和 C 依赖 D(但 A、B 和 C 相互独立)的依赖关系应分解为多个 CI/CD 管道。在本例中,有四个独立的管道。在这种情况下,您应该为 D 构建一个其他三个组件都依赖的流水线,并为 A、B 和 C 各构建一个流水线。

代码

CI/CD 管道是为部署代码而构建的。这些管道通常易于实施,因为由于之前的工作,基础架构已经可供使用。这里的重要考虑因素是测试、可重复性以及从错误部署中恢复的能力。

可重复性是指在不损害系统的情况下重复部署相同转换的能力。部署应该是可重入且等效的。部署应将系统的状态设置为已知配置,而不是对现有状态应用修改器。不能重复应用修改器,因为在第一次部署之后,修改器正常运行所需的起始状态已经发生了变化。

对于不可重复更新,一个简单示例是通过向配置文件添加数据来更新该文件。请勿在配置文件中追加行或使用任何此类修改技术。如果通过追加方式完成更新,则配置文件最终可能会出现数十行重复行。正确做法是,将配置文件替换为源代码管理中写入的正确文件。

这一原则也应适用于数据库更新。数据库更新可能会出现问题,需要注意细节。必须使数据库更新过程具有可重复性且具备容错能力。在应用更改之前立即进行备份,以便可以恢复。

另一个考虑因素是如何从错误的部署中恢复。有两种情况:部署失败,系统处于未知状态;部署成功,警报被触发,故障单开始流入。有两种一般的处理方法。第一种方法是回滚。第二种方法是使用功能标志并关闭必要的标志,以恢复到已知的良好状态。有关功能标志的更多信息,请参阅本文的步骤 8。

在检测到错误的部署后,回滚会将先前已知的良好状态部署到环境中。这应该在一开始就做好计划。在操作数据库之前,请先进行备份。确保您可以快速部署以前版本的代码。定期在测试或暂存环境中测试回滚过程。

步骤 7 - 添加监控、警报和仪器

DevOps 团队需要监控每个环境中正在运行的应用程序的行为。日志中有错误吗?对 API 的调用超时了吗?数据库崩溃了吗?监视系统的每个组件是否存在问题。如果监控检测到问题,则会提交故障单,以便有人能够解决问题。作为解决过程的一部分,需要编写可以发现问题的其他测试。

修复缺陷

监控和响应问题是运行生产软件的一部分。采用 DevOps 文化的团队负责软件的运营,并借用站点可靠性工程师 (SRE) 的行为。对问题进行根本原因分析,编写测试以检测问题,修复问题,并验证测试现在是否通过。这个过程在前期通常很费力,但从长远来看,一定会有所回报,因为它减少了技术债务并保持了运营灵活性。

性能优化

一旦实现了基本的运行状况监控,下一个常见的步骤便是性能优化。了解系统各个部分的运行状况,并对慢速部分进行优化。正如 Knuth 所说:“过早的优化是万恶之源”。不要优化系统中所有组件的性能。只优化最慢、最昂贵的部分。监控有助于确定哪些组件速度慢且成本高昂。

第 8 步 - 使用功能标志实现金丝雀测试

要启用金丝雀测试,请将每项新功能封装在一个功能标志中,并附上包含测试用户的允许列表。只有在部署到环境后,新功能代码才会为允许列表中的用户运行。让新功能浸泡在每个环境中,然后再将其推广到下一个环境。当新功能渗入到某个区域时,请注意指标、警报和其他工具,以发现问题迹象。具体而言,请留意新的请求单的增加。

在将问题升级到下一个环境之前,先解决该环境中的问题。在生产环境中发现的问题的处理方式应与在测试或暂存环境中发现的问题的处理方式相同。确定问题的根本原因后,编写测试以确定问题,实施修复,验证测试是否通过,然后通过 CI/CD 管道提升修复程序。新的测试将通过,请求单数量将下降,而更改将渗透到检测到问题的环境中。

总之...


回顾一下将第一个组件移入 DevOps 的项目。找出痛点或具有挑战性或困难的部分。扩大计划以解决这些痛点,然后转到第二个组件。

在一开始就使用 DevOps 方法将组件投入生产似乎是一项艰巨的工作,但以后一定会有所回报。一旦奠定了基础,第个二组件的实施应该会更容易。可以采用与第一个组件相同的流程,并针对第二个组件稍作修改,因为工具已经到位,技术已理解,团队受过培训,可以按照 DevOps 风格工作

要开始 DevOps 的旅程,我们建议您尝试 Atlassian Open DevOps,这是一个集成的开放式工具链,包含开发和操作软件所需的一切,并且能够随着需求的增长集成其他工具。

Warren Marusiak
Warren Marusiak

Warren is a Canadian developer from Vancouver, BC with over 10 years of experience. He came to Atlassian from AWS in January of 2021.


分享这篇文章
下一个主题

推荐阅读

将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。

Devops 示意图

DevOps 社区

Devops 示意图

DevOps 学习路径

地图插图

免费试用

注册以获取我们的 DevOps 新闻资讯

Thank you for signing up