第 4 章:部署到测试环境

第 3 章中,我们探讨了持续集成的基础知识,重点关注 CI/CD 流水线的早期步骤:主要是构建和部署前测试。我们详细讲解了一个在 PR 打开时触发的示例流水线,如 图 4-1 所示。

图 4-1. CI 流水线
图 4-1. CI 流水线

该流水线构建并打包了代码,进行了静态代码分析,并执行了早期快速测试,包括单元测试和轻量级集成测试,从而向 PR 提供构建和测试反馈。这些步骤确保拉取请求中的代码处于可合并状态,并提供信心,确保合并后的代码能按预期运行,不会引入任何回归。假设 PR 中的代码更改已准备就绪,开发人员即可合并该 PR。

随着新代码的合并,下一步是通过部署到测试环境并运行一系列测试来为生产环境做准备。AI 和 ML 工具正在被整合到部署流程中。这些工具帮助团队做出更好的部署决策,主动识别潜在问题,并简化验证流程。优秀的 AI 实施非但不会增加复杂性,反而能减轻开发人员的认知负荷,同时提高部署的可靠性。

在 CI 步骤和生产发布之间,我们主要关注测试。我们想知道发布是否已为我们的用户做好准备。如果可以安全发布,我们希望快速将其交付给用户,以增强用户体验,并可能提高客户参与度和忠诚度。如果我们的软件有问题,我们需要迅速发现并解决。这种动态是发布有价值更新的障碍,缺陷引入与将其反馈给开发团队之间的时间越长,相关开发人员对工作的记忆就越不清晰。他们将不得不花费更多时间和精力来熟悉这些代码段,从而使修复成本更高。如果开发人员已经深入到下一个任务中,那么该任务也可能会被中断,完成成本也会更高。

当发布准备就绪时,我们将把发布部署到一个或多个环境,以便我们可以在运行中的代码上进行测试。正是在这些预生产环境中,我们弥合了开发与实际使用之间的差距,确保我们的软件不仅功能正常,而且已为实际场景做好准备。

图 4-2 概述了我们的整个交付过程。AI 越来越多地被嵌入到整个流水线中,以加强测试和部署决策。

图 4-2. 高层级交付流程
图 4-2. 高层级交付流程

在本章中,我们将探讨预置基础设施、部署到一个或多个预生产环境以及对软件进行测试的步骤。此外,我们还将介绍关键的最佳实践,包括:

  • 使用 IaC 创建与生产环境一致但规模更小的低级环境
  • 使用“类生产”部署来一致地移动您的应用程序
  • 将测试连接到部署流水线
  • 选择在何处将 AI 应用于部署以及在何处保持谨慎

流水线中的这个阶段是关键阶段,开发和运维关注点在此交汇。通过理解和实施这些最佳实践,您将能够更好地根据您的特定项目需求(无论项目规模或复杂性如何)确定最佳的测试环境数量和类型。您将了解如何平衡开发速度和运维稳定性,确保您的软件经过彻底测试并已准备好发布。

建立统一的部署流程

当我们继续沿着交付流水线迈向生产环境时,我们需要考虑必要的部署步骤和部署环境。为了实现可预测和可靠的交付流程,我们需要可预测和可靠的部署步骤和环境。

在本节中,我们将介绍从测试到生产环境实现我们所追求的可预测性和可靠性的最佳实践。在第 8 章中,我们将更详细地介绍生产发布和生产环境。

一致地部署到每个环境

自动化是 DevOps 的基础,而我们交付流水线的一项关键功能就是自动化预生产环境的设置以及向这些环境的部署。正如我们需要在发布软件之前对其进行验证一样,我们也需要采取措施来验证我们如何部署软件。

我们通过始终使用相同的方法部署到预生产环境和生产环境来实现这一点。这种一致性测试了我们的部署方法,并最大程度地降低了在将软件部署到生产环境时重复这些步骤可能出现意外问题的风险。

