拥抱 DevOps 发布管理——CI/CD 流水线如何强化良好的 DevOps 发布管理

362 阅读54分钟

到目前为止,你已经了解到 CI/CD 是 DevOps 的关键方面。可重用、定制的 CI/CD 平台最大化了每位开发人员的时间价值。通过成为自动化、测试和协作的汇聚点,CI/CD 提高了组织的生产力,增加了效率并简化了工作流程。其他 DevOps 增强措施,如左移策略和创建更紧密的反馈回路,有助于企业消除孤岛、高效扩展,并比其他发布管理方法更快地实现业务价值。

当今的发布经理必须精通 CI/CD 程序、DevOps 和自动化部署技术。他们需要能够在早期阶段识别问题,并了解 CI/CD 流水线的运行机制,这对于 DevOps 发布管理至关重要。在本章中,我们将讨论 CI/CD 流水线如何强化良好的 DevOps 发布管理。我们将涵盖的主题包括管理上市速度和 CI/CD 治理、制定团队的分支策略、构建发布流水线、实施适合 DevOps 发布管理的变更审批流程等!

在本章中,你将学习以下主题:

  • 理解 CI/CD 治理
  • 分支策略
  • 发布流水线
  • 变更管理

理解 CI/CD 治理

在 DevOps 发布管理中实施治理需要建立一系列旨在创建 CI/CD 基础设施内监督机制的程序。这种模式通常结合了访问控制管理、合规政策、自动化测试和手动审核检查点。DevOps 治理的主要重点在于推进操作安全目标,并建立一个全面的框架,用于监控、批准和记录所有修改,以确保可追溯性。

要熟悉 CI/CD 治理,你必须全面了解 CI/CD 流水线的运作机制。正如你在上一章所学的那样,CI/CD 流水线包含一系列自动化工作流程、系统和方法,专门设计用于促进从开发人员的工作站到生产环境的新代码的快速可靠交付。这使得开发人员更容易接收和响应最终用户的反馈。毫无疑问,利用精心设计的 CI/CD 流水线基础设施,可以避免许多通常与软件交付相关的风险。值得注意的是,CI/CD 鼓励开发团队将软件更新分成较轻、较小的批次,而不是一次性大规模处理。

因此,与 DevOps 发布管理相关的快速开发速度可能会在有效管理治理和减轻安全风险方面带来挑战。例如,在生产过程中使用开源软件是开发团队经常关心的问题。如果没有适当的审计、分析和自动化测试,你无法预测何时以及是否会有漏洞影响源代码中的关键依赖项。

OWASP 前十大 CI/CD 安全风险

CI/CD 已成为当代软件工程实践中的关键要素。不幸的是,CI/CD 的利用也带来了一些需要认真考虑的安全漏洞。在本节中,我们将介绍 OWASP 前十大 CI/CD 安全风险,这是一项对威胁任何组织 CI/CD 流水线基础设施的最常见安全风险的全面研究。

开放 Web 应用安全项目(OWASP)是一个全球公认的非营利组织,致力于增强 Web 应用安全性。OWASP 坚持的基本原则之一是通过其官方网站提供免费且易于获取的资源。这些资源包括各种形式的支持,如书面文档、专用工具、教学视频和互动论坛。

OWASP 前十大 CI/CD 安全风险如下:

  1. 流程控制机制不足 (CICD-SEC-1)
  2. 身份和访问管理不足 (CICD-SEC-2)
  3. 依赖链滥用 (CICD-SEC-3)
  4. 被毒害的流水线执行 (CICD-SEC-4)
  5. 流水线访问控制不足 (CICD-SEC-5)
  6. 凭证管理不足 (CICD-SEC-6)
  7. 系统配置不安全 (CICD-SEC-7)
  8. 第三方服务的无治理使用 (CICD-SEC-8)
  9. 工件完整性验证不当 (CICD-SEC-9)
  10. 日志记录和可见性不足 (CICD-SEC-10)

你可以在 OWASP 基金会网站上找到这些风险的列表。

OWASP 前十大 CI/CD 安全风险的详细信息过于庞大,无法在本章中包含。相反,请参考本书末尾的附录,以详细研究这些前十大安全风险以及如何实施保护措施来防范这些风险。通过熟悉这些风险并实施建议的对策,你将有信心增强组织中 CI/CD 流水线基础设施的安全性。

上市速度与治理之间的平衡

CI/CD 使快速开发和发布周期成为可能,但全面的安全检查、手动审核和审批程序可能会大幅减缓进程。在理想的情况下,安全检查和合规评估应以既有目的性又不具侵入性的方式融入软件交付生命周期。将 CI/CD 治理与效率相协调的任务可能会带来可避免的困难,因为过于宽松的治理方法可能会导致代码质量下降和安全风险增加,而过于严格的方法则可能会阻碍部署过程并抑制创新。

为了优化生产力并防范潜在风险,建立明确的政策和程序并严格执行其遵守是非常宝贵的。有效的软件开发策略应纳入确保代码质量和最小化安全漏洞的协议。其中一些做法可能包括代码审查、自动化测试和一键部署审批。通过实施这些措施,你可以建立质量关卡来评估代码更改并防止引入未经授权的代码,这是一个主要的安全风险。定期审查和更新治理标准对于确保团队继续与组织目标保持一致至关重要。

三种常见的 CI/CD 治理路径

经验丰富的 DevOps 团队通常使用三种主要的治理模型来管理他们的应用程序部署和 CI 基础设施。这些模型在治理的方面有所不同,分别是基础设施代码、部署工具链和提供的云资源:

  1. 中央模式库治理模型:这是一个宝贵的资源,提供了一组经过精心整理的部署模板。这些模板旨在被应用团队在部署过程中重复使用。通过利用中央模式库,团队可以受益于预先开发的模板,这些模板经过精心选择和组织,便于访问和实施。这种治理模型的另一种思考方式是,它通过将决策权下放给独立开发团队,从而统一于一套预先批准的流程。
  2. CI/CD 即服务治理模型:这是一种提供标准化工具链供应用团队使用的软件开发实践。此服务允许代码更改的无缝集成和交付,确保顺畅高效的开发过程。通过提供可重用的工具链,CI/CD 即服务能够简化应用团队的工作流程并增强开发环境中的协作。另一种描述此治理模型的合适术语是服务目录。
  3. 中央管理基础设施治理模型:指的是一种系统,应用团队可以部署由中央运营团队管理的云资源。这种安排实现了资源部署和管理的简化,因为监督和维护这些资源的责任是集中的。通过实施这种方法,组织可以确保云资源的高效利用,同时在不同的应用团队中保持一致的标准化基础设施。与此治理模型相关的另一个合适术语是 DevOps 卓越中心。

