暑期2021优秀学生的评选已经正式启动了,期待今年闪耀的新星!
开源之夏公众号持续欢迎大家分享项目经验,开源心得!
本期分享来自ChaosBlade社区的罗荣周同学带来的项目经验:chaosblade-box支持演练工具 chaos-mesh
投稿方式:
E-mail :summer@iscas.ac.cn
or 关注本公众号,后台回复“投稿”。



首先对项目进行分析。chaosblade-box 是一个由 Spring Boot 构建的项目,前端使用了 React 框架,是一个典型的 Java web 项目。整个项目采用 maven 多模块化工程,并采用策略设计模式,使用注解标识行为,用户自己可以扩展一些模块。由于项目已经实现了 chaosblade 和 litmuschaos 云原生混沌实验的场景解析和演练执行器,我只需要仿照实现 chaos-mesh 即可,代码主要逻辑结构和代码风格与其保持一致。
实现场景解析模块,其目的是将各种混沌实验场景导入到数据库中,在前端可视化展示,供用户选择要执行的实验。混沌实验场景必须包含实验名称、实验介绍以及需要填写的实验参数等必要信息。
chaosblade 和 litmuschaos 场景解析的实现方法是读取实验场景 yaml 文件,解析其内容。由于这两个工具的实验场景文件格式比较简单,尤其是实验参数部分,是一维的列表,容易读取和解析。而 chaos-mesh 没有原生的实验场景文件,只能去项目源码和 CRD 定义文件分析实验场景。我所要完成的工作有两个难点,一是 chaos-mesh 的实验参数并不是一维的列表,它们存在嵌套的关系;二是 chaos-mesh 的实验参数有使用条件,不同的实验场景使用不同的参数组合,参数之间也可能存在一些关联。因此,如果编写统一的解析器,想从 CRD 文件读取参数是非常困难的,还不利于后续的扩展,只能靠人工解析实验参数,再写成易于读取的 yaml 文件。
chaos-mesh 每一类混沌实验都有自己的 CRD 结构体,包含了多种实验动作,不同动作以action
字段区分。因此,我首先根据 chaos-mesh 的项目源码以及 CRD 定义的 yaml 文件分析出所有实验动作,写成场景列表文件 category.yaml
,导入之后如下图所示展示在 Web 页面。

然后具体分析各种实验场景所需要的参数,这里还需要参考 chaos-mesh 的官方网站的用户文档。分析完每一种实验场景所需要的参数后,下一步手动构建实验场景 chaosmesh-action-spec-2.0.0.yaml
文件。该 yaml 文件由实验场景列表组成,每一个实验场景包含了场景名称以及一维的实验参数列表,实验场景对应了 Java 代码中的类型 ParamSet
。这里的参数是一维列表,便于解析,参数的嵌套关系体现在了参数命名结构上,命名为如 delay.reorder.correlation 的形式,后续可以构建成为有嵌套关系的参数对象,进而构建混沌实验的 CRD 结构体。导入实验场景后,将实验的详细信息展示在如下图所示的 Web 页面。

演练执行器模块,其目的是执行与中止混沌实验。在云原生的场景下,混沌实验是由 Kubernetes CRD (Custom Resource Definition) 构建,其中 chaos-mesh 每一类实验对应一个 CRD 结构,想要执行某一个混沌实验,只需创建对应的 CRD 资源即可。
本项目使用了 Kubernetes client-java 来进行 CRD 资源的创建。由于 chaos-mesh 的每一类混沌实验都有对应的 CRD 结构,因此在 Java 代码中也要创建对应的类型,这里参照了 chaos-mesh 的源码的 CRD 类型。
创建 chaos-mesh 混沌实验的难点在于如何由一维的实验参数列表来构建 CRD 对象。这里我创建了工具类 ChaosBodyBuilder,用来构建 CRD 的 spec
对象。首先将实验参数列表转换成 Properties 对象,再使用第三方库将其转换成 JSON 字符串,最终转换成 Java 对象。对于 JSON 字符串,需要进行字符串的处理,例如将列表型参数内容的引号去除,以便于进一步转换 Java 对象。前端所传入的参数除了所填的实验参数外,还包含了 Pod 列表和 Container 列表,用于构建 chaos-mesh 的实验范围字段。
构建完 CRD 对象后,使用
createNamespacedCustomObjectAsync
函数来创建CRD资源,执行混沌实验,这里的命名空间需要提前在环境中创建。中止混沌实验,使用
deleteNamespacedCustomObjectAsync
函数来删除对应的CRD资源。

这里通过一个具体的混沌实验 chaosmesh.container-network.delay 来说明整个流程。由命名可知,该实验的实验范围是容器,实验的类别是网络资源,实验的动作是网络延迟。这里对 chaos-mesh 提供的一个小应用 web-show 进行实验,它以图形化的界面动态展示了容器的实时网络延迟情况。
可以看到,在执行混沌实验之前,容器的网络延迟是相对比较稳定的。

在实验场景列表中选择实验 chaosmesh.container-network.delay 并填入合适的实验参数。我们设定延迟的时间长度 delay.latency 为 30ms,延迟时间的时间长度与前一次延迟时长的相关性 delay.correlation 为 0.5,延迟时间的变化范围 delay.jitter 为 2ms。除了必填项外,其它的实验参数可以不用填写。

填写完毕实验参数后,可以创建实验并执行,可以看见显示实验执行成功,意味着对应的 CRD 资源已经创建完毕。

执行混沌实验后,观察容器的网络延迟,发现实验现象符合我们的预期。

点击中止演练,实验成功停止,此时 CRD 资源已经被删除成功,实验进行完毕。

再次查看容器的网络延迟,发现已经恢复了正常。






