前言
chaosblade是一个混沌实验实施工具,其组件可以大致分为两部分:
1)白屏控制台:chaosblade-box和chaosblade-box-agent;
2)黑屏命令行:chaosblade,blade命令行工具,对于不同实验类型底层依赖众多组件,如k8s实验依赖chaosblade-operator,jvm实验依赖chaosblade-exec-jvm;
由于官方文档比较匮乏,而chaosblade组件众多,遇到问题难以定位,也难以入手做改造,所以看源码的方式了解一下细节。
本章基于chaosblade-1.7.4版本分析chaosblade黑屏命令行的实现原理。
后续将分析chaosblade-box白屏控制台,chaosblade-exec-jvm和jvm-sandbox。
一、项目结构
1、构建产物
1)blade:chaosblade-io/chaosblade主项目构建产物,Go编写,命令行工具,为混沌实验提供统一入口,管理所有混沌实验;
2)bin/lib/yaml:chaosblade子项目构建产物
2-1)bin,可执行程序,如chaos_os,由chaosblade-io/chaosblade-exec-os构建,Go编写,命令行工具,封装了基础资源故障场景,支持的组件包括 CPU、内存、网络等;
2-2)lib,复杂的可执行程序,对目录相对路径有一定要求,如sandbox由chaosblade-io/chaosblade-exec-jvm构建,Java编写,基于jvm-sandbox,通过javaagent做故障注入;
2-3)yaml,不同子项目提供的描述文件,blade通过解析yaml匹配需要执行的实验。
如chaosblade-exec-os提供chaosblade-os-spec-1.7.4.yaml,blade通过解析得到cpu满载实验和其相关参数。
2、构建脚本
chaosblade通过Makefile构建:
1)pre_build:创建目录等操作;
2)cli:构建chaosblade主项目;
3)os~kubernetes:构建子项目;
4)package:打压缩包;
主要看子项目构建,以os为例:
1)如果target/cache目录下不存在os子项目,则git clone下载;
2)git pull更新目标分支;
3)make编译chaosblade-exec-os;
4)将构建产物分别放入bin目录和yaml目录;
通过修改project和branch可以指向自己的仓库进行定制开发。
3、工程结构
chaosblade主项目分为三个模块:
1)cli:blade命令入口,cli/cmd子目录对应blade子命令,如prepare、create、status;
2)data:数据存储模块,chaosblade使用****sqlite存储实验数据,experiment表对应create,preparation表对应prepare;
3)exec:底层命令执行模块,比如os执行chaos_os;
4、小总结
chaosblade命令行集成了n个子项目对于混沌实验场景的实现,通过blade命令统一管理,用sqlite本地存储实验状态。
二、os实验-cpu满载
1、案例
通过create子命令创建cpu满载实验。
plain
代码解读
复制代码
root@service-e:/opt/chaosblade# ./blade create cpu fullload {"code":200,"success":true,"result":"b0ad36cdedce219c"}
通过status子命令查询实验信息。
plain
代码解读
复制代码
root@service-e:/opt/chaosblade# ./blade status --type=create { "code": 200, "success": true, "result": [ { "Uid": "b0ad36cdedce219c", "Command": "cpu", "SubCommand": "fullload", "Flag": "", "Status": "Success", "Error": "" } ] }
通过top命令查看cpu使用率。
通过destroy子命令删除实验,需要指定实验唯一id。
plain
代码解读
复制代码
root@service-e:/opt/chaosblade# ./blade destroy b0ad36cdedce219c {"code":200,"success":true,"result":{"target":"cpu","action":"fullload","ActionProcessHang":false}}
2、create-创建实验
cli/cmd/create.go#actionRunEFunc:当匹配到create子命令,执行actionRunEFunc定义的回调方法。
Step1,创建实验模型ExpModel,一个普通对象。
target=cpu,actionCommandSpec.Name=fullload,cmd包含执行参数。
Step2,实验模型持久化到sqlite。
在持久化到db前,由blade侧生成uid。
首次获取db连接,会创建两张表(preparation和experiment),数据文件存储在blade命令行所在目录chaosblade.dat文件。
experiment实验记录如下,如设置cpu负载为60%。
Step3,blade根据cpu和fulllload找底层实验实现执行。
exec/os/executor.go:blade实际调用底层chaos_os命令,启动chaos_os进程消耗cpu。
plain
代码解读
复制代码
root@service-e:/opt/chaosblade# ps -efww | grep chaos_os root 680 1 99 01:39 pts/0 00:00:53 /opt/chaosblade/bin/chaos_os /opt/chaosblade/bin/chaos_os create cpu fullload --uid=9eb0176ff57ba279 --cpu-percent=60
exec/cpu/cpu.go:245:chaos_os侧开启cpu数量个协程执行死循环,main线程根据当前系统cpu使用率,调整协程死循环速率。
exec/cpu/cpu.go:333:chaos_os每个gorouting做死循环。
Step4,根据执行情况,更新实验记录。
如果命令执行失败,更新实验记录Error。
如果命令执行成功,校验chaos_os进程是否存在(response.Result是pid)。
如果存在,更新实验记录Success,否则更新Error。
3、status-查询实验
cli/cmd/status.go:71:可根据type类型或根据uid查询实验。
如果type=create/destroy,查询experiment表;如果type=prepare/revoke,查询preparation表。
4、destroy-销毁实验
cli/cmd/destroy.go:70:Step1,根据uid查询实验。
cli/cmd/destroy.go:142:Step2,根据实验模型找到os命令执行器。
cli/cmd/destroy.go:200:Step3,blade执行chaos_os命令,如果执行成功更新实验记录为Destroyed,否则不变。
chaos_os命令如:
</