常见的 CI/CD 治理障碍

在 CI/CD 治理方面,找到速度、稳定性和可靠性之间的最佳平衡可能具有挑战性。这只是你可能面临的一些常见问题之一。另一个挑战是团队在更大规模上管理 CI/CD 流程和系统的能力。原因在于企业公司拥有大量员工、复杂的组织结构和广泛的代码库。这些因素导致了这些类型公司所独有的特定需求和要求。

理想的治理架构应优化基础设施能力与业务需求的对齐,同时为最终客户提供最大的价值。IT 组织可以利用治理模型作为一种高效工具来实施企业标准,引入新技术,并执行默认的监管要求。值得注意的是,企业架构师有责任确保治理模型与业务架构保持一致。

构建治理模型的最佳实践包括可扩展性和可重复性。当为组织构建治理模型时,该过程可以被用于多个产品和服务。治理模型管理的项目必须是可量化的,以便在合规性审查、可用性监控和性能优化时进行审查。治理模型还应涵盖所有可能的基础设施能力组合以及不同的部署要求。因此,创建云治理模型的目标是可扩展性,即治理模型可以根据市场或目标受众的需求增长或缩减。它应促进所提供服务的水平和垂直扩展的透明集成。治理模型还应具有适应性,考虑到最终用户的不断变化需求以及对 IT 基础设施的影响。

必须记住,除非同时考虑到业务视角和 IT 视角,否则不可能创建优化的云治理模型。在开发 CI/CD 治理架构时,组织通常会面临以下四个常见挑战中的至少一个。它们反映了广泛的不同考虑因素。

工具的扩散

CI/CD 治理模型的实施常常受到组织技术堆栈复杂架构的阻碍。在大多数环境中,开发团队倾向于使用多种编程语言、框架、生产力工具和结构系统。然而,这些工具的扩散在实施统一的治理实践和流程方面带来了挑战:

image.png

这种困境通常导致工具瘫痪的状态,在这种状态下,软件工程师对现有的技术基础设施表示不满,同时也担心转向替代解决方案所需的时间、精力以及潜在的挑战。产品负责人最终会对膨胀的估算感到不满,甚至可能质疑为何需要多个冲刺周期才能开发出某个特定功能。

用户访问控制和授权管理

访问和授权管理是许多企业面临的主要障碍。拥有一套适当的工具来自动化大部分流程至关重要,以便在需要时正确的人员可以访问适当的信息。有一些工具可以帮助管理和控制用户访问权限,但并非所有工具都提供了所需的细粒度授权管理功能。

自动化消除了许多手动安全分析检查的需求。如今,流水线的完整性被用来简化职责分离的要求。维护流水线基础设施的团队与使用它的团队之间需要有明确的职责分离。你可以设置源代码控制工具,使只有负责 CI/CD 流水线基础设施的工程师才能对基础设施组件和/或配置和模式进行更改,从而有效地分离各组的责任。例外情况应当很少见,并且要经过授权、记录,并在发生时受到密切监督。

系统访问管理

许多公司面临的一个典型挑战是确保 CI/CD 工作流中使用的各系统之间网络连接的安全性。使用个人访问令牌作为密码的替代品以及使用临时的、一次性使用的令牌是确保安全性的两种最重要策略。此外,还有一些辅助软件和服务可以编程方式自动旋转密钥和刷新凭证。

攻击者利用不良的凭证管理实践,通过找到暴露的凭证并利用它们获得对系统的未经授权访问。一旦完成提取,攻击者会验证凭证的有效性。通常,这在被入侵或一次性使用的机器上完成,以规避检测。一旦攻击者获得必要的凭证,他们就可以获得对计算机系统或服务的未经授权访问。攻击者的权限和授权级别决定了他们能访问的敏感信息、能发出的命令或能执行的其他恶意行为。

可追溯性

在受到严格监管的行业中,可追溯性和审计能力往往是强制性的。然而,无论你是否受监管,可追溯性都是必不可少的。其目标是能够识别你期望在最终产品中看到的功能是否确实存在于软件中。如果发生安全漏洞,这一点至关重要。

为了实现理想的流水线,CI/CD 生态系统及其各种组件必须无缝运作,不能有任何中断。还需要对现有的所有元素(如代码、脚本、测试以及开发和测试标准)进行全面记录。每个元素的用途、创建者、依赖关系和关联都必须记录并定期更新。你必须确保这些记录存储在源代码控制下并得到妥善管理。

创建企业 CI/CD 治理模型

没有一个单一的 CI/CD 治理标准格式。这是因为每个模型都是根据其支持的公司或组织的具体需求、立法、合规标准和行业规范量身定制的。然而,大型企业可以通过一些方法来创建和维持一个强大的端到端 CI/CD 治理策略。在制定或审核你的 CI/CD 治理标准时,可以考虑本节中提出的技术。

映射 CI/CD 系统和流程

创建 CI/CD 流程和系统的可视化表示,有助于全面理解整个 CI/CD 流水线。这有助于识别安全性最容易受到威胁的具体阶段。此外,这可能揭示出改善流程、基础设施和安全态势的其他选项。一种有效的完成此任务的方法是生成所谓的价值流映射。价值流映射应包括 CI/CD 流程、基础设施和工具,以便你能够全面了解各个过渡点,并在业务控制、合规要求和行业法规之间建立联系。这样做可以优化当前流程,建立治理模型,并为公司准备接受审计。增加流程的可见性是观察如何改进它的最快方法之一:

image.png