以下最佳实践有助于提供我们所追求的可预测性。

使用一致的工具

开发人员使用简单工具启动自己的轻量级部署流程以部署到测试环境,而运维团队则专注于使用企业级工具进行生产部署,这并不少见。流程之间的这种不一致性导致更改以“有问题才通知”的方式进行沟通,即开发人员更新其流程后,会忘记通知运维团队,直到出现问题。

应避免这种方法,因为它限制了非生产环境中测试的有效性,并导致自动化脚本工作的重复。相反,应为所有部署采用统一的工具集。

鼓励一致性的一种方法是为开发人员提供易于使用的预制模板流水线,称为"黄金流水线"或"铺就之路"。我们将在第 10 章中更详细地探讨这一点。至少,您的开发人员和运维团队需要就一套通用的部署工具达成一致。

使用一致的流水线步骤和部署策略

无论您是使用 CI/CD 工具还是自定义部署脚本,操作序列都应在不同环境之间保持一致。金丝雀发布或蓝绿部署等高级部署策略通常是基于降低生产部署风险而选择的。如果您的生产环境采用了这些策略,请在您的预生产环境中复制它们。同样,如果您在生产环境中使用特性标志来发布单个特性,请在测试环境中使用特性标志来推出这些特性。这种一致性最大程度地降低了部署期间引入差异或疏忽的可能性。

我们将在第 7 章第 8 章中更彻底地介绍生产部署和这些渐进式部署策略。目前,请注意您使用的步骤和策略应在每个层面进行复制。虽然测试环境可能由于成本或资源限制而规模较小,但部署时应将其视为生产环境。例如,生产环境中的滚动部署可能一次向 10 个目标部署两个节点,而在测试环境中,您可以一次向 3 个目标部署一个节点。这种方法确保您的生产部署步骤和策略在部署到测试环境的每个版本中都经过彻底测试。

第 7 章中,我们将深入探讨 AI 技术如何验证部署在新环境中没有引起问题。这些相同的方法也应在较低级别环境中使用,以验证其正常工作,并保护我们的测试不会针对有缺陷的安装运行。

使用参数化处理差异

环境之间不可避免地会存在差异。目标名称、服务 URL 和密码可能不同。与其为每个环境创建唯一的部署脚本,不如利用变量来适应这些差异。这使您能够维护一个单一、可适应的脚本或流水线,可在运行时根据特定环境进行调整。

通过在部署中保持一致性,您将创建健壮且可靠的交付流水线,从而增强团队无缝高效发布软件的能力。

利用 AI 加速流水线创建

第 3 章中,我们讨论了自动化流水线创建。模板化仍然是一种很好的模式——您希望您的 AI 能够利用您组织的模板并引入适合您的项目和团队的正确调整和变量。无论是由您还是 AI 创建或维护流水线,流水线代码需要管理的越少越好。

利用基础设施即代码实现部署一致性

我们希望拥有一致且可预测的环境,以将发布交付到生产环境。IaC 为我们提供了一种方法,不仅可以实现一致性,还可以像管理代码资源一样精心控制我们的配置。其核心在于,IaC 将基础设施配置视为软件代码。

工程师在本地对 IaC 代码进行更改,并在其开发环境中进行测试。然后,这些更改会像应用程序代码一样提交到版本控制系统(VCS)。通过管理我们的 IaC,我们充分利用了 VCS 和 CI/CD 流水线的这些功能。

代码即服务的特性使得 IaC 成为一个快速受益于大型语言模型的 DevOps 领域。AI 编码助手能够很好地生成和解释 IaC 代码,降低了开发人员和基础设施专业人员采用新 IaC 语言的门槛。对于能够访问环境性能数据或结合云成本功能与 IaC 管理的 DevOps 平台的主要云提供商来说,未来的代码生成工具可能会结合以下基于实时工作负载的运行时优化:

协作与代码审查

