持续交付的发布工程最佳实践

3a6538a43ef53b11ccdba3f512e7ef1e.png

什么是发布工程?

发布工程是软件工程中一个新兴且发展迅速的学科。它为应用程序开发制定了标准,并严格遵循以确保产品发布时的可靠性。发布工程师精通多个学科,例如源代码管理、配置管理、开发流程和客户支持。发布工程是一个根据产品需求而形成的灵活流程。


发布工程的开发指南是什么?

这是发布工程流程定义的第一部分,其中列出了开发人员必须遵循的所有准则。

分支模型

本条款规定在开发过程中必须遵循适当的 git-flow 分支模型。从长远来看,创建和维护 Git 分支是合理且经济实惠的。下面列出了每个分支关于使用 git-flow 分支模型的相应指南。

Main 主分支

源代码主分支代表生产就绪状态。它包含最稳定的代码,并将部署到生产中。主分支正式保留任何软件应用程序源代码的发布历史记录。主分支上的所有提交都必须标有版本号。开发人员不应直接向主分支提交任何内容。未经 QA 团队批准,不应将代码合并到主分支中。

Develop 开发分支

我们的工作流程将使用两个分支来记录项目历史,而不是单个主分支。开发分支是集成各种功能分支的分支。开发人员和维护人员都有权将功能分支与开发分支合并。在将分支合并到开发中时,开发人员应简要描述他们在该分支上开发的功能。

Feature功能分支

功能分支是开发分支的子分支,也就是说,功能分支不是从主分支分支出来的,而是作为其父分支来开发的。使用功能分支,开发人员可以同时开发多个功能。一旦设计和测试了新功能,功能分支就会合并到开发分支中。

  1. 应用程序的每个新功能的代码都应驻留在其特定的功能分支中,该分支可以推送到中央源代码存储库以进行备份和协作。

  2. 所有功能分支都应该只存在于开发人员的存储库中,而不是原点中。

  3. 功能分支永远不会与主分支交互或直接合并到主分支。当某个功能完成后,其相应分支总会合并回开发分支。

UAT 分支

用户验收测试是预生产分支,也称为暂存区。一旦在开发分支中开发并测试了代码,它就会合并到 UAT 分支中。

  1. UAT 分支应该被锁定,这样开发人员就不能直接向此分支提交代码。只有维护者才有权接受 UAT 分支中的合并/拉取请求。

  2. 完成所有测试后,UAT 分支应创建一个发布分支。UAT 中的错误修复不应直接合并到 UAT 分支中;所有错误修复分支都应先合并到开发分支中。

Release 发布分支

发布分支将派生自 UAT 分支。创建此分支是为了启动下一个发布周期,它表示在此之后不能添加任何新功能 - 只能在此分支中完成文档、错误修复和其他与发布相关的任务。源代码标记和发布版本控制也在这里完成。代码发布后,发布分支将合并到主分支中。它也标有版本号。此外,它应该合并回开发分支,该分支可能自发布启动以来已经取得了进展。

Hotfix/Bugfix 修复/错误修复分支

热修复分支,也称为维护分支,用于快速修补生产版本。当生产环境中出现一些错误时,会从主分支派生出错误修复分支。一旦错误被修复,热修复分支就会合并到主分支和开发分支中。然后是正在进行的发布分支,然后主分支会标记更新的版本号。


分支命名约定

本条款规定,下面提到的每个分支都必须遵循正确的命名约定。分支名称只能包含小写字母、连字符、斜杠和数字,正则表达式:/[a-z0-9-]+/。

Feature 功能分支