上图展示了一个在精益制造背景下的价值流图的通用示例。尽管价值流图通常与制造业相关联,但它也被应用于物流和供应链管理、服务导向的垂直行业、软件开发、产品开发、项目管理等诸多领域。

价值流图的目标是发现并消除或最小化业务流程中的浪费活动,从而最终提高特定价值流的整体效率。减少浪费的目标是通过简化流程来提高产出,并使其更容易发现质量低劣或浪费过多的情况。

关于价值流图的更多信息,请参考本书末尾的附录。

声明式地表达 CI/CD 流水线

常被称为“流水线即代码”的技术是通过使用代码来定义 CI/CD 流水线的过程。该过程起源于采用声明性技术,结合使用配置文件,并在版本控制系统中使用。声明式地以代码形式表达 CI/CD 流水线的一个优势是能够结合控制、关卡和流程(如治理实践和程序)并在多个环境中一致地应用它们。此外,它还便于建立审计跟踪,使你能够验证治理标准的合规性。最后,通过声明式地以代码形式表达 CI/CD 流水线,你将更好地为灾难恢复(DR)场景做好准备。

定义明确的角色和职责

回顾前面的价值流图步骤,确定每个团队和个人在与之交互时的角色和职责。这是设计 CI/CD 治理模型最有效的方法。请注意,开发人员负责代码开发,而不应该让他们同时负责构建和维护 CI/CD 流水线。这在确定需要向每个需要访问基础系统的团队成员提供的授权级别以及需要采用哪些协议以确保组织的良好治理时将非常有帮助。

定期审查访问和授权控制

管理权限和访问并不容易,但你必须这样做。使用 Azure Active Directory 等身份提供商(IDP),你可以建立一个管理用户身份和权限的权威来源。无论你使用的技术堆栈是什么,都应识别出最有价值的资源,并将其作为基础设施的主要焦点。

为团队提供灵活性

无论你采取多少预防措施,人们仍然会创建自己的工具、脚本和自动化。实施防护措施以避免这种情况,或使人们能够以透明和批准的方式建立自己的工具和实例,是良好 CI/CD 治理的一个重要方面。实现这一目标的最有效方法是为员工提供执行任务所需的自由,并定期进行流程审查,以确定需要额外自由或相反,需要增加正式性的领域。创造性的自由是打造一支对公司充满投入的员工队伍的最佳方式。

大力投资于自动化测试

高效的 CI/CD 治理模型的一个基本要素是结合适当的测试套件,尤其是自动化测试,以帮助团队尽早在软件开发生命周期(SDLC)中左移或优先考虑安全性和功能。我们强烈建议在 SDLC 开始时优先进行快速且经济高效的测试。这类测试必须在非常短的时间内完成——短到工程师不会被激励去换档并在另一个项目上进行多任务处理。如果测试失败,开发团队应立即意识到这一点,以便问题不会被意外忽略或遗忘。随着 SDLC 的成熟,测试要求应变得更为具体。可追溯性是自动化测试实践中另一个关键因素。如果你能够识别出失败点,那么你将处于更有利的位置,能够迅速诊断问题并找到解决方案。

标准化代码审查

实施强大的 CI/CD 治理需要创建一个系统,使个人无法任意编写代码、启动构建过程并在未经额外验证的情况下部署该代码。这意味着每次修改至少必须获得两个人的批准。值得注意的是,并非所有修改都必须获得第二人的批准。在某些情况下,依赖于自动化测试即可提供足够的保证继续前行。无论选择何种策略,必须在组织层面上建立并明确规则,以确保团队遵守统一的实践和流程。目标是提高开发人员识别和解决代码问题的成功率,减少缺陷的引入,并确保符合核心项目规范。结果是,这可以提高开发工作的整体生产力和效率,使团队能够更快地为客户交付卓越的软件。

在部署策略中设置环境规则

应该遵循的核心原则是建立环境一致性,并能够无缝跟踪整个构建、测试和交付层次中的进展。在一个环境中引入条件性而在其他环境中忽略这种做法可能会带来潜在后果,因此要谨慎。保持环境一致性将加快在每个环境中进行软件测试的过程,即使生产环境中存在其他环境所没有的独特条件。

建议使用配置文件的声明性语法将环境视为输入参数。在 CI/CD 流水线中,这是一种成功的方法。将环境参数化为代码有助于确保所有前提条件从开发到发布都得到标准化。此外,由于参数化,CI/CD 系统将更易于维护,从而避免创建过多的流水线。

防止未经授权访问 CI/CD 流水线基础设施

为了防止对系统和代码的未经授权访问,所有参与 CI/CD 流水线的系统必须安全集成。

在所有情况下,应适用最小权限原则。授予用户、工具和服务的访问权限应保持在最低限度。通过这样做,你可以确保组织最私密的信息和系统免受窥探。此外,你必须加密任何私密信息。如果可行,请使用只能一次性使用的临时令牌,并在每个任务完成后自动轮换。

你应该始终使用静态应用程序安全测试(SAST)工具对所有依赖项进行定期安全测试。这些测试应涵盖从 CI/CD 流程到代码库再到底层系统(如容器)的一切。有些工具可以集成到 CI/CD 流水线中,对代码库进行自动扫描以检测任何已知的安全漏洞,并在检测到任何漏洞时通知相关团队。一些例子包括 SonarQube、Fortify、CheckMarx 和 Veracode。

最后,定期进行安全检查。这些审计的目的是为增强组织的整体安全态势提供建议,并记录任何发现,包括任何问题或漏洞。通过保持安全测试的领先地位并保持有条理,你将处于更有利的地位,能够响应组织中的安全事件。

监控 CI/CD 流水线性能

评估 CI/CD 过程性能的关键指标通常包括部署频率、变更前置时间、恢复服务所需时间和变更失败率。测量这些指标可以帮助组织识别 CI/CD 工作流中的潜在瓶颈或低效率。此外,它们还可以用于监控治理政策和程序对向客户部署新代码的影响。

使用 SigNoz、Datadog 或 New Relic 等专用监控工具是一种监控 CI/CD 流水线有效性的方法。尽管这些工具揭示了流水线整体性能中的模式,但仅靠它们还不足以说明全部情况。前面提到的 DORA 指标应被确立用于监控流水线、治理政策和程序的有效性。这些指标提供了可观察的信号,结合起来,可以更完整地描绘流水线和系统整体的健康状况。

