持续交付是任何软件交付实践的重要组成部分。无论目标部署环境如何,我们都应该设计CD工作流,以便将软件的任何更改投入生产。
对于微服务架构来说同样如此。本文将分享作者Sheroy Marker在架构设计和应用开发中的一些关于CD工作流的思考和经验。
微服务和CD
按照Martin Fowler的说法,微服务架构是“将软件设计一组为可独立部署的服务的方式“。这种方式目前已经成为构建分布式系统/应用的主流;按照Jez Humble的说法,CD(持续交付)是“能够以可持续的方式安全快速地将所有类型的变更 - 包括新功能、配置、错误修复和实验 - 投入生产”。
无论是一体化架构还是微服务架构,无论目标部署环境或我们的架构选择如何,设计好CD工作流程以使我们对应用的任何更改投入生产都很重要。CD工作流程是DevOps流程的核心,能够很好的串联组织中的各种功能,包括开发、QA以及IT运维等等。
微服务架构CD的4项挑战
-
维护复杂分布式系统的完整性:由于我们将大型一体化系统分解成为了更小、更易于管理的微服务,因此系统本身的整体复杂性会增加,我们开始需要处理分布式系统相关的问题;
-
安全快速地发布功能:当我们的功能可能涉及一个或多个微服务的更改时,需要特别考虑一下如何管理频繁的功能发布;
-
管理不同技术堆栈的部署:微服务环境通常包括用于服务的不同技术堆栈,跨技术对战的管理和部署过程很有挑战性;
-
独立部署服务的过程和工具:有许多工具可用于构建CD工作流程,但选择工具、制定CD工作流并不是一件容易的事。
微服务架构CD的5点思考
- 准备好测试策略
跟传统一体化架构应用相比,微服务架构的测试和验证更加细致,也更加复杂。一个有效的测试策略必须同时考虑到测试单个服务和验证整个系统行为的需要。
对于服务的pre-production测试,特别是以隔离的方式测试,传统方法仍然适用。测试金字塔仍然可以帮助我们在不同类型的测试之间保持平衡。但是,在测试服务聚合时,这种测试方式的效果有限。我们会遇到一些在测试环境中无法模拟的错误类别,例如由分布式系统中的最终一致性引起的问题,导致系统部分失败的硬件和网络故障等。
我们最好利用一些技术来作为传统测试的补充,例如synthetic user testing、lightweight user acceptance testing以及fault injection testing等等。
- 检查好CI实践
CI是CD的关键实践。除了构建服务器、构建定义相关的考虑,基于主干的开发和功能切换是实现简单而强大的CI过程的两个关键实践。
在基于主干的开发中,开发人员在一个名为“trunk”的分支中协作。这样做的好处是,避免开发分支的drift和由此产生的merge hell。这与维护长期特征和释放分支的做法相反。在分支模型中,虽然我们可能会在各个分支上运行构建,但事实上,我们没有进行持续集成。
要进行基于主干的开发,需要有称为feature toggles的控件。功能切换支持WIP和已完成功能的组合的多次提交。通过这些切换,我们可以在生产环境中关闭不完整特性的显示,直到这些特性在生产环境中得到充分的开发和测试。特性切换通常存储在靠近代码基的规范或配置文件中,并由CD管道中的自动化程序在特定环境中打开切换。
一旦我们有了维护feature toggles的机制,我们可以使用相同的机制来引入其他类别的toggles,如release toggles(控制对未完成的代码的访问)、Ops toggles(控制生产代码的行为)、permissions toggles(到打开特权用户的特定行为)和experimental toggles(对于多变量测试 - 在使其成为永久性之前接收到的功能的程度)。
- 计划好环境
环境计划包括我们的环境集、它们的预期用途、通过这些环境促进工件的策略以及在这些环境中的toggle状态。
首先,考虑需要什么环境以及它们的预期用例。组织中不同的部门有不同的竞争需求。在创建环境时,我们应该满足所有这些相互竞争的需求。
其次,如果可能的话,考虑使用云基础设施动态创建环境。例如使用Kubernetes的标签功能,可以在飞行测试环境中创建自动化测试,而不是在长期存在的环境。
第三,CD管道会生成许多artifacts,我们应该考虑要存储多少artifacts?我们需要多少repositories等等。
- 管理好配置
应用的配置包括那些每次部署时不尽相同的东西,应该与代码分开存储。那么当我们拥有一组微服务时,应该如何处理配置呢?
一种办法是在Consul或Vault等存储库中集中管理部署配置,在Chef和CD管道中扩展部署配置只会徒增理解难度。
另一种技术是采用标准化分发配置的流程,不管服务的技术对战如何,让服务根据堆栈处理配置。例如,我们通常参考12-factors,避免分发配置文件。
最后,像证书这样的关键部分需要一个治理过程来确保它们得到适当的管理。通常会是手动的过程,但我们需要早点考虑并安排妥当。
- 准备好应对可能的错误
在微服务系统中,多个服务频繁更新,当服务的部署引入不稳定性或bug时,我们怎么办?
回滚,找到故障的根源并尽快修复,在大多数情况下是最好的反应。能够实现回滚的一个先决条件是确保我们能够从热修复分支直接发布到生产。
回滚操作在生产环境中往往非常棘手。在大多数情况下,如果更改不大,并且明白问题其中的缘由,回滚会相对容易些。但如果部署包含了一些不容易理解的更改,例如DB更改,特别是那些涉及到模式的更改,则需要在连续部署中将DB更改与代码更改分开部署,以确保DB更改与早期版本的代码向后兼容。
关于Rainbond
Rainbond(云帮)是"以应用为中心”的开源PaaS, 深度整合基于Kubernetes的容器管理、ServiceMesh微服务架构最佳实践、多类型CI/CD应用构建与交付、多数据中心资源管理等技术, 为用户提供云原生应用全生命周期解决方案,构建应用与基础设施、应用与应用、基础设施与基础设施之间互联互通的生态体系, 满足支撑业务高速发展所需的敏捷开发、高效运维和精益管理需求。