模拟 JVM 应用故障
JVMChaos 能向目标容器中的 JVM 注入故障,适用于任何使用 JVM 作为运行时的应用。目前 JVMChaos 借助 chaosblade-exec-jvm 实现对 JVM 的错误注入,主要支持以下类型的故障:
- 指定返回值
- 方法延迟
- 抛自定义异常
- 内存溢出
- 填充 JVM Code Cache
- Java 进程 CPU 满载
- 执行任意自定义 Groovy/Java 脚本
目前 Chaos Mesh 使用 修改对 Pod 的定义,通过 Init 容器加载 java agnet,并非运行时加载 java agent。因此在使用时存在如下限制:
- Kubernetes 需要启用 Webhook 支持。
- 在为命名空间配置 MutatingAdmissionWebhook 之前已经存在 Pod,不会受到 JVMChaos 影响。
- 命名空间下的所有容器中的 JVM 都会在启动阶段加载 java agent,JVMChaos 在被删除后也不会卸载 java agent。若考虑到 java agent 可能对程序行为或性能带来的影响,期望清理 java agnet,请将工作负载移出该命名空间。
另外,目前无法通过 Chaos Dashboard 创建 JVMChaos。
下面将以指定返回值为例,展示 JVMChaos 的使用方法与效果。以下内容中涉及的 yaml 文件均可在 中找到,以下步骤默认的工作路径也是在 中。 默认 Chaos Mesh 安装的命名空间为 chaos-testing
。
建立应用所在的命名空间:
为命名空间 app
增加 label admission-webhook=enabled
,允许 Chaos Mesh 的 MutatingAdmissionWebhook 修改该命名空间下的 Pod。
kubectl label ns app admission-webhook=enabled
kubectl apply -f sidecar-template.yaml
kubectl apply -f sidecar.yaml
jvm-chaos-demo 是一个简单的 Spring Boot 应用,此处作为被测应用。被测应用定义在 example/jvm/app.yaml
中,内容如下:
kind: Deployment
metadata:
name: springboot-jvmchaos-demo
namespace: app
spec:
replicas: 1
selector:
matchLabels:
app: springboot-jvmchaos-demo
template:
metadata:
annotations:
admission-webhook.chaos-mesh.org/request: jvmchaos-sidecar
creationTimestamp: null
labels:
app: springboot-jvmchaos-demo
spec:
- image: 'gallardot/chaosmesh-jvmchaos-sample:latest'
imagePullPolicy: IfNotPresent
name: springboot-jvmchaos-demo
其中值为 admission-webhook.chaos-mesh.org/request: jvmchaos-sidecar
的 annotation
与步骤 1 sidecar.yaml
中 ConfigMap
的名称对应。
建立应用 Deployment:
执行 kubectl -n app get pods
,预期能够观察到命名空间 app
中出现 1
个名称形如 springboot-jvmchaos-demo-777d94c5b9-7t7l2
的 Pod,等待其 READY
为 1/1
后进行下一步。
预期结果如下:
NAME READY STATUS RESTARTS AGE
springboot-jvmchaos-demo-777d94c5b9-7t7l2 1/1 Running 0 21s
在注入前你可以先观测应用 jvm-chaos-demo
未被注入时的行为,例如:
kubectl -n app port-forward pod/springboot-jvmchaos-demo-777d94c5b9-7t7l2 8080:8080
在另外一个 shell session 中使用 curl 或者直接使用浏览器访问 http://localhost:8080/hello
,预期返回 Hello firend
:
指定返回值的 JVMChaos 内容如下:
apiVersion: chaos-mesh.org/v1alpha1
kind: JVMChaos
metadata:
name: jvm-return-example
spec:
action: return
target: jvm
flags:
value: 'hello chaos mesh!'
matchers:
classname: 'org.chaosmesh.jvm.Application'
methodname: 'hello'
mode: one
selector:
labelSelectors:
app: springboot-jvmchaos-demo
JVMChaos 将 hello
方法的返回值修改为字符串 hello chaos mesh!
。
注入指定返回值的 JVMChaos:
kubectl apply -f ./jvm-return-example.yaml
使用 curl 或者直接使用浏览器访问 ,预期返回 hello chaos mesh!
:
hello chaos mesh!
关于 action 的取值的含义,可参考:
名称 | 含义 |
---|---|
delay | 指定方法调用延迟 |
return | 修改返回值 |
script | 编写 groovy 和 java 实现场景 |
cfl | java 进程 CPU 使用率满载 |
oom | 内存溢出,支持堆、栈、metaspace 区溢出 |
ccf | 填充 jvm code cache |
tce | 抛自定义异常场景 |
cpf | 连接池满 |
tde | 抛方法声明中的第一个异常 |
tpf | 线程池满 |
关于传递给 chaosblade-exec-jvm
的参数,Chaos Mesh 会将 flags
与 matchers
中的所有字段合并后作为请求体发送给 ,具体可参考 chaosblade-exec-jvm/协议篇。