定期审查和更新 CI/CD 治理程序

要建立一个有效的审查委员会,建议由来自多个职能领域的人员组成,包括开发、安全、运营和 IT 团队。首先对现行政策和流程进行全面分析,以确定任何缺陷或可改进的领域。然后,召集审查小组,根据其各自的专业领域对现有政策和程序提出意见。接下来,修订现有的政策和程序,以纳入审查小组提供的意见。建议彻底评估所做的修改,以确保其与公司特定要求保持一致。最后,通过有效地向受影响的团队传达细节来执行实施过程。必须系统地监控和评估新实施政策的有效性,并在必要时准备进行修订。

由于 CI/CD 治理和公司最重要的优先事项会随着时间的推移而发生变化,定期审查应成为公司支持其成功的最重要功能之一。有效的 CI/CD 治理可确保所有交付的代码都是高质量的、安全的,并且可以追溯到其来源。

DevOps 发布管理治理的目的是制定政策和程序,帮助确保组织的 CI/CD 流水线基础设施高效、安全,并符合行业标准和法规。在组织层面,公司经常难以实施适当的工具、流程和程序来成功控制其 CI/CD 工作流。这在公司刚刚开始开发治理模型时尤其如此。这一切都归结于规模问题:在企业级别,有更多的人、工具、系统和用户,这使得有效治理更加困难。

然而,当团队遵循既定流程并有效实施 CI/CD 方法时,可以更有信心地确保所有发布的产品都符合必要的标准和质量要求。此外,这些产品还配备了必要的标签,如果需要,将来可以进行追溯。因此,初期投资的重要性变得更加显著。

至此,我们关于 DevOps 发布管理治理的讨论结束。你现在已经熟悉了 OWASP 前十大 CI/CD 安全风险、上市速度与治理的平衡、CI/CD 治理的常见路径、CI/CD 治理的常见障碍以及创建治理模型的要点。

在下一节中,我们将讨论 DevOps 发布管理中一个备受争议且同样重要的方面:分支策略!分支策略经常被忽视,我们将讨论四种最常见的软件开发分支策略的重要性,并学习何时以及如何应用它们。

理解分支策略

大多数现代版本控制系统都支持分支,即从核心代码库派生出的独立工作流。根据具体使用的系统不同,版本控制系统中主分支的命名可能有所不同,例如 master、mainline、default 和 trunk 等。开发人员可以从源代码生成分支,从而使他们能够与源代码一起独立工作。

分支实践促进了开发团队在统一代码库中的无缝协作。当软件开发人员在版本控制系统中创建分支时,会生成代码库的副本,记录代码在特定时间点的状态。对分支所做的修改不会影响团队中的其他开发人员,这种模式无疑是有利的。然而,分支不一定必须独立存在。通过分支,开发人员可以无缝集成其他程序员的更改,以进行协作开发,这可能涉及到各种功能,同时确保他们的分支与主分支保持紧密对齐。

成功实施分支策略将在构建有效的 DevOps 工作流中发挥关键作用。DevOps 发布管理的许多关键目标是提供快速、优化且高效的工作流程,同时确保最终交付物的完整性和卓越性。软件开发团队所采用的分支策略以及如何处理每个新功能、升级或错误修复,应该由精心设计的分支策略来管理。这样做将简化发布过程,让软件工程师一次只专注于单个功能的开发,而不会影响产品的其他部分或干扰其他团队的工作。

选择分支策略

在选择分支策略时,应充分考虑用户的需求和项目的要求。这一选择受到多种因素的影响,包括创建过程的复杂性、项目的规模以及开发人员的偏好。你在 DevOps 流水线中使用的分支策略受不同因素影响,例如 CI/CD 集成的可用性。如果分支策略与 CI/CD 不兼容,或者使其难以建立,那么在以 DevOps 为中心的组织中使用这些策略并不是一个好主意。

定义有效的分支策略可以为开发过程提供一个明确的进程轨迹,从原型修订开始,最终达到生产部署。这种方法使开发人员能够生成有组织的发布工作流。正如前面提到的,拥有明确分支策略的一个关键优势是能够实现并行开发,这种策略可以提高每个开发人员工作流的效率,而不会引入任何显著的阻力。分支策略还可以与许多 DevOps 技术和工作流无缝集成。对于高级团队来说,分支策略还为使用 GitOps 工作流进行部署打开了大门。也许使用分支策略的最明显的优势是其能够促进快速发布周期的能力。总之,在选择适合你的分支策略时,没有一种适用于所有情况的通用方法。

常见的 DevOps 分支策略

现在你对分支策略有了更好的理解,并知道团队使用分支策略的目的,让我们来看一下目前软件工程团队使用的一些流行的分支策略。在本节中,我们将重点介绍当前在 DevOps 发布管理中最常用的四种分支策略:Gitflow、GitHub flow、trunk-based development 和 GitLab Flow。

Gitflow

Gitflow 在有预定发布日期和策划开发周期的项目中最为有效。这种分支策略采用多分支方法来管理源代码。Gitflow 包含两个主要分支,master 和 development,这两个分支在整个开发生命周期中都得到维护。开发分支也被称为长生命周期分支:

  • master:这是保留所有生产代码的主分支。当开发分支中的修改完成后,这些修改将被合并到 master 分支中,并在代码准备好发布时用于部署过程。
  • development:变化、增长和演变都在开发分支中进行。此分支包含所有的预生产源代码,其他分支完成的所有工作将立即合并到 develop 分支中。

image.png

软件开发人员在开发过程中会创建许多不同的分支,以满足各种应用程序需求。开发分支(develop branch)充当初始起点——生成软件产品的基础。

额外的分支也以类似的方式出现。例如,在开发软件时,通常会使用功能分支(feature branches)来更轻松地创建新功能。这些分支直接从开发分支派生,而不是从其他分支派生。