命名功能分支时,可以使用斜线或连字符作为分隔符,但请确保功能分支命名是同质的;不要混合使用多个功能分支命名约定。在开展项目之前,请确定一个命名约定并坚持使用。

  1. feature/*

  2. feature/gitlab-integration

  3. feature/ticket_id

  4. feature-*

  5. feature-slack-integration

Release 发布分支
release-*

release-1.0.0

热修复分支
  1. hotfix/*

  2. hotfix/broken-link


合并流程

开发人员应该遵循适当的合并流程/请求和发布分支流程。

为了确保合并顺利进行,在执行合并之前需要进行几个准备步骤。在将代码合并到任何分支之前,请使用简短的描述。

  1. 确认目标分支

  2. 获取最新的远程提交

  3. 应用合并

feature/branch_name → develop → UAT→ Release→ Master

发布分支是指将发布驻留在特定分支中的概念。当团队开始开发新版本(例如“版本 2.1”)时,将创建一个分支,在下一个版本存储在此分支中之前,所有工作都已完成。

Git 提交指南

本条款规定了Git Commit的准则 。当您在小组项目上工作或为开源项目做贡献时,提交消息是向该项目上的其他开发人员以及您未来的自己传达变更上下文的最佳方式。

但大多数时候,开发人员并不关注提交信息。他们使用奇怪的提交信息,这些信息对任何人都没有帮助,而且这些信息无法传达所做的更改以及原因。为了使提交信息有意义,开发人员必须遵循以下准则。提交信息应简短且具有描述性;尽量不要超过 50 个字符(最多 72 个字符)

-提交信息应该是必要的。

  1. "Add Dockerfile"

  2. "Added Dockerfile"

-提交信息应该描述为什么进行更改以及如何解决问题。

-在提交信息中将主题大写。

  1. Fix github integration error."

  2. "fix github integration error."

-如果提交涉及问题/错误,请确保在提交消息中添加问题/错误编号。

-使用字符使提交信息简短。

  1. "Add Hindi & English translation."

  2. "Add hindi and english translation."

  • 主题行不应以句号结尾。

  1. “Add new Dockerfile.”

  2. “add new Dockerfile.”


发布工程的 CI/CD 指南是什么?

这是发布工程流程定义的第二部分,其中列出了发布工程师必须遵守的所有准则。

CI/CD 阶段

上述第 I 部分中提到的每个分支都应有一个严格由下面提到的阶段组成的 CI/CD 流水线。

功能/修补程序分支
  1. Unit Testing

  2. Integration Testing

  3. Build

  4. Push

  5. Deploy code (if required)

开发分支
  1. Code Quality Check

  2. Unit Testing

  3. Integration Testing

  4. Functional Testing

  5. Build

  6. Push

  7. Deploy to Dev

UAT 分支
  1. SAST

  2. DAST

  3. Browser Performance Testing

  4. Load Testing

  5. Fuzz Testing

  6. Build

  7. Push

  8. Deploy to UAT

发布分支: 此分支不应包含任何管道。此分支仅包含可供发布的代码。仅关注文档、最终润色和代码的小错误修复。 也可以使用发布分支进行CI/CD发布,最终发布验证完成后合并到主分支,这种情况下主分支就不用做CI/CD只作为和生产一致的最新的代码。

主分支:

  1. Build

  2. Push

  3. Deploy to Prod


各阶段定义

  1. 代码质量检查: 这将有助于分析源代码质量,并确保项目代码保持简单、可读且更易于贡献。源代码将自动分析以发现问题,以检查代码质量是否随着最新提交而改善或变差。

  2. 单元测试: 单元测试 是在源代码级别测试离散功能的阶段。这是一种测试,我们测试软件应用程序的单元或组件。单元测试的目的是验证软件代码每个单元的性能。

  3. 集成测试:集成测试阶段用于执行一定程度的软件测试,其中将各个单元/组件集成在一起并作为一个整体进行测试。它揭示了集成单元之间交互中的故障。

  4. 功能测试:功能测试是一种质量保证流程,也是一种黑盒软件测试,用于验证软件系统是否符合功能要求/规范。功能测试的目的是通过提供适当的输入并根据功能要求验证输出来测试软件应用程序的每个功能。很少考虑内部程序结构。

  5. SAST:SAST 代表静态应用程序安全测试。它扫描应用程序源代码和二进制文件以执行静态代码分析,这有助于在应用程序部署之前发现潜在漏洞。每个合并请求都会触发扫描,收集结果并在单个报告中显示漏洞列表。

  6. DAST:动态应用程序安全测试 分析正在运行的 Web 应用程序是否存在已知的运行时漏洞。它引入了增强的安全性,因为它是一种黑盒测试,其中通过前端与 Web 应用程序进行通信,以识别 Web 应用程序中的潜在安全漏洞和架构弱点。

  7. 浏览器性能测试:这是一种 Web 性能测试,我们使用自动浏览器性能测试来确保软件在浏览器中的性能。这将使用开源工具测量网页的性能并创建应作为工件上传的报告。引入此功能是为了提供每个网页的总体性能得分。

  8. 负载测试:负载测试是 CI 流程的重要组成部分。开发人员可以通过测量软件对负载和引入的更改的响应情况,在流程早期做出性能决策,这可以归类为性能测试。

  9. 模糊测试:模糊测试或模糊测试通过提供意外输入(例如某些格式错误或随机的数据生态系统)来衡量应用程序的响应和稳定性。这有助于监控不可预测的行为或应用程序崩溃。模糊测试至关重要,因为它可以发现传统测试方法通常无法发现的问题。它可以让您发现应优先解决的软件缺陷,因为这些缺陷可能会导致高度可利用的漏洞。

  10. 构建:无论使用哪种语言,云原生软件通常都使用 Docker 进行部署。通过结合应用程序的源代码和依赖项,我们产品的可运行实例被构建并交付给最终用户。此 CI/CD 管道阶段将整个代码及其依赖项打包成镜像并构建 Docker 容器。

  11. 推送:这是一个阶段,其中构建的 Docker 映像被推送到我们安全的私人harbor注册中心,并带有相关标签,以便稍后根据要求检索以进行部署。

  12. 部署:这是任何管道的最后阶段,其中应用程序被部署到与分支相关的环境,即 dev、uat 或 prod。


CI/CD 阶段设计的最佳实践

参照上面提到的设计 CI/CD 阶段,必须确保:

  1. 除发布外,每个分支的管道中都应灌输构建和推送阶段,即功能/修补程序、开发、uat 和 master。

  2. 仅当出于测试目的需要时,才应灌输功能/修补程序分支管道中的部署阶段。此外,开发分支中的代码必须部署到专用的开发环境中。同样,UAT 分支中的代码必须部署到 UAT 环境,以供 QA 团队进行手动测试。最终部署到最终用户的生产环境必须在主分支的管道内完成。

  3. 发布分支不能有任何管道,因为它们应该只用于文档和发布的最后润色。(具体情况待定)

  4. 就测试而言,应实施以下准则:

  5. Feature/Hotfix 分支中的管道必须仅进行单元和集成测试。

  6. Develop 分支中的流水线必须包含单元、集成和功能测试。

  7. UAT 分支中的管道必须专用于所有类型的安全和性能测试,即 SAST、DAST、浏览器性能测试、负载测试和模糊测试。

  8. 以上分支测试完成后,主分支中的管道就不需要有任何测试阶段,可以直接部署。


定义环境

本条款规定应该为 DEV、UAT和PROD提供隔离的部署环境。
  1. 必须严格考虑每个环境的隔离,以避免任何冲突点。理想情况下,隔离不同环境的最安全、最可靠的方法是为每个环境使用单独的集群。此选项可最大限度地降低由于潜在的人为错误和机器故障而导致的生产环境风险。然而,这会增加维护和管理开销,降低利用率并增加基础设施管理成本。

  2. 或者,可以使用具有不同命名空间的单个集群来隔离不同的环境。K8s 社区已经发展并成熟了很多,使我们能够通过适当的网络策略、节点选择器、seccomp、访问控制等来解决安全问题。

  3. 不过,为了在生产环境和非生产环境之间实现强有力的分离,我们可以为 DEV + UAT 环境设立一个集群,并为最终生产环境设立一个完全专用于最终生产环境的集群。

因此,最终的选择取决于当时的需要。考虑所有可能的利弊,应实施与用例相关的最佳选项。

根据环境命名约定

本条款规定,访问部署在不同环境中的应用程序时应遵循适当的命名约定。

假设正在开发一个主机名为“example.com”的应用程序。因此,必须确保:

  1. 在 DEV 环境中部署的应用程序的主机名应该是dev.example.com。

  2. 在 UAT 环境中部署的应用程序的主机名应该是 uat.example.com。

  3. 最终在PROD环境中部署的应用程序的主机名应该是example.com。


制品管理

本条款规定,必须把适当的令人满意的管理放在首位。

DevOps CI/CD 流程中的每个发布  都是必须正确保存和管理的工件集合。工件被称为软件开发的副产品。它被视为应用程序的可部署组件,例如 docker 镜像、jar 文件、wheel 文件等。

  1. 源代码、会议记录、工作流程图、数据模型、风险评估、用例、原型和编译后的应用程序都被视为工件。在规划阶段,必须制定一份清单,涵盖所有需要生成的工件。

  2. 必须确保对 docker 镜像等工件进行稳定的标记,以便正确隔离和轻松识别。标签可能包括项目名称、存储库名称、分支名称、管道 ID 等。

例如:life data/stt-server:develop123456

  1. Artifactory 存储库必须用于存储和管理工件。它旨在存储、版本控制和部署构建的工件。它既是构建所需工件的来源,也是部署构建过程中生成的工件的目标。


如何向最终用户发布您的产品?

产品运送至最终用户

本条款规定了产品交付给最终用户的流程。一旦您的代码准备好交付到实时环境,产品团队必须遵循以下条款,以便顺利将产品发布给最终用户。

  1. 开发人员应按照给定的链接了解 Changelog 文件结构,为每个产品微服务创建 Changelog 文件。

  2. 可供生产的代码还应该包含README文件。

  3. QA 团队应将 QA 签发给开发人员和发布工程师。如果没有 QA 签发,代码就绝不能合并到生产中。

  4. 产品团队应该准备好所有的用户文档和参考文档。

  5. 销售和营销团队在与客户讨论产品功能之前应该对产品有一个基本的了解。

  6. 应该对支持团队进行适当的培训,以解决用户有关产品的任何问题。

  7. 发布工程师应该创建一个清单,并涵盖发布的所有必要事项。

  8. 一旦清单中的所有内容都完成,开发人员必须为发布版本控制和标记创建一个发布分支。

  9. 开发人员在创建标签或发布时应遵循 语义版本控制。

  10. 一旦发布版本控制完成,开发人员应该将该分支合并到生产分支中。


如何选择正确的部署策略?

  1. Recreate 重新创建:版本 A 终止;然后推出版本 B。

  2. Ramped (also known as rolling-update or incremental)渐进式(也称为滚动更新或增量):版本 B 缓慢推出,取代版本 A。

  3. Blue/Green 蓝/绿:版本 B 与版本 A 一起发布,然后流量切换到版本 B。

  4. Canary灰度:版本 B 先向部分用户发布,然后全面推出。

  5. A/B 测试:在特定条件下向子集用户发布版本 B。

  6. Shadow 影子:版本 B 与版本 A 一起接收真实世界的流量,并且不会影响响应。


Recreate 重新创建

此部署策略规定旧 Pod 将一次性全部终止,并替换为新 Pod。此部署方法涉及停机,因为旧版本将被关闭,而最新版本将启动。

情况/注意事项

  1. 您的应用程序不支持多个版本,并且无法承受短时间的停机。

  2. 您已将 ReadWriteOnce 卷安装到您的 Pod,并且您不能与副本共享它。

  3. 您想在启动新应用程序之前停止处理旧数据并运行一些先决条件。

Rolling Update 滚动更新

这是 Kubernetes 中的默认策略,其中新 Pod 通过替换旧 Pod 缓慢推出,而不会导致任何停机。滚动更新不会缩减旧 Pod 的规模,除非它通过就绪探测进行验证并确认新 Pod 已准备就绪。如果出现任何问题,您可以中止滚动更新或部署,而无需关闭整个集群。

滚动更新配置包括:

  1. 最大激增:在所需的 Pod 数量之上可以创建的最大 Pod 数量。

  2. 最大不可用数:更新过程中不可用的 Pod 数

滚动更新策略的好处/注意事项:
  1. 将应用程序/服务发布到开发/登台环境。

  2. 每分钟处理大量事务的应用程序停机可能会导致很多问题。然而,在滚动更新中,应用程序可以继续运行,且停机时间为零。

  3. “跟踪/记录”部署的功能,在回滚时很有用。

Blue-Green  蓝绿色

在这个策略中,应用程序的新旧版本会同时部署。用户只能访问旧版本,新版本会先供 QA 团队测试;测试完成后,用户的流量就会转移到新版本。

它有助于在公开之前测试生产质量环境。与滚动和金丝雀部署方法相比,它还使他们能够一次性将所有用户切换到新闻稿。

蓝绿策略的好处/考虑因素:
  1. 快速回滚和轻松灾难恢复。

  2. 蓝绿部署零停机时间,因此团队可以进行切换,让负载平衡系统自动将所有用户转移到绿色版本。如果出现问题并需要回滚,旧的蓝色版本应用程序已准备就绪并等待。

  3. 开销:运行两个相同的环境成本很高。

Canary 金丝雀

在 Canary 部署策略中,我们将一定比例的用户流量转移到新版本的应用程序。我们主要在对新版本的稳定性没有信心时使用此策略。与蓝/绿部署相比,此应用部署策略的一个主要优势是可以尽早识别错误并得到反馈。它可以在 IT 团队向所有用户推出更新之前发现弱点并改进更新。

金丝雀部署策略的好处/注意事项:
  1. 很高兴尝试新功能并观察当流量路由到新版本时应用程序和系统如何表现。

  2. 只有当您能够跟踪金丝雀部署对您的系统的影响时,金丝雀部署才会对您有帮助。

A/B 测试

A/B 测试 是一种部署策略,在特定条件下将部分用户引导至新功能。它通常是一种基于统计数据而非部署策略做出业务决策的技术。

A/B 测试的好处/注意事项:
  1. 完全控制流量分配,您可以跟踪客户行为和收入结果。

  2. 多个版本并行运行,如果新版本没有提供显著的好处,则很容易恢复到旧版本。

  3. 开销:昂贵的设置

Shadow 阴影

影子部署包括与版本 A 一起发布版本 B、分叉版本 A 的传入请求,并将其发送到版本 B,而不会影响生产流量。这对于测试新功能的生产负载特别有用。当稳定性和性能满足要求时,应用程序就会推出。

影子部署的好处/注意事项:
  1. 它使您无需设置专用的负载测试环境。负载测试基于您现有环境中的实际流量。

  2. 为了获得更高的准确性,可以使用生产流量对应用程序进行性能测试。

  3. 开销:昂贵且复杂的设置(重复的交易或请求)。


什么是回滚?它在发布管理中起什么作用?

回滚是将对象返回到某个先前状态的操作。

如果部署的当前状态不稳定或者由于应用程序代码或配置而未给出预期结果,我们将回滚到早期的部署修订版本。

在某些情况下,即使部署完美,在与新版本集成时应用程序也会停止运行。那时,我们必须借助部署可用的修订版本恢复到运行良好的应用程序版本。

执行回滚时要遵循的步骤:

  1. 首先,找到导致应用程序出现问题的错误原因。可以通过部署(其 pod)的日志和状态进行查看。一些错误参考 CrashLoopBack、ImagePullBackOff 等。

  2. 如果问题无法解决并且需要回滚,我们将遵循回滚流程。

  3. 检查发布历史记录以了解可用的修订。如果在创建部署时使用了—-record 标志,则可以检查更改原因。kubectl rollout history deployment.v1.apps/<deployment-name>

  4. 选择您认为稳定且按预期运行的修订版本,并将其(修订版本)输入到 --to-revision 标志中kubectl rollout undo deployment.v1.apps/<deployment-name> --to-revision=<number-of-the-revision>

  5. 您可以描述回滚的部署并验证其配置。 -kubectl describe deployment nginx-deployment

注意: 默认情况下,Kubernetes 会存储最后 10 个 ReplicaSet。但您可以通过更改 Deployment 文件中的 spec—revision history limit 键来更改要保留的 ReplicaSet 数量。

结论

发布工程是软件工程中一个发展迅速的领域,涉及从开发阶段到成功发布可靠产品的系统化方法。组织必须建立强大的发布工程流程,以快速、高质量地交付产品。

原文链接:https://www.xenonstack.com/blog/release-engineering-best-practices

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值