版本控制使多个团队成员能够同时处理文件并管理冲突。我们可以定义和强制执行策略,要求对基础设施配置更改进行代码审查。

分支与实验

版本控制允许您创建分支以试验不同的配置,而不会影响主生产环境。

可追溯性与可审计性

版本控制系统(VCS)提供了配置设置更改的完整历史记录。提交信息和更改历史记录帮助您理解系统演变的原因,并且审计追踪对于支持符合安全框架至关重要。

回滚与恢复

如果基础设施配置更改导致问题,您可以快速回滚到以前正常工作的版本,最大程度地减少停机时间并降低对系统的影响。此外,在发生灾难性故障的情况下,您可以使用版本控制的配置将系统恢复到已知的正常工作状态。

自动化测试

交付流水线可以对 IaC 代码运行自动化测试,包括语法检查、安全扫描和合规性测试。然后,这些更改会应用于预演环境进行集成测试,最后,它们会被提升到生产环境,通常采用谨慎的推广策略。

安全性

版本控制有助于强制执行围绕配置更改的安全策略和控制,确保只有经过授权的人员才能进行修改。

考虑一个在科技行业中许多人耳熟能详的场景:一个应用程序在开发环境中运行完美,在预演环境中运行顺畅,但部署到生产环境时却陷入混乱。这种差异通常源于不同环境之间基础设施配置的不一致。通过 IaC 配置定义,您可以确保从开发到生产的每个环境都得到相同的配置。

这种有条不紊的过程确保您的基础设施以受控、可预测的方式演进。它通过消除环境之间意想不到的差异,解决了“在 QA 环境中正常运行”的问题。通过以与对待应用程序代码相同的尊重和严谨对待您的基础设施,您将获得一致性、可靠性和敏捷性。

除了控制和一致性之外,IaC 还提供了多项优势。只需一个命令,您就可以启动与现有基础设施完全相同的全新环境。这不仅使您的流程可重复,而且还充当了准确、实时的文档。由于环境易于创建和销毁,您可以在不使用时将其拆除,从而节省资源并降低成本,并确信它们可以毫不费力地重新创建。

为了有效地实施 IaC,您需要合适的工具,并且有多种流行的选择。Terraform 及其更开放的分支 OpenTofu 采用云无关的方法。如果您完全依赖于特定的云提供商,那么像 AWS CloudFormation 或 Azure Resource Manager 这样的原生工具可能更适合。

通过 GitOps 利用 Git 工作流

GitOps 是一种较新且日益流行的软件部署方法,它建立在代码仓库的能力之上。通过 GitOps 方法,您可以在版本控制的配置中描述所需的基础设施状态。这种描述是声明性的。GitOps 工具包含一个代理,该代理会定期协调实际环境与 Git 控制配置中描述的所需状态。您无需运行脚本直接部署软件,而是通过更新代码仓库中的配置来启动软件部署。这种方法和 GitOps 工具通常用于 Kubernetes 环境中,以跨机器集群编排容器化应用程序。

通过这种方法,您可以依靠代码仓库来强制执行安全、提供治理,并实施您组织的策略,例如要求通过代码审查和批准进行监督。您的更新是可追溯和可审计的。您可以协作、实验并回滚用于部署软件的配置更新。一旦您进行了更新并合并,GitOps 协调代理就会完成其余工作,获取更新并对目标环境实施更改。

这种方法之所以受到欢迎,是因为管理描述复杂编排云系统的复杂配置非常适合代码仓库的功能。此外,GitOps 解决了环境漂移问题;即,环境在操作上偏离了所需状态。协调代理会自动检测并修复,防止环境中的不一致。

虽然 GitOps 方法功能强大,但在 CI/CD 交付流水线中采用 GitOps 方法进行部署比简单地用脚本推送应用程序更新要复杂。使用 GitOps,您的流水线必须自动化以下步骤:

  1. 从您的代码仓库检索配置。
  2. 更新配置以引用您的应用程序的最新版本。
  3. 将更新后的配置合并回 Git。