如果出现需要快速解决的紧急生产问题,将会开发热修复(hotfix)作为应对措施。每个分支都有从 master 分支(也称为主分支)派生的能力。这些派生必须同时合并到 master 和 develop 分支中,以确保更改被一致地集成,并避免冲突。为了简化发布到生产的过程,发布分支(release branch)会收集所有最新的错误修复和功能。新分支将是开发分支的子分支,最终会合并到 master 分支中。

Gitflow 的优势在于能够轻松实施不同且专门的分支,每个分支都有特定功能,并通过明确定义的命名系统来实现。这种方法对于管理生产代码的多个迭代特别有利。

Gitflow 的缺点之一是你无法再轻松读取 Git 历史记录。此外,在开发过程中,并不总是需要 master/develop 的分离,这样做在与某些 CI/CD 工具集成时可能会带来挑战。进一步来说,这不适合需要保持只有一个工作版本更新的人。最后,取决于项目的规模,这种方法可能会使源代码控制过于复杂难用。

以下是 Gitflow 的摘要:

  • master 分支 包含已发布的生产代码,并附带标记(tagging)。
  • 仅将热修复和发布分支合并到 master 分支(最好是发布分支)。
  • 将功能分支合并到开发分支。
  • 发布分支只包含错误修复,不包含新功能。如果需要开发新功能,将其合并到开发分支,而不是发布分支。

GitHub Flow

GitHub 是这一策略的发起者,旨在提供一种简单且不引人注目的方法来管理开发过程。当维护单一主分支的源代码时,GitHub Flow 按以下规则管理过程:

  • master 是主分支,其他分支从中分离,新代码也会合并到其中。master 分支中的所有内容(有时也称为主分支)应始终准备好进行部署。
  • 任何修改(无论是功能还是错误修复)都需要在从 master 分支派生的新分支中实现,该分支应有一个描述开发过程的名称。你应该将代码更改提交到本地的功能或错误分支,并定期推送这些新更改。

image.png

一旦功能或错误修复分支的开发完成,你需要创建一个拉取请求(pull request),以便对代码进行评估。在代码经过检查和验证后,需要在同一分支中进行测试,然后才能将其合并回 master 分支。到达此点后,用户应该能够直接部署包含最新更新的 master 分支。

GitHub flow 的优势包括易于理解且工作流程简单明了。此外,这种方法产生的 Git 历史记录干净整洁,易于阅读。你还可以轻松地将其集成到 CI/CD 流水线中。此外,GitHub flow 非常适合只想保留单个生产版本的情况。

GitHub flow 的一些缺点包括它过于简单,并且不适用于基于版本发布的软件开发。此外,GitHub flow 不适合在需要同时维护多个软件版本的情况下使用。此外,如果在将分支合并到 master 分支之前没有彻底测试这些分支,可能会导致不可靠的生产代码。

基于主干的开发(Trunk-Based Development)

在基于主干的开发中,开发人员需要每天至少将他们的代码修改直接集成到共享的主干(master)中。共享主干始终保持在可部署状态,随时可以进行发布。开发人员编写的代码可以在从主干分支拉取后推送到共享主干。

image.png

发布分支被视为源代码的快照,从创建时的时间点提取,且准备好发布。这意味着在基于主干的开发中,发布分支不会被维护。由于这种集成频繁发生,开发人员可以立即监控彼此的代码更改,并在发现任何问题时立即做出反应。

扩展的主干开发

扩展的主干开发是基于主干开发的衍生方法,遵循类似的模式,但设计用于大规模企业级开发团队的易用性。

与基于主干的开发的区别在于,在完成构建并确保功能测试成功后,小型团队可以将他们的更改直接提交到共享主干。另一方面,对于拥有更大团队的组织来说,扩展的主干开发过程可以分割为短期的功能和错误修复分支。在创建功能或错误修复分支后,开发人员将持续向这些特定分支提交代码,并通过拉取请求和自动化测试验证代码,然后再将其合并回共享主干。扩展的主干开发允许开发团队同时做到以下两点:

  • 在不对主分支施加过大压力的情况下实现规模扩展
  • 对每次更改实现更高水平的监管和监督

image.png

值得注意的是,扩展的主干开发利用功能标志(feature flags)来控制在共享主干中进行的开发活动,当需要进行发布时尤其如此。借助这些功能标志,开发团队可以在构建过程中有选择地激活或禁用部分代码,并将仅需的代码发送到生产环境。通过这种方法,团队可以直接从主干发布,并为每次提交标记一个发布编号。特别地,如果一个错误进入了发布版本,则可以从过去的提交中生成一个发布分支,并将修复内容挑选并合并到该分支中。这种分支风格最适合具有源代码管理经验的专家开发团队。

主干开发的一些优势包括以最纯粹的形式使用持续集成(CI),开发人员不断保持主干的最新状态。主干开发是包括更简单的工作流程以便于自动化测试的 CI/CD 流水线的绝佳选择。此外,主干开发减少了周期时间并加快了开发人员的反馈速度。因此,代码的修改更容易显现出来。对于较少的迭代,它们使团队更容易监控所有更改,同时降低代码冲突的风险并提高整体代码质量。

然而,主干开发的一些缺点在于开发人员直接与共享主干(master)一起工作。对于没有经验的开发人员来说,这种技术可能会令人望而生畏。此外,功能标志管理不当可能会带来挑战。另一个缺点是它增加了产生错误的风险,因为在每次合并时不会进行回归测试。此外,这种分支策略要求开发团队在合并之前等待更改通过测试流程和自动构建。值得注意的是,从更传统的方法(如 GitHub flow)转换过来可能会比较困难。

总体而言,主干开发促进了协作、敏捷性和高质量软件的快速交付。你可以轻松地实施稳固的 CI 文化,并利用功能开关的优势。此外,通过遵循这种方法,你将能够更有效地响应客户请求,并拥有更容易管理和随着时间改进的源代码。无论你的团队规模或项目的复杂性如何,使用主干开发都可以增强团队合作,加快上市时间,并改善编码实践。

GitLab Flow

