本文将整体介绍字节跳动混沌工程在云原生场景下的实践,主要包括混沌工程背景介绍和发展历程,以及应用韧性增强服务(Application Resilience Enhancement Service,ARES)产品和未来展望。其中将从技术架构、演练流程、核心功能介绍等多个维度,重点展开介绍混沌工程应用韧性增强服务。
微服务拓扑图
随着公有云市场的高速增长和云原生技术的发展,企业用户逐步向云原生架构迁移,系统内的微服务进一步朝着分布式的架构演进,微服务数量呈爆炸式增长,各服务间相互调用关系也变得更为繁杂,这对软件的可靠性提出了更高的要求,而传统的质量工程和软件测试已无法检测出生产环境中的意外故障和性能问题。为了应对愈发复杂的实际生产问题,混沌工程应运而生,它可以帮助用户提前检测出生产环境中可能潜在的故障和性能问题。
混沌工程是一套通过在系统基础设施上进行实验,主动找出系统中脆弱环节的方法学。通过实验性的方法,发现系统中潜在的、可以导致灾难性故障、或让用户受损的薄弱环节,并推动研发自主地进行问题修复、代码优化,最终建设成为真正意义上的韧性架构,增加用户抵御突发事件的能力与信心。
混沌工程最早由 Netflix 在 2008 年开始实践,通过实践,Netflix 总结出来混沌工程五大基本原则:
传统的测试或者 QA 通常包括以下环节:
然而这些传统的测试只能覆盖一些应用层面的内容,并不能解决异常场景下更为复杂的问题,如:网络发生延迟时,服务是否能够正常工作;服务器宕机时,系统是否能够切换到备份等。面对上述问题,混沌工程提供系统应对故障、从故障中恢复的能力,帮助我们预先发现潜在风险。
混沌工程通常通过注入故障来模拟实验场景,虽然混沌工程、故障注入和故障测试在侧重点和工具集的使用上有一些重叠,但是混沌工程和故障注入本质上是不同的思维方式。
混沌工程在字节跳动的实践主要包括三个阶段:
上面讲了字节跳动混沌工程发展的三个阶段,三个阶段实现能力总结如下:
应用韧性增强服务( Application Resilience Enhancement Service,简称 ARES)是一款遵循混沌工程实验原理并融合了内部多年业务实践的产品。应用韧性增强服务提供丰富故障场景,能够帮助分布式系统提升容错性和可恢复性,增强系统和应用的韧性,满足用户对系统和应用的高可用需求。
下面将主要介绍 ARES 如何进行落地和实现,以及相关的技术突破。
演练流程可以总结为准备实验、实验编排、开始实验、执行实验、故障结果分析、优化系统六大步骤,下面具体介绍下每个步骤:
上图主要列了产品的主要功能,支持实验配置、实验流程编排、故障观测、实验报告与风险统计、演练活动、高可用演练方案、个人工作台等几大功能。
随着服务规越来越大,单个 Kubernetes 集群支撑的节点数有限,并且用户通常会将控制面和数据面进行分离等,把服务部署在多个集群上。因此,混沌工程云原生产品支持了多集群同时演练的能力,还支持异地多活演练。并支持多集群统一管理,可以动态增删多个指定 Kubernetes 集群,如下图所示。
分布式服务和场景越来越复杂,有些用户服务已通过完成云原生容器化部署和编排,而有些用户只有部分通过实现云原生改造,部分服务还在虚拟机上。由于服务的特殊性和改造成本,有一大部分用户仍通过物理机或者虚拟机运行服务。针对用户的复杂使用场景和需求,产品支持了多场景的演练。
如上图所示,ARES 既支持应用服务的演练,也支持基础设施自身的高可用演练,适用于以下多种场景:
通过故障场景的细分,我们可以精准地控制故障的爆炸半径,同时我们也支持在数量、比例上进行精确的配置,能够按照全部、随机指定个数、指定数量、一定百分比四种模式进行目标选择。
上图是 WebShell 管理的部分截图,通常用户注入故障后,故障的有效性和指标,或者产生的日志,需要登录机器查看和操作。平台支持通过 WebShell 管理集群服务的 Pod、Node 节点,并查看对应的日志信息。可以快速验证故障是否生效,方便定位问题。
当前支持的故障能力类型如上图所示,主要支持网络、Pod、系统、主机、DNS、Kubernetes、进程、接口、Java、Python、Golang、中间件、自定义故障等几大故障类型,并且故障类型会持续不断地丰富。
在网络服务演练中,根据用户不同需求和不同场景,用户可以选择在服务的上游或者下游方向进行注入。
通过演练流程探索系统的稳定性和缺陷,在提供了核心的故障模拟能力与指标分析能力之后,可以通过演练流程将故障、指标分析、串行或并行执行。
演练流程具备相对固定的步骤:演练开始阶段通过系统指令或对硬件设备进行人为干预注入干扰;演练进行中,观察并收集各类指标的实时变化;演练结束后,分析对比收集的各类指标,评估系统的状态变化。
上图主要展示故障验证的监护流程图,对故障的管控主要分为两个部分:
向系统中注入故障后,我们采用AI算法,观测分析故障是否生效。理论上,我们可以通过对同一个环境注入故障和不注入故障之间的系统差异来观测故障注入的效果。但事实上,我们不能同时既注入故障,又不注入故障,所以我们无法真实的观测到这个差异。因此,我们引入因果推断算法,通过构造贝叶斯结构化时间序列模型,预测反事实条件下(没有故障注入)的时间序列,并与注入故障后实际观测到的时间序列比较,计算注入故障对系统的累计因果效应,从而判断故障是否生效。
上图中竖直的黑色虚线表示故障注入的时刻,紫色的阴影部分表示蓝色虚线的置信区间
上图从上到下分别展示为:
如上图为注入内存故障后,内存使用的数据。在 观测 页面查看当前实验场景的运行结果。目标 Pod 的 Memory 负载在故障注入的一分钟时间内,到达了预设故障参数值 70% 。实验结束后可以恢复到正常状态。
在混沌工程的实验里面,可观测能力是非常重要的一环,而监控指标的获取和接入是可观测能力里面比较基础的功能。
混沌工程的系统本身不会做过多的监控能力,但为了获取到混沌实验观测中所需要的指标,需要有一个适配层来接入用户的监控系统,以及获取监控系统的监控指标。而用户所使用的监控系统是多样的,因此适配层会适配多种主流的监控系统,并转化成混沌平台上的指标语义。
在 ARES 产品中,用户可以在平台上提前配置好想要观测的指标,提供指标的类型,名称,所属的监控系统类型(如prometheus,zabbix,skywalking等),指标 URL 等。配置完成过后,该指标可以在平台的稳态观测,指标分析等能力中进行使用。而由于不同监控系统的指标语义有所差异,ARES也会将不同语义的指标进行转换,统一为平台侧的语义,方便进一步的处理和展示。
“围绕稳态行为进行假设” ,是混沌工程的重要原则之一,也是混沌工程实验和普通的故障注入,故障演练的重要区别。
稳态观测的功能是 ARES 里面对混沌工程原则进行产品化落地的重要实践,通过对实验的稳态观测,使用户的每一次混沌演练都有比较明确的,可以量化的实验结果。
关于稳态假设的一些概念,我们这样定义:
通过稳态假设的能力,我们把传统的故障注入和故障演练的场景进一步提升,向着混沌工程的理念更进一步,使得故障演练能得到更加直观的实验结果。
权限管理是 ARES 作为云产品的基本能力之一。同一个主账户下,不同子账户可能是不同的业务部门,不同部门的服务可能会运行在不同集群,也可能同集群下相同的 namespace。为了防止各业务账户故障注入互相影响,我们设计了一套权限管理体系,抽象出 role,permission,resource 等概念,进行权限管理。
基于以上设定,我们提供了权限配置,权限继承等能力,使得管理员可以方便地对不同账户,不同资源进行管理。
故障插件为用户提供了更加高级,灵活的能力。顾名思义,在故障注入的前,中,后三个阶段,我们提供了钩子,用户可以在这三个阶段执行自定义的脚本,使故障实验更加丰富。
工作台大盘以数据可视化大盘的形式,为用户提供了高频实验故障,高频实验集群,实验场景执行统计等实验执行的数据分析和统计的功能。通过大盘,用户可以直观,快速的了解到工作空间内的实验执行情况。
混沌工程是个漫长的探索之旅,故障的模拟和注入只是其中的一部分,我们的最终目标是要通过故障注入实验,提前发现系统的薄弱环节,降低事故影响,提升系统韧性。基于目前发现的问题和不足之处,我们从多个方面讨论未来的期望:
演练可观测:当前平台已经具备了演练的能力,然而在演练的过程中,难以及时地对故障和演练进行观察,包括故障的生命周期,相关的服务状态,主机状态,爆炸半径等。未来平台将进一步优化演练的可观测能力,融入AI能力,能实现对服务拓扑的感知,让用户在演练的时候实时的看到整个服务集群的调用拓扑,以及故障注入前后的拓扑变化。
韧性智能分析当前平台主要半自动对故障结果和效果进行分析。未来通过不同维度和不同程度的实验,对实验的结果进行数据分析,结合AI智能判断,评估出系统的韧性度等级和脆弱点,智能生成演练场景,并梳理出系统优化方案,推荐用户进行下次演练,形成演练闭环,增强用户抵御线上真实突发故障的信心。
更好的安全性和故障能力:如 eBPF 内核技术等新的技术能力,给故障实现带来更多的可能性,能给我们带来更加精细化,更加安全,性能更好的故障注入能力。
未来我们将探索更多的故障能力,探索内核,硬件级别的故障。当前业界混沌工程还处在不断持续探索阶段,混沌工程的核心理念尚未体现,因此不断探索、完善混沌工程,任重而道远,欢迎大家和我们交流,一起努力共建。
|