然后由 GitOps 协调器接管。

您还可能遇到跨多个集群进行地理复制的应用程序的复杂性。由于许多 GitOps 协调器都针对将应用程序部署到单个集群进行了优化,因此在集群之间维护一致性和同步可能很困难。您可能需要在单一事实来源的需求与某些配置需要针对特定集群进行定制的现实之间取得平衡。商业 GitOps 工具通常在这些更复杂的场景中提供编排和可见性,扩展了开源工具的功能。

尽管存在这些挑战,但在协作、可追溯性和自动化协调方面的优势使 GitOps 成为广泛利用 Kubernetes 的组织的有力选择。

CI/CD 流水线中的持续交付、部署和测试

现在我们已经了解了可预测和可靠的部署步骤与环境的重要性,让我们回到我们的交付流水线。随着新代码的合并,我们现在希望将其部署到一个或多个环境,以便我们可以在运行中的代码上进行测试。图 4-3 显示了一个示例流水线。

图 4-3. 在预生产环境中测试我们的代码
图 4-3. 在预生产环境中测试我们的代码

在本节中,我们将重点介绍流水线:

1. 代码触发器

拉取请求被审查、批准并合并到主分支。在此流水线中,PR 合并触发流水线。

2. 持续集成

流水线重复了我们在上一章中回顾的持续集成步骤,包括检出、构建和执行持续集成测试。

3. 预置基础设施

流水线预置测试所需的预生产环境。

4. 部署到一个或多个预生产环境

流水线将应用程序部署到一个或多个预生产环境。

5. 对已部署的应用程序进行测试

流水线对已部署的软件进行测试。可以运行各种类型的测试,具体取决于软件类型和组织优先级。我们将在下一节中介绍多种不同类型的测试。流水线可以配置为并行或顺序运行多种类型的测试。某些测试可以重复使用相同的预生产环境,而其他测试

可能需要根据测试要求定制的预生产环境。通常,较快的测试优先于较慢的测试。

6. 部署到生产环境

最后一步是部署或推进到生产环境。根据您的交付流程,部署到生产环境的决策可以是自动化的,也可以需要手动批准。我们将在第 7 章中探讨推进策略和部署到生产环境的步骤。

持续交付与持续部署

持续交付(Continuous Delivery)和持续部署(Continuous Deployment)这两个术语经常互换使用。持续交付通常被宽泛地定义为一个自动化软件发布直到生产部署点的过程,在更改上线前需要手动批准。另一方面,持续部署则完全自动化了整个过程,包括部署到生产环境。

混淆产生的原因是流水线会自动部署到中间测试环境。一些人使用“持续交付”来涵盖这些自动化的中间部署,而另一些人则将其保留给不自动部署到任何环境的流程。同样,“持续部署”有时被广泛用于描述任何自动化部署,包括部署到测试环境。

为了避免混淆,我们倾向于广义地使用“持续交付”来指代频繁向用户交付软件的过程。减少手动步骤的数量通常会使这个过程更频繁。当我们讨论特定交付流程中的部署步骤时,我们会包含关于部署环境(中间或生产)和类型(自动化或手动)的详细信息。

测试类型

测试环境对于运行测试至关重要,但测试的选择在很大程度上取决于所开发的应用程序类型、目标用户、软件架构以及预算和时间限制。例如,一般来说,网站的测试优先级与嵌入式软件或 Web API 的测试优先级将大相径庭。在高度受监管行业中的软件服务与必须对大量零售用户直观且引人注目的软件之间的测试优先级也会有所不同。您选择的测试及其频率会显著影响应用程序质量、基础设施成本和整体交付速度。

AI 驱动的测试平台越来越多地使用机器学习(ML)来优化测试策略。这些平台分析历史测试数据、代码更改、应用程序架构和过去的部署问题,以智能地选择和优先处理测试。例如,AI 驱动的测试选择工具可以识别针对每次代码更改要执行的最具影响力的测试,从而显著加快测试周期。Harness、Tricentis SeaLights 和 CloudBees Launchable 等供应商正在使用 AI 和 ML 技术来优化测试选择。