GitLab Flow 将功能驱动开发和功能分支的原则与问题跟踪的利用融合在一起。这种方法与 GitHub flow 方法类似,但与其他工作流程不同的是,这种特定的流包括一个独特的生产分支,用于管理部署到生产服务器的代码。此外,建议建立一个预生产、预发布或发布分支,作为你的预发布环境的代表,在部署前可以在此进行最终测试。换句话说,你至少需要三个主分支:

  • master:这是所有人用于本地开发环境的分支。
  • staging:这是生产前的最终测试环境,master 分支会被集成到这里。
  • production:代码从 staging 合并到 production 分支,通常通过标记来实现。如果不使用 staging,那么合并就会从 master 开始。

image.png

如前所述,在 GitLab Flow 的背景下,软件开发过程在三个不同的环境分支中进行。这些分支作为指定的空间,用于验证和测试代码。一旦代码经过必要的审查并被认为合适,它将被合并到其他分支中,从 master 分支开始。这种迭代合并过程一直持续到代码最终到达生产分支,标志着它已准备好进行部署。让我们来详细看看环境中提到的这三个分支的细节。

master 环境 是所有开发活动的主要场所。开发人员为他们当前正在处理的特定功能或错误修复建立独立的分支,然后将这些分支集成到 master(主)分支中。随后,这些新的代码更改将接受进一步的评估和自动化测试。一旦新的功能和错误修复准备好发布,源代码将从 master 分支合并到预生产(staging)分支,这是生产的初始阶段。然后,这些代码将进行进一步的测试,最终被合并到生产分支中进行部署。

生产 是指创建商品或服务的过程。一旦集成了准备好生产的代码,就可以将此分支直接部署到生产环境中。这是专门为这个特定环境设置的分支,其中包含的代码已经过彻底测试并被认为适合部署到生产环境中。

GitLab Flow 的一个优势在于,实施 GitLab 确保了不同开发环境之间的有效分离,保证了每个分支的干净状态。此外,软件无缝集成到 CI/CD 流水线中。简而言之,GitLab Flow 通过优化 DevOps 生态系统内的工作流程,增强了 GitHub flow 方法。GitLab Flow 的另一个好处是 Git 历史记录更容易访问且视觉上更有条理。

GitLab Flow 的一个缺点是需要协调多个环境分支的额外工作,这可能使实施变得困难。如果管理不善,开发分叉可能会变得混乱。由于其灵活性,你必须仔细考虑如何使用它,这使得它比其他方法更复杂一些。确保团队中的每个人都了解你希望使用的可选分支。

GitLab 是 Gitflow 和 GitHub flow 之间的一个优秀且成熟的折中方案,因为它比 Gitflow 简单,但比 GitHub flow 更全面。凭借其可选分支,GitLab 足够灵活,可以满足你的独特需求,并且在 CI 环境中表现良好。GitLab 在其文档中为 GitLab Flow 提供了一套全面的说明,涵盖了从重置仓库到撰写有效提交消息的所有内容。无论你的团队选择哪种方法,通读一遍这些说明都是个好主意。

如何选择你的分支策略

到目前为止提到的所有分支策略都经过测试和验证,是管理源代码的好选择。然而,每种方法都有其独特的优点和缺点,在进行评估之前不应盲目选择某一种策略。

例如,在 DevOps 过程不断演变的环境中,标准的 Gitflow 可能不是最佳选择。这里介绍的其他解决方案都在努力改进 Gitflow,并使其现代化,以便与敏捷的 DevOps 过程兼容。因此,和往常一样,你需要决定一个理想的策略,以适应你的所有需求,并适用于你独特业务的操作。在做出这一决定时,考虑客户、公司和团队的需求是非常重要的。

分支策略的最终目标是将每个团队成员对代码库的更改组织和协调成一个单一的发布版本。然而,协调所有这些更改不仅仅涉及编写代码。例如,新的发布必须以某种方式部署,这就是发布流水线的作用。

探索发布流水线

发布流水线是一种工作流或一系列步骤,旨在确保最近交付的代码能够快速实施。基本上,一个构建良好的发布流水线可以使代码的生产部署变得快速、简便且可靠。

发布流水线的具体阶段因组织和产品而异,但它们通常是线性依次进行的。值得注意的是,较复杂的流水线设计可能包括可以并行执行的步骤。由于并行处理提供的战略优势,以及当代工具的进步使得实现这种功能变得更加容易,因此这种趋势在近年来变得越来越流行,且不需要大量脚本编写。

通常,发布是由事件触发的,比如代码提交,但在某些情况下,发布可能是显式启动的或预先安排的。你可能还希望将流水线的执行自动化,直到特定的里程碑(例如预生产测试结束),然后手动授权实际部署到生产环境中。例如,在监管严格的行业中,可能需要将手动触发器作为完成条件,即使流水线过程是自动启动的。

通常来说,在团队的交付策略组合中拥有一个合适的发布流水线意味着每周部署一次与每天多次部署之间的区别。但是,发布流水线在 CI、CD 和持续部署之间的光谱中位于何处?要回答这个问题,我们必须了解发布流水线的所有组成部分,包括支持它的相关基础设施。以下部分将详细概述发布流水线的各个元素。

任务

任务是指在详细级别上完成的特定活动。在发布流水线的背景下,阶段中的任务顺序对于整个过程的成功完成应具有较少或没有影响。在控制流程时,使用阶段作为关卡,任务则是在其中执行的活动。

至少,你的发布流水线必须包括以下任务:

  • 配置基础设施:这指的是分配和配置必要的资源,以建立和运行各种应用程序和服务。这可能需要为测试目的创建新的虚拟环境,或验证测试环境的正确配置,甚至安装和激活必要的服务,例如 Web 服务器。
  • 应用程序部署:这是发布过程,需要获取打包的软件并将其部署到指定的服务器基础设施中,同时根据需要实施特定环境的配置调整。
  • 软件测试:这指的是执行自动化测试并传播相应的结果。此外,必须提供将某个阶段指定为不成功的能力,以防测试执行产生不利结果。
  • 解除基础设施:无论结果如何,在完成流水线阶段后都应进行此操作。团队常常利用 Kubernetes 集群在不可变的容器实例中操作短暂的流水线阶段。这种策略的关键优势在于,容器实例在完成分配的任务后能够优雅地终止所有未保存的资源。

