模拟 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。

    1. kubectl label ns app admission-webhook=enabled
    1. kubectl apply -f sidecar-template.yaml
    2. kubectl apply -f sidecar.yaml

    jvm-chaos-demo 是一个简单的 Spring Boot 应用,此处作为被测应用。被测应用定义在 example/jvm/app.yaml 中,内容如下:

    1. kind: Deployment
    2. metadata:
    3. name: springboot-jvmchaos-demo
    4. namespace: app
    5. spec:
    6. replicas: 1
    7. selector:
    8. matchLabels:
    9. app: springboot-jvmchaos-demo
    10. template:
    11. metadata:
    12. annotations:
    13. admission-webhook.chaos-mesh.org/request: jvmchaos-sidecar
    14. creationTimestamp: null
    15. labels:
    16. app: springboot-jvmchaos-demo
    17. spec:
    18. - image: 'gallardot/chaosmesh-jvmchaos-sample:latest'
    19. imagePullPolicy: IfNotPresent
    20. name: springboot-jvmchaos-demo

    其中值为 admission-webhook.chaos-mesh.org/request: jvmchaos-sidecarannotation 与步骤 1 sidecar.yamlConfigMap 的名称对应。

    建立应用 Deployment:

    执行 kubectl -n app get pods,预期能够观察到命名空间 app 中出现 1 个名称形如 springboot-jvmchaos-demo-777d94c5b9-7t7l2 的 Pod,等待其 READY1/1 后进行下一步。

      预期结果如下:

      1. NAME READY STATUS RESTARTS AGE
      2. springboot-jvmchaos-demo-777d94c5b9-7t7l2 1/1 Running 0 21s

      在注入前你可以先观测应用 jvm-chaos-demo 未被注入时的行为,例如:

      1. kubectl -n app port-forward pod/springboot-jvmchaos-demo-777d94c5b9-7t7l2 8080:8080

      在另外一个 shell session 中使用 curl 或者直接使用浏览器访问 http://localhost:8080/hello,预期返回 Hello firend

      指定返回值的 JVMChaos 内容如下:

      1. apiVersion: chaos-mesh.org/v1alpha1
      2. kind: JVMChaos
      3. metadata:
      4. name: jvm-return-example
      5. spec:
      6. action: return
      7. target: jvm
      8. flags:
      9. value: 'hello chaos mesh!'
      10. matchers:
      11. classname: 'org.chaosmesh.jvm.Application'
      12. methodname: 'hello'
      13. mode: one
      14. selector:
      15. labelSelectors:
      16. app: springboot-jvmchaos-demo

      JVMChaos 将 hello 方法的返回值修改为字符串 hello chaos mesh!

      注入指定返回值的 JVMChaos:

      1. kubectl apply -f ./jvm-return-example.yaml

      使用 curl 或者直接使用浏览器访问 ,预期返回 hello chaos mesh!

      1. hello chaos mesh!

      关于 action 的取值的含义,可参考:

      名称含义
      delay指定方法调用延迟
      return修改返回值
      script编写 groovy 和 java 实现场景
      cfljava 进程 CPU 使用率满载
      oom内存溢出,支持堆、栈、metaspace 区溢出
      ccf填充 jvm code cache
      tce抛自定义异常场景
      cpf连接池满
      tde抛方法声明中的第一个异常
      tpf线程池满

      关于传递给 chaosblade-exec-jvm 的参数,Chaos Mesh 会将 flagsmatchers 中的所有字段合并后作为请求体发送给 ,具体可参考 chaosblade-exec-jvm/协议篇