以下是此阶段常见的测试类型:

端到端测试或功能测试

这些测试是最直接的测试类型,它们模拟真实世界的用户场景,并从头到尾验证整个应用程序流程,以确定软件是否按预期运行。这些测试可以是自动化的,也可以是手动执行的。现代团队更多地采用自动化。Selenium 是一个常用的开源测试自动化框架,许多商业工具也以此为基础。机器学习在这些工具中已经存在了一段时间,但我们正越来越多地看到向 AI 优先方法的转变,我们将在稍后深入探讨。

AI 驱动测试

AI 可以自动生成测试用例,识别边缘情况,并从之前的测试运行中学习,从而专注于最可能出现问题的区域。AI 测试很可能补充或成为您的端到端(功能)测试程序的一部分。

API 测试

API 测试是功能测试的一种形式,它验证 API 是否按预期工作。在分布式系统中,服务通过 API 进行交互,因此确保 API 运行良好至关重要。常见的 API 测试框架包括 SoapUI、Postman、Insomnia 和 Swagger。AI 增强的 API 测试超越了简单的验证,能够智能地探索 API 行为和边缘情况。这些系统可以通过分析 API 文档或实际使用模式自动生成 API 测试场景。

用户体验测试

开发人员、测试人员和产品经理可能会评估新功能,以确保它们易于使用且直观。虽然这可能测试与端到端测试相同的系统,但重点在于评估可用性。

用户验收测试

这些测试通常作为最后一道检查,以确保软件满足最终用户的需求、符合要求并按预期运行。用户验收测试可以包括许多其他类型的测试,从端到端到用户体验和性能测试。这些测试从最终用户的角度进行,目的是对软件发布提供最终和正式的验收。

辅助功能测试

这些测试确保我们的软件可供有视力、听力或认知障碍的人使用,以服务我们的用户并符合法律、合同和法规要求。开源辅助功能扫描器包括 Lighthouse 和 Pa11Y。包括 accessiBe 在内的公司也开始提供 AI 增强的测试和修复工具。

本地化测试

本地化测试对于面向全球受众的软件至关重要。它涉及对产品在特定目标区域内的语言准确性、文化适宜性和功能正确性进行全面评估。这包括验证翻译、根据文化敏感性调整视觉效果,并确保软件在本地格式和法规下正常运行。

性能测试

这些测试模拟工作负载,以评估应用程序在不同条件下的速度、响应能力和稳定性。这些测试有助于识别性能瓶颈,并确保应用程序能够处理预期的流量。对于具有季节性高峰的应用程序,此类测试至关重要,以确保发布能够承受高峰需求。Apache JMeter、Gatling 和 Grafana k6 经常用于性能测试。AI 可以利用性能测试数据来推荐要运行的弹性测试。这些由 AI 驱动的性能测试系统现在可以比传统的基于阈值的方法更准确地检测性能异常。这些系统建立基线性能模式,并识别可能预示即将出现问题的细微偏差。更高级的平台甚至可以通过将测试结果与代码更改和架构图关联起来,查明导致性能下降的具体组件或代码更改。

弹性测试

在现代分布式系统中,生产系统由许多组件组成。唯一可以确定的是,总会有某个地方出问题。弹性测试,也称为混沌测试,评估当软件所依赖的服务发生故障时,软件是否能保持可用。我们将在第 6 章中回到弹性测试。

安全测试

这些测试识别应用程序中可能被攻击者利用的漏洞和弱点。它们有助于确保应用程序的安全性和完整性。动态应用程序安全测试(DAST)是一种特定类型的安全测试,它自动化了渗透测试,检查正在运行的应用程序是否存在安全缺陷。DAST 尝试像恶意用户一样攻击您的应用程序。ZAP 是一种常用的免费工具,而 Veracode 和 Checkmarx 的商业产品也很受欢迎。我们将在第 5 章中回到安全测试。