在发布流水线中,某些任务可能需要异步方法,这要求流水线能够适应各种相关情况,例如这里提到的情况。例如,考虑一个需要在云中创建服务器实例的应用程序发布流水线。在基础设施配置的开始和随后应用程序的部署或测试之间的这段时间内,有必要允许大约 1 分钟的间隔期。这段时间窗口对于充分准备环境以执行发布流水线的后续任务至关重要,从而避免竞态条件。

制品库

代码更改通常启动发布过程,最终形成提供的基础设施和交付的软件制品。在此过程中,可能需要通过使打包的软件适应相关环境的需求来进行调整,然后进行部署。因此,制品库是发布过程的基础,例如 jFrog Artifactory 或 Sonatype Nexus Repository Manager。

制品库的要求是促进离散制品版本的管理。关键是确保与单个构建和后续发布相关的制品既是不可分割的,也是独立于其他发布的,不存在任何形式的混杂或连带干扰。

在过去,实现这一目标是通过建立一个专门用于构建和发布过程的网络共享来完成的。在这个共享中,每个构建都分配一个独立的文件夹以确保组织的一致性。在发布管理中,无论选择哪种方法(无论是使用数据库,采用特定方法,甚至是选择将所有数据存储在对象存储中,例如 S3 存储桶或 Azure Blob 存储),制品的持久性都是至关重要的。

配置库

另一方面,配置库是存储各种值的存储库,这些值在各种构建/发布配置中提供一致性。例如,CI/CD 过程和应用程序的构建配置数据可能会作为一组键/值对保存在配置库中。通常,这些配对会作为环境变量或输入参数注入到构建环境中,尽管也可以包括作业完成的信息。这些值通常包括关键元素,如连接字符串、API URL、特定环境的用户、权限等。

发布流水线还需要能够在流水线的每个对应阶段中提取特定环境所需的配置。一旦提取出配置,便应使用它来促进配置和部署过程。值得注意的是,通过使用适当的值引用相同的参数,可以使流水线代码具有可重用性,具体取决于环境。需要强调的是,即使配置库仅限于基础设施的详细信息,最终它也将包含部分生产配置。因此,配置库必须通过强大的安全措施和加密协议来加固。

日志记录

在 DevOps 中,人们本能地理解,如果在执行流水线时出现问题,至关重要的是检查日志,以确切查明问题的来源并找出障碍的根本原因。市场上有几种流行的日志聚合工具,其中一些包括 Splunk、ELK Stack 和 Loggly。在一个由众多动态组件组成的复杂系统中,强烈建议建立一种机制,以有效聚合日志,从而提高意识并加快分析速度。

为了确保适当的文档记录,所有日志条目至少应附有应用程序名称、流水线阶段、构建编号和时间戳。在满足这些要求后,你使用任何其他方法来表示日志条目完全是主观的。最基本的系统可能只是将它们全部汇总在一起并使其可搜索,但更高级的构建流水线系统将为你提供流水线执行的图形表示,并能够深入查看它们生成的日志。

工作流执行

工作流引擎可以将通常由 IT 驱动的手动工作流转化为由人类和软件共同管理的流程。这使得信息流的路由和定向、任务的分配以及协作渠道的建立成为可能,以优化资源的利用。这个过程的底层机制因具体实现而异,但流程的执行是必不可少的。无论是涉及复杂的 bash 脚本还是托管工作流引擎(如 Jenkins),任务都必须以逻辑、组织良好的方式执行。

部署与发布的区别

此时,你可能会想知道部署流水线和发布流水线之间的区别,因为这两个术语经常被互换使用。然而,部署和发布确实是独特的!部署是指软件从一个受控环境向另一个受控环境的过渡。另一方面,发布是指为最终用户提供的一组精选的软件更改。

以下是部署和发布之间的一些关键区别:

  • 软件发布是在生产环境中交付的一组更改,而部署是将构建的代码从一个受控环境迁移到另一个受控环境。
  • 通常,发布会频繁更新生产环境。相反,部署是 SDLC 的最后阶段,在所有环境中执行。
  • 从统计上讲,发布更容易让最终用户暴露于存在漏洞的版本、错误和问题中。相反,部署发生在生产环境和开发环境中,用户永远不会看到这些环境。
  • 发布代码可能尚未准备好进入生产,而部署代码已准备好进入生产。
  • 软件发布是用户可见的,而部署可以在基础设施内的任何目标环境中运行。

换句话说,业务理由是区分部署和发布的决定性特征。通常,发布管理倾向于成为一种以业务为导向的活动,而不仅仅是纯粹的技术活动。通常,安排发布的决策背后的理由受到业务战略的影响,尤其是在收入生成和产品组合管理方面。

考虑到涉及的各种环境,显而易见的是,部署并不一定意味着用户将能够访问已实施的功能。某些组织可能会将他们的发布与生产的部署阶段同时安排,而其他组织则会选择等待公司做出最终决定。这意味着新功能可能已获准在生产中发布,但直到以后部署时才会向用户开放。

此时,你已经了解了拥有合理分支策略的重要性。一个适合团队工作流的良好分支策略使你能够逻辑地组织大量软件更改,从而使创建新版本变得更加简单。你还探讨了什么是发布流水线以及如何实现它。然而,在这些更改同时发生时,如何以理智的方式管理它们?展示团队辛勤工作的最佳方式是什么?答案是拥有合理的变更管理实践。

理解变更管理

数字服务遵循一个必须管理的生命周期,大多数组织通过一套专门的变更管理流程来实现这一点。这些行动通常作为减轻变更可能对操作和安全产生潜在负面影响的第一道防线。

为了促进系统中变更的实施,变更管理方法通常涉及从外部审查者或变更控制委员会(CCB)获得批准。合规经理和安全经理在验证合规性要求时严重依赖变更管理流程,以证明实体的合规性。这就是为什么你必须基于详细记录维护所有变更的汇总日志,以明确证明你的构建和发布过程,以及其他任何合规要求。最值得注意的是,许多行业监管要求通常要求提供证据,证明所做的任何修改都经过了正式授权,并包含它们发生的时间戳。

