ShardingSphere Proxy 作为重要的数据库基础设施,系统整体的韧性至关重要。混沌工程是测试和验证韧性的有效方法。ShardingSphere on Cloud 项目正在设计和实现名为 Chaos 的新 CRD 来支持自定义的混沌测试,预计在 0.3.0 中发布,敬请期待!
为方便社区的小伙伴更加理解 Chaos CRD 的特点,本文将从混沌工程的概念和实践原理简要介绍,欢迎对 ShardingSphere on Cloud 项目感兴趣的小伙伴们深度阅读。
系统可用性是衡量一个系统正确地对外提供服务(可工作)的能力,在实际生产中有很多方法来保证系统可用性:韧性工程、反脆弱等。混沌工程也是一种实践,通过系统故障来学习提高系统可用性的方法。
混沌工程在 [1] 的定义如下 : 混沌工程是在系统上进行实验的学科, 目的是提升系统抵御生产环境中失控条件的能力以及增加信心。换言之:混沌工程是一种实践,它的目的是发现生产环境的弱点,并提升应对故障的能力,从而提高系统的健壮性。
为什么需要混沌工程
线性与非线性是表现系统复杂度的一种方式,反映了系统输入的变化会如何影响系统输出的变化。对于一个线性系统来说,它通常是可预测的。线性系统在自然界中有很多实例,像是简单的数学函数和物理定义。对于一个非线性系统来说,它的输出并不是能通过计算准确得出的。对于一个庞大的分布式程序而言,系统中的组件互相发生作用,我们并不能确定它在各种输入下都能有预期的输出。
目前大多数的程序是趋于复杂化的。在常见的云环境下,各种组件的协调越来越复杂(如 Kubernetes,还有运行在它之上的服务,如 Istio,Envoy 和各种其它软件基础设施)。
由于系统的复杂性和经常更改的特点,这导致不同设施的开发人员对整体系统的认识可能存在片面性。比如,对于一个商城系统来说,开发商城业务的开发人员并不清楚他们所依赖的基础设施的技术细节。随着系统复杂性的增加,任何个人对系统所建模型的准确度都会迅速下降,所以完整地理解一个复杂系统是不现实的。
混沌用来描述复杂系统未知的状态,它是复杂系统所固有的。混沌工程就是用来发现系统中固有的混沌,学习系统的行为,在故障出现时应对故障并使系统恢复到稳态的能力。
混沌工程的准则与实践方式
建立关于稳态环境的假说
每个实验都始于一个假说,通常会有如此的表现形式:“即使在_____情况下,系统依然处在稳态下”。该原则强调围绕稳态定义来建立假说,所以我们应该根据对生产环境长期行为的监控,定义系统在正常情况的各种指标作为稳态,并关注可测量输出,而不是聚焦于系统的内部属性。
在定义稳态时,常常要关系的是系统的全局性输出,类似于运行日志、性能日志、告警、程序的行为等,并将它们抽象成稳态条件。在引入实验变量(故障)后,这些稳态条件应该按我们的预想发生变化。在系统处于我们定义的稳态时,我们应该认为系统是可以正常对外提供服务的。此外,对稳态的监控也很重要,以便系统能在短时间内恢复到稳态。
多样化地引入现实世界的事件
我们应该引入真实的、我们关心的事件。可以尝试复现曾经生产环境中出现过的故障,如缓存失效、服务降级等。不应该引入会引发相同故障表现的行为:比如占用服务实例全部的内存、CPU、磁盘,或者“杀死”实例。这些事件会引发的结果是该实例无法响应请求。测试时应该专注于引发故障后的系统行为,而不是考虑怎么引发故障。
在生产环境中进行实验
在进行实验时,我们可以学习系统的相关行为,并对系统建立信心。如果在测试环境中进行实验,我们只能建立对该测试环境的信心。如果生产环境和测试环境有不同的地方,那么我们并不能对生产环境建立信心。因为复杂系统是一个整体,环境的不同所带来的影响有可能就像“长鞭效应”一样,使在测试环境进行的实验失去意义。但是在生产环境中进行实验可能会影响使用该系统的用户,进而引发损失。我们需要在正式环境下进行取舍,可以让实验工具在准生产环境下发展成熟后,再将实验路由到生产环境中的一小部分流量中。
自动化实验
当需要测试的实验集非常多时:相比于人工创建实验环境,对于注入故障,收集结果这个过程来说,自动化实验可以省去人工执行步骤的时间,并且持续进行,覆盖更多的实验集。
需要重复进行实验时:随着软件的迭代,之前实验的假设并不是一直为真的,它可能会在某次软件迭代中失效,应该进行回归实验,定期进行实验来证实假说。
最小化爆炸半径
安全的实验方式可以降低实验在生产环境中造成影响的风险。比如使用影子流量、在某个合适的时间段进行实验。因为与一个较小的对照组相比,一个较小的变量组的指标通常都是显而易见的。
混沌成熟度模型
混沌成熟度模型提供了模型地图,可以在这个地图根据所处的位置来评估不同的混沌工程实践。
该模型地图有两个坐标轴,分别是采用度和复杂性,这两方面都可以独立探索:
采用度( X 轴)
随着混沌工程整个学科的成熟,最终软件会在策略上要求自己达到混沌工程的特定水平。仅凭健壮性的验证就能对合规过程产生重大影响。但是在达到这种程度之前,对混沌工程的"采用"一般都是从零开始的。
复杂性( Y 轴)
复杂性有几种表现形式:提供咨询性服务与提供一组工具。
由于软件基础设施的多样化,以至于不存在一个工具,能够在所有的环境抽象出复杂的混沌工程实验用例并加以实现。所以,混沌工程实践始于大量的人力投入,并逐渐发展定制化的解决方案。
理解混沌工程复杂性的另一种方法是考虑那些引入实验变量的系统层级。实验通常始于基础设施层。在混沌实验开始时,通常会使用杀死 Pod 或者虚拟机的方式进行,随着工具的复杂性越来越高,后期可能会在目标系统中加入混沌的判断逻辑,进而影响服务间的请求。
除此之外,当实验变量影响业务逻辑时,我们会看到更复杂的实验,例如,给服务返回可行但出乎意料的请求响应,程序就可能产生不一样的结果。实验在系统层级上发展的自然过程,会从基础设施层发展到应用程序层,从应用程序层发展到业务逻辑层。更进一步地会关注于细粒度的实验,偏向于引发一些业务逻辑上可能导致故障的实验。
持续验证
持续验证是对软件进行主动实验的一门学科,被实现为验证系统行为的工具——Casey Rosenthal
进行持续验证开发的工具可以被视作前文提到的混沌成熟度模型中复杂性的一个表现形式。与 CI/CD 一样,CV(持续验证)源于对运维日益复杂的系统的需求。组织没有时间或其他资源来验证系统的内部计划是否如预期所示,因此只好确认系统的输出是否符合预期,这是验证优于确认的地方,也是复杂系统成功管理的标志。对于持续验证来说,应该至少有三种类别:性能测试,数据制品和正确性。
性能测试:顺着性能的多个表现(并发性,延迟偏差,执行速率等),基于对实际生产流量的观测,建立对此次测试的报告和认知;
数据制品:数据库和存储应用对写入和检索数据的特性有很多要求,比如事务的一致性、幂等性、不正确的数据隔离级别等;
正确性:并不是所有正确的形式都表现为某种状态或理想属性。在某些情况下,一个组件与各个不同组件的交互必须通过接口契约或者约定。当一个接口请求返回了一个看似正确但是在它判断逻辑之外的结果,可能就会引发意想不到的错误。发生这种问题的原因是,不同级别的代码在逻辑的层面的是一致的,但是各层之间不一致。
开源的混沌平台
Litmus Chaos 项目 [2] 是一个具有跨云支持的云原生混沌工程框架。它是 CNCF 的一个开源项目,被多个组织采用。它的使命是通过提供完整的混沌工程框架和相关的混沌实验,帮助 Kubernetes SRE 和开发人员找到非 Kubernetes 以及在 Kubernetes 上运行的平台和应用程序中的弱点。
Chaos Mesh 项目 [3] 是 PingCAP 开源的混沌平台。提供丰富的故障模拟类型,具有强大的故障场景编排能力,方便用户在开发测试中以及生产环境中模拟现实世界中可能出现的各类异常,帮助用户发现系统潜在的问题。Chaos Mesh 提供完善的可视化操作,旨在降低用户进行混沌工程的门槛。用户可以方便地在 Web UI 界面上设计自己的混沌场景,以及监控混沌实验的运行状态。Chaos Mesh 基于 Kubenetes CRD 构建,主要包含三个组件:
Chaos Dashboard:Chaos Mesh 的可视化平台,提供了一套用户友好的 WebUI 界面,可以可视化的进行 Chaos 的创建,监控,和对 RABC 权限的控制
Chaos Controller Manager:Chaos Mesh 的核心逻辑组件,负责调度用户创建的 Chaos CR,这个组件包含多个 CRD Controller,例如 PodChaos Controller,WorkerFlow Controller 等控制组件。
Chaos Daemon:Chaos Mesh 的主要执行组件,Chaos Daemon 以 DaemonSet 的方式运行,默认拥有 Privileged 权限(可以关闭)。该组件主要通过侵入目标 Pod Namespace 的方式干扰具体的网络设备、文件系统、内核等。
💡注:Chaos Blade 项目 [4] 是阿里巴巴 2019 年开源的混沌工程项目,包含混沌工程实验工具 Chaos Blade 和混沌工程平台 Chaos Blade Box ,旨在通过混沌工程帮助企业解决云原生过程中高可用问题。实验工具 Chaos Blade 支持 3 大系统平台,4 种编程语言应用,共涉及 200 多的实验场景,3000 多个实验参数,可以精细化地控制实验范围。混沌工程平台 Chaos Blade Box 支持实验工具托管,除已托管 Chaos Blade 外,还支持聚合 Litmus Chaos 等其他平台的实验工具。
总结
当针对于某个系统引入混沌工程时,我们可以参考混沌成熟度模型,先从简单的投入开始。以类“红蓝对抗”的方式:约定一个日期,集合系统中各个组件的开发人员一起来进行故障测试,记录结果,提高混沌工程对于工作人员的参与感和重要性。之后观测系统行为,定义稳态,然后设计合理的混沌实验方案。在准生产环境或者生产环境进行实验。发现和学习系统的新行为,提高团队应对故障的能力。然后设计将实验自动化,以回归实验的方式确保实验假说的正确性。
参考链接
[1] https://principleofchaos.org
[2] https://litmuschaos.io
[3] https://chaos-mesh.org/
[4] https://chaosblade.io/