虽然上面概述的测试类型很常用,但重要的是要注意,软件测试没有一刀切的方法,并且术语在不同组织之间可能有所不同。您选择的具体测试以及如何分类它们将取决于您独特的开发流程、应用程序架构和风险承受能力。

基于意图的功能和端到端测试

传统的自动化功能和端到端测试方法通常严重依赖脚本化测试或简单的录制 - 回放方法。虽然最初方便,但这些测试很快变得脆弱且难以维护,只要发生微小的 UI 更改就会失效。这种脆弱性带来了高昂的维护负担,减慢了开发速度,并经常导致团队完全放弃自动化测试或限制其范围。

一种新兴的 AI 优先测试方法,称为基于意图的测试,旨在克服这些挑战。团队不再明确地编写脚本或手动录制每个测试步骤,而是表达其测试场景的意图,描述他们期望的结果,而不是实现它的精确行动序列。AI 原生测试工具随后通过与您的应用程序交互,像人类用户一样动态生成和执行这些测试。

例如,您无需记录电子商务结账流程中精确的点击和表单输入,只需描述目标:“使用信用卡购买产品。”AI 将自动确定通过您的应用程序的最合适路径,智能地与按钮、表单和工作流进行交互。

一个重要的好处是测试弹性的提高——解决了基于 UI 的测试脆弱的挑战。如果 UI 后来发生变化,AI 会适应新的布局或修改后的交互,从而显著减少维护开销。测试自动化工具多年来一直尝试自动修复测试,采用的技术从跟踪 DOM 对象到实施机器学习。转而理解测试背后的意图,并尝试响应 UI 大修重新生成整个脚本,带来了新的可恢复性水平。

这些工具还可能有助于弥补从专业测试人员转向要求开发人员拥有这些测试的转变。这些工具可以推荐与现有测试相关的额外测试和断言,这可能有助于乐观的开发人员记住检查边缘情况和不良用户行为。

AI 的高级用例包括将使用传统工具(如 Selenium 和 Playwright)编写的测试迁移到基于意图的测试工具中,以及不仅生成和运行单个测试,还生成和运行整个测试用例。

传统测试与“掏空中间层”方法

在传统软件开发中,测试通常是分门别类的,每种类型都有专门的环境。例如,这可以确保手动用户体验测试永远不会受到并发自动化性能测试的影响。然而,这种隔离是有代价的:测试环境的激增成本高昂,并且管理耗时。当单个新发布必须通过众多阶段时,面对加速的发布节奏和日益增长的应用程序复杂性,这种方法变得越来越不可持续。

当您试图加速发布节奏并且您的应用程序变得更加复杂时,跨多个阶段进行测试变得越来越不可持续,每个阶段都需要一个新的环境。图 4-4 说明了这种分阶段的方法。

图 4-4. 通过多个预生产环境进行的传统测试
图 4-4. 通过多个预生产环境进行的传统测试

另一方面,一种更现代的测试方法正在挑战这种模式。这种方法有时被称为“掏空中间层”。它不再是在多个环境中进行多个顺序测试,而是减少环境数量,并在其中并发运行测试。这种实践提倡将测试同时“左移”和“右移”

我们在第 3 章中介绍了左移安全。通过将 SAST、SCA、依赖项扫描和秘密检测移至部署前步骤,我们的示例流水线体现了左移。我们早期就纳入了这些关键测试,使其通过成为代码合并的先决条件。作为合并工作流一部分完成的单元测试和其他早期测试,也代表了左移方法。这有助于更早地发现问题,减少对大量下游测试的需求。

右移方法提倡在实际生产环境中对新版本执行某些类型的测试,这些测试传统上属于后期测试类型。我们不再是从一个或多个预生产环境预置并移动发布,然后使用这些隔离环境进行测试,而是将应用程序直接部署到生产环境并在那里进行验证。例如,负载测试可能难以很好地执行,并且环境可能需要很大。部署到生产环境的一部分,对目标基础设施施加负载,并使用生产可观测性工具测量影响,这可以作为传统负载测试的可行替代方案。图 4-5 阐述了这种方法。

图 4-5. “掏空中间层”的测试方法
图 4-5. “掏空中间层”的测试方法

我们可以看到,消除对与生产环境高度相似的预生产环境的需求可以节省成本和维护工作,但如何在生产环境中进行大量测试才能安全呢?右移依赖于新的工具和生产部署实践。凭借先进的流量管理、可观测性工具和容器化技术,许多组织发现这些测试实际上可以在生产环境中执行,且副作用最小。除了显著削减基础设施开支外,这种方法还具有产生更准确结果的优势。我们将在第 7 章中讨论这些新工具和生产部署实践。

掏空中间层优化了测试,是组织为加快交付速度而采取的一种现代策略。通过重新设计我们在环境之间移动软件的方法,我们同样可以加速我们的交付过程。在“环境间的推进”一节中,我们将探讨我们应如何以及为何在环境之间推进发布。

环境间的推进

在上一节中,我们研究了一个典型的交付流程,该流程要求我们的软件经过多个测试阶段,每个测试阶段都在一个单独的预生产环境中进行。在此流程中,我们希望尽可能快且智能地推进我们的发布,这意味着我们的新版本软件应毫无不当延迟地进入下一个环境和阶段。

关于推进
不同环境之间的版本推进promotion,即版本在各个交付环境之间的逐步推进/流转,以进入更高阶段的测试或上线)

AI 在此推进过程中开始发挥越来越大的作用,它分析测试结果、性能数据和部署历史记录,以就何时以及如何推进发布做出智能决策。这些系统可以同时评估多个指标,检测可能指示风险的细微模式,并随着时间的推移通过机器学习变得越来越准确。

理想情况下,我们的推进过程很简单:如果一个阶段的测试通过,我们的发布将立即推进到下一个环境,并且该环境已准备好并可用于下一轮测试。推进决策是自动且即时的,仅基于前一个测试阶段是否通过。在实践中,

发布推进,即使是在测试环境之间,在许多交付流程中也成为瓶颈。这可以归因于几个因素:

推进决策由委员会决定

推进决策不是自动化的,需要对测试结果进行小组审查和批准。

推进依赖繁琐的手动步骤

手动干预以触发下一次部署会造成瓶颈。

测试环境数量不足

如果下一个环境正在测试其他版本,则新版本必须等待。

在本节中,我们将探讨解决这些问题的缓解措施。我们将介绍的实践有助于我们将发布从一个预生产环境移动到下一个,也适用于将我们的应用程序推进到生产环境。然而,最终发布到生产环境有一些特殊考虑,我们将在第 7 章中更深入地讨论。

从委员会决策到自动化决策

人类决策,无论是委员会会议还是值得信赖的个人决策,都不可避免地会延迟您的发布从一个阶段推进到下一个阶段。团队成员需要收到提醒,然后花时间分析测试结果,才能做出决定并采取行动。虽然这不一定总是劳动密集型任务,但无疑会减慢速度。

虽然传统自动化依赖简单的通过/失败标准,但 AI 系统提供了更复杂的决策能力。现代 AI 推进引擎可以同时评估数百个指标,超越简单的测试结果,全面分析系统行为。这些系统可能会考虑性能趋势、错误类型、用户影响评估,甚至基于过去的部署模式的代码更改风险级别等因素。通过适当地加权这些因素,AI 可以做出比传统基于规则的方法更细致的决策。

我们的目标是通过自动化发布推进决策来简化这一过程。我们将在第 7 章中详细回顾这一主题。

从手动推进到自动化推进