根据 2019 年发布的《DevOps 状态报告》的发现,实施变更批准的最有效方法是在开发过程中通过同行评审进行。这种方法应通过自动化加以强化,以便在 SDLC 早期检测、避免和修复不良变更。持续测试、CI、严格的监督、强大的可观察性和补充策略提供了早期和自动化检测、增强的可见性和快速反馈。此外,公司可以通过更好地沟通当前已建立的流程,并帮助团队轻松导航这些流程来提高绩效。高管们应该亲自去了解实际工作的情况,理解过程,询问问题,并学习。

当所有团队成员对变更审批流程有全面的操作意识时,绩效会更高。接下来,我们将讨论如何务实地实施以 DevOps 为中心的变更审批流程。

实施变更审批流程

减少与变更实施相关的风险,并满足监管机构规定的要求,是遵循变更审批流程的两个最重要的原因。职责分离是一项常见的多行业监管要求,规定对流程的任何更改必须由不是该流程原始创建者的个人批准。这确保了没有人可以完全控制整个流程。

实现这些结果的传统方法是将拟议的变更提交给一个外部小组以供批准,例如变更控制委员会(CCB)或变更咨询委员会(CAB)。然而,DevOps 研究与评估组发布的研究表明,这些方法对软件部署速度产生了负面影响。此外,数据并不支持正式的外部审查程序可以降低变更失败率的观点。这些繁琐的方法增加了生产系统暴露于风险的机会,从而提高了变更的失败率,因为它们减慢了交付过程,并导致开发人员不那么频繁地发布更大的工作批次。DevOps 研究与评估组对数据的分析证实了这一理论的有效性。

相反,团队应专注于角色分离,这可以通过使用同行评审来实现。此外,管理软件开发的平台应用于记录审查、评论和批准。此外,你还应该利用自动化、持续测试、CI、监控和可观察性,以便能够快速发现、避免和修正任何不良变更。最后,将你的开发平台视为一种产品,正确使用时,它可以使开发人员快速获得有关其更改在安全性、性能、稳定性以及缺陷等各方面影响的反馈。

你的目标应该是使你的标准变更管理程序足够快速可靠,以便在紧急情况下使用。在这一新视角下,CCB 或 CAB 仍在持续交付范式中扮演重要角色,这包括简化团队沟通与协作的过程。此外,CCB 应促进团队通过流程改进活动(如举办内部黑客马拉松)来增强软件交付绩效。最后,领导层应就需要在市场速度与业务风险之间、或在获得组织高层支持之间取得平衡的战略业务决策提供意见。

CCB 的新定位是战略性的。将详细的代码审查工作委托给从业人员,并实施自动化流程,使领导和管理角色中的个人能够将他们的时间和注意力分配到更具战略意义的事务上。领先的软件交付组织的策略反映了从守门人到流程架构师和信息灯塔的这一转变。

实施变更审批的障碍

过于依赖 CCB 来纠正缺陷和批准变更是当今最常见的错误之一。选择通过 CCB 进行监督通常会导致额外的等待和不幸的沟通问题。虽然 CCB 在传播有关变更的信息方面确实有效,但许多跨越不同时间区域的团队可能会无意中对新变更或政策的重要性产生误解。另一个常见的错误是企业在批准流程中过于草率。这意味着当所有变更都受到统一的审批流程时,变更审查的效率低下,导致个人无法为那些由于风险特征或截止日期不同而需要专注考虑的变更分配足够的时间和注意力。

另一个公司常犯的错误是缺乏对持续改进项目的投资。为了提高变更管理流程的绩效,必须专注于关键绩效指标,例如交付时间和变更失败率。这需要为团队提供适当的工具和培训,以帮助他们有效地导航流程。

image.png

最后,添加不必要的流程是许多公司常犯的一个错误。通常情况下,企业在软件制造阶段遇到稳定性问题时,会实施额外的程序和更严格的授权协议。现实分析表明,采用这种技术最有可能会使情况恶化,因为它对交付时间和批量大小的影响,从而产生一个负反馈循环。与其承诺增加这些流程,不如将资源分配到逐步提高变更过程的效率和安全性上,但要将两者视为密不可分的。

改进变更审批流程的方法

要改进变更审批流程,重点是实施自动化测试并使用同行评审流程来评估所有在提交之前的修改。另一个改进变更审批流程的方法是开发自动检测问题的方法,包括在代码更改提交后尽早发现回归问题、性能问题和安全漏洞。此外,定期进行分析,识别并突出高风险变更,并在发现任何问题时立即进行进一步调查。

此外,实施将验证步骤移到开发平台上的方法也是一种良好的实践。这有助于团队研究整个变更过程,寻找瓶颈并识别潜在的解决方案。与其将安全规则的手动检查作为软件交付过程的一部分,不如在平台和基础设施层以及开发工具链中实施这些规则。

根据 2019 年《DevOps 状态报告》中的研究结果,提高软件交付性能的一个简单方法是更好地沟通现有流程,并帮助团队有效地导航这些流程。这可以对软件交付性能产生积极影响,尽管最终目标是摆脱传统的、正式的变更管理流程。当团队中的每个人都清楚地了解必须遵循的程序,以便获得变更实施的批准时,就可以实现卓越的绩效。这意味着他们能够自信地在最短的时间内通过审批流程获得变更,并且他们清楚了解通常提交的各种类型变更所需的流程。

总结

这标志着第八章的结束。阅读并理解本章内容后,你现在应该在脑海中形成了一个可靠的蓝图,以便在开始进行有关治理、分支策略、发布流水线和变更管理的开发和实施时可以参考。

正如你所看到的,通过构建你的 CI/CD 基础设施,使其能够自动执行这些原则,你可以最大限度地减少人为错误和倦怠的风险。对于这一点不应掉以轻心,因为我们不是在取代或削弱组织中的治理、分支策略、发布流水线和变更管理,而是将它们融入整体。这意味着这些职责仍然必须像以前一样得到彻底实施和执行,但通过可以在你的 CI/CD 流水线配置中实施的各种监督机制来实现。

在下一章中,我们将讨论你可以用来在组织的发布管理策略中培养 DevOps 文化的有效策略。