一旦您自动化了决策过程,构建的实际推进就会变得显著更容易。关键是确保在做出继续决策后立即触发部署到下一个环境,从而消除不必要的等待时间。

如何实现这种自动化取决于您选择的持续交付工具。一些工具提供端到端流水线,带有简单的内置触发器,可实现阶段间的无缝推进。其他工具允许您在当前流水线中将另一个流水线或作业作为步骤调用,提供灵活性,但可能需要更多配置。虽然实现难度各异,但达到这种自动化水平几乎总是可行的。

然而,GitOps 风格的部署在此领域通常提出独特的挑战,正如我们在“通过 GitOps 利用 Git 工作流”中所讨论的。为了执行部署,我们需要自动化对 GitOps 配置的 Git 更改,而不是依赖手动更新。为此,我们通常会直接在我们的 CI/CD 流水线中自动化拉取请求步骤及其批准。我们保留 Git 作为 GitOps 所熟知的单一事实来源,同时自动化我们发布推进的每个步骤。

例如,想象一个场景,您的流水线已确定一个构建已准备好推进到用户验收测试(UAT)环境。当我们的流水线配置为生成必要的拉取请求、触发任何所需的批准,并在(获得批准后)将更改合并到主分支时,我们的流水线将无缝启动到 UAT 环境的 GitOps 部署。

打破环境瓶颈

在您的交付流程中自动化阶段和环境之间的推进,最后一个挑战是确定您所需的“正确”环境数量。环境过多会因维护其底层基础设施而造成财务负担,而环境过少则会造成瓶颈并延迟发布向交付的进程,因为流程需要等待资源可用。

临时环境为这一困境提供了一个常见的解决方案。这种方法涉及在需要测试时按需创建环境,并在测试完成后迅速将其拆除。在云时代之前,环境创建是一个费力的过程,通常需要数天时间。现在,得益于可编程的云基础设施,环境可以在几分钟内启动和拆除。

基础设施即代码管理(IaCM)工具简化了临时环境。这些专业的 CI/CD 平台使用代码自动化基础设施资源的预置、配置和部署。与专注于应用程序的传统 CI/CD 工具不同,IaCM 工具管理底层基础设施。使用 IaCM 工具,您可以使用声明式代码模板定义所需的基础设施状态,使配置更易于管理、维护和版本控制。

理想情况下,为实现我们“类生产”测试环境的目标,应使用相同的模板创建预生产测试环境和生产环境,仅对变量进行调整。当您的流水线与 IaCM 工具无缝集成时,部署到“测试”阶段会自动触发相应“测试”环境的创建。一旦此环境预置并配置了必要的详细信息,如 IP 地址、密码和其他特定于环境的变量,部署和测试过程即可进行。完成后,IaCM 工具会高效地拆除环境,释放资源。

虽然此策略在一致性、灵活性和成本降低方面提供了显著优势,但需要注意的是,环境创建和销毁过程可能会增加整体测试周期几分钟。因此,对于目标是极快速交付周期(例如以分钟计)的流水线,临时环境可能不是理想的解决方案。然而,对于以小时、天或周为单位的交付周期,临时环境提供了一种强大的方式来打破瓶颈、提高一致性并优化基础设施成本。

总结

在本章中,我们继续探讨交付过程,重点关注持续集成之后的持续交付步骤。这些主要是测试步骤,我们回顾了对验证软件所有方面都至关重要的测试类型。我们讨论了可靠和可预测的预生产环境对测试的重要性,以及实现这些环境的最佳实践。通过自动化发布在测试阶段之间推进的所有方面,包括推进决策,我们可以显著加速软件的交付。

完成测试后,只剩下最后一步才能将我们最新的软件版本交付给用户:实际部署到生产环境。我们将在第 7 章中回到这一步。在此之前,我们将在接下来的几章中讨论如何加强我们的发布,使其更安全、更具弹性和更可靠。

文章导航

独立页面

这是书籍中的独立页面。

书籍首页

评论区