- 云原生
- 运维
- 可观测性
【免费下载链接】litmus
Litmus helps SREs and developers practice chaos engineering in a Cloud-native way. Chaos experiments are published at the ChaosHub (https://hub.litmuschaos.io). Community notes is at https://hackmd.io/a4Zu_sH4TZGeih-xCimi3Q
在 Litmus 混沌工程体系中,每一次实验的运行状态与最终判定并不写在 ChaosEngine 或 ChaosExperiment 里,而是由一个名为ChaosResult的独立自定义资源承载。本文以官方文档 chaos-result/contents.md 为核心,系统讲解 ChaosResult 的spec与status字段规范、探针状态记录方式,并结合仓库中的 CRD 定义、Go 订阅器与前端 TypeScript 模型,说明这份结果数据在 Litmus 控制平面中如何被采集与消费。读完本文,你将能完整读懂任意一次混沌实验的 ChaosResult 输出,并据此定位实验失败环节。
一、ChaosResult 是什么
ChaosResult 是 Litmus 实验执行链路中的"结果载体"。官方文档对其定位概括为:
Hold engine reference, experiment state, verdict (on complete), salient application/result attributes, sources for metrics collection.
即它保存了四类关键信息:实验关联的引擎引用(engine reference)、实验运行状态(experiment state)、完成时的最终判定(verdict)、被攻击应用的属性与指标采集来源(salient application/result attributes)。
从仓库中的 CRD 定义可以看到它的资源形态:
- 定义位置:litmus-portal-crds.yml
- API Group:
litmuschaos.io,版本v1alpha1 - Kind:
ChaosResult,复数形式chaosresults,单数形式chaosresult - Scope:
Namespaced(命名空间级资源) spec与status均以x-kubernetes-preserve-unknown-fields: true保留字段,保证向后兼容
每次实验运行结束后,会生成一个以<engineName>-<experimentName>命名的 ChaosResult 实例。例如执行engine-nginx引擎下的pod-delete实验,对应的结果对象名为engine-nginx-pod-delete。
按照官方文档,ChaosResult 的字段体系分为三大部分:
| 字段分组 | 作用 | 详细说明 |
|---|---|---|
| Spec Specification | 定义 ChaosResult 的 spec 细节 | spec-specification.md |
| Status Specification | 定义 ChaosResult 的 status 细节 | status-specification.md |
| Probe Specification | 定义 ChaosResult 中探针组件的结果细节 | probe-specification.md |
下文逐一展开。
二、spec 规范:引擎与实验的关联标识
ChaosResult 的spec只做一件事:标记本次结果属于哪个引擎、哪个实验。规范定义于 spec-specification.md。
| 字段 | 类型 | 说明 |
|---|---|---|
.spec.engine | string | 记录本次实验所属 ChaosEngine 的名称 |
.spec.experiment | string | 记录注入故障的 ChaosExperiment 名称 |
.spec.engine:保存当前实验流程所使用的 ChaosEngine 名称,是关联引擎的"指针"。.spec.experiment:保存执行故障注入的 ChaosExperiment 名称,是关联实验定义的"指针"。
官方文档给出的完整示例(一个典型的pod-delete结果对象):
Name: engine-nginx-pod-delete Namespace: default Labels: app.kubernetes.io/component=experiment-job app.kubernetes.io/part-of=litmus app.kubernetes.io/version=1.13.8 chaosUID=aa0a0084-f20f-4294-a879-d6df9aba6f9b controller-uid=6943c955-0154-4542-8745-de991eb47c61 job-name=pod-delete-w4p5op name=engine-nginx-pod-delete Annotations: <none> API Version: litmuschaos.io/v1alpha1 Kind: ChaosResult Metadata: Creation Timestamp: 2021-09-29T13:28:59Z Generation: 6 Resource Version: 66788 Self Link: /apis/litmuschaos.io/v1alpha1/namespaces/default/chaosresults/engine-nginx-pod-delete UID: fe7f01c8-8118-4761-8ff9-0a87824d863f Spec: # name of the chaosengine Engine: engine-nginx # name of the chaosexperiment Experiment: pod-delete Status: Experiment Status: Fail Step: N/A Phase: Completed Probe Success Percentage: 100 Verdict: Pass History: Failed Runs: 1 Passed Runs: 1 Stopped Runs: 0 Targets: Chaos Status: targeted Kind: deployment Name: hello Events: <none>注意示例中的两个细节:一是对象标签中带有job-name=pod-delete-w4p5op,说明该结果对象由实验 Job 创建;二是Spec区块只有Engine与Experiment两个字段,status才是承载运行信息的核心区域。
三、status 规范(上):experimentStatus 实验状态
status.experimentStatus记录了实验运行期与收尾期的核心状态,规范定义于 status-specification.md,共四个字段:
| 字段 | 类型 | 取值范围 | 说明 |
|---|---|---|---|
.status.experimentStatus.failStep | string | n/a | 实验失败的具体步骤,便于快速定位失败环节 |
.status.experimentStatus.phase | string | Awaited、Running、Completed、Aborted | 实验当前所处阶段,随执行推进而更新 |
.status.experimentStatus.probeSuccessPercentage | int | 1 到 100 | 探针成功率,即成功校验次数与总探针数的比值 |
.status.experimentStatus.verdict | string | Awaited、Pass、Fail、Stopped | 实验最终判定 |
逐字段解读:
- failStep:标记实验在哪一步失败,是排障的第一入口。若实验未失败则为
N/A。 - phase:实验阶段的实时状态。正常情况下按
Awaited → Running → Completed推进;若实验被中止,则为Aborted。 - probeSuccessPercentage:探针成功率的百分比评分。例如总共 1 个探针全部通过则为
100。它是 Litmus 判定实验质量的重要量化指标。 - verdict:最终判定。实验进行中为
Awaited;结束后依据探针与内置检查的结果收敛为Pass或Fail;实验被手动停止时为Stopped。
官方文档示例(节选):
Status: Experiment Status: # step on which experiment fails Fail Step: N/A # phase of the chaos result Phase: Completed # Success Percentage of the litmus probes Probe Success Percentage: 100 # Verdict of the chaos result Verdict: Pass四、status 规范(下):history 结果历史与目标信息
status.history记录该 ChaosResult 对象维度的累计运行统计与被攻击目标信息。字段如下:
| 字段 | 类型 | 取值范围 | 说明 |
|---|---|---|---|
.status.history.passedRuns | int | 任意非负整数 | 累计通过(Pass)的运行次数 |
.status.history.failedRuns | int | 任意非负整数 | 累计失败(Fail)的运行次数 |
.status.history.stoppedRuns | int | 任意非负整数 | 累计停止(Stopped)的运行次数 |
.status.history.targets.name | string | - | 被攻击应用(目标应用)的名称 |
.status.history.targets.kind | string | - | 被攻击应用的资源类型(如 deployment) |
.status.history.targets.chaosStatus | string | targeted、injected、reverted | 混沌注入状态 |
passedRuns/failedRuns/stoppedRuns:三个累计计数,反映该引擎下同一实验的多次执行结果分布。targets:记录本次实验"打到了谁"——目标应用名称(如hello)、资源类型(如deployment),以及混沌状态:targeted(已锁定目标)、injected(已注入故障)、reverted(已回滚恢复)。
官方文档示例(节选):
History: # fail experiment run count Failed Runs: 1 # passed experiment run count Passed Runs: 1 # stopped experiment run count Stopped Runs: 0 Targets: # status of the chaos Chaos Status: targeted # kind of the application Kind: deployment # name of the application Name: hello五、Probe Specification:探针执行结果
status.probeStatus记录实验中每个探针在不同模式下的执行结果,规范定义于 probe-specification.md。字段如下:
| 字段 | 类型 | 取值范围 | 说明 |
|---|---|---|---|
.status.probeStatus.name | string | n/a | 实验中所使用探针的名称 |
.status.probeStatus.type | string | HTTPProbe、K8sProbe、CmdProbe | 探针类型 |
.status.probeStatus.status.continuous | string | Awaited、Passed、Better Luck Next Time | Continuous 模式下的探针结果 |
.status.probeStatus.status.prechaos | string | Awaited、Passed、Better Luck Next Time | SOT 模式(测试开始前)的探针结果 |
.status.probeStatus.status.postchaos | map[string]string | Awaited、Passed、Better Luck Next Time | EOT 模式(测试结束后)的探针结果 |
关于探针模式,需要结合 litmus-probes.md 理解:Litmus 探针是定义在 ChaosEngine 中的可插拔校验,实验 Pod 会按探针设定的模式执行这些校验,并将其成功与否作为实验判定(verdict)的必要条件。探针共五种运行模式:
SOT:Start of Test,作为故障注入前的预检执行EOT:End of Test,作为故障注入后的后检执行Edge:故障注入前后各执行一次Continuous:故障注入期间按指定轮询间隔持续执行OnChaos:仅在混沌注入的持续时间内按指定间隔执行
官方文档给出的探针结果示例(一次同时使用了三种探针的实验):
Probe Status: # name of probe Name: check-frontend-access-url # status of probe Status: Continuous: Passed 👍 #Continuous # type of probe Type: HTTPProbe # name of probe Name: check-app-cluster-cr-status # status of probe Status: Post Chaos: Passed 👍 #EoT # type of probe Type: K8sProbe # name of probe Name: check-database-integrity # status of probe Status: Post Chaos: Passed 👍 #Edge Pre Chaos: Passed 👍 # type of probe Type: CmdProbe从示例可以看出三件事:
HTTPProbe更适合 Continuous 模式(持续探测前端访问 URL 可用性);K8sProbe常用于 EOT 模式(实验结束后校验集群资源状态是否恢复);CmdProbe可同时挂载 Pre Chaos 与 Post Chaos(Edge 模式),例如校验数据库在注入前后的一致性。
探针结果取值中的Better Luck Next Time表示该轮探针校验未通过("下次好运"是 Litmus 对探针失败的固定表述);最终 verdict 是否通过,取决于探针在这些模式下的综合表现。
探针的配置方式(以httpProbe的 Continuous 模式为例)可在 probe-modes.yaml 中查看完整示例:
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-delete-sa experiments: - name: pod-delete spec: probe: - name: "check-frontend-access-url" type: "httpProbe" httpProbe/inputs: url: "<url>" insecureSkipVerify: false responseTimeout: <value> method: get: criteria: == responseCode: "<response code>" # modes for the probes # supports: [SOT, EOT, Edge, Continuous, OnChaos] mode: "Continuous" runProperties: probeTimeout: 5 interval: 2 retry: 1 probePollingInterval: 2其中runProperties中的probeTimeout(单次校验超时)、interval(重试间隔)、retry(失败重试次数)、probePollingInterval(连续/OnChaos 模式每轮探测后的等待间隔)共同决定了探针的时序行为,也直接影响probeSuccessPercentage与最终 verdict 的取值。
六、源码印证:ChaosResult 在控制平面中的消费链路
ChaosResult 不只是给人类排障看的 YAML,它还贯穿 Litmus 控制平面的数据链路。从仓库源码可以确认其真实消费方式。
1. 订阅器(subscriber):按engine-experiment命名拉取结果
在 chaoscenter/subscriber/pkg/events/util.go 的getChaosData中,订阅器通过 litmus 官方 Go client 直接读取 ChaosResult:
if len(crd.Status.Experiments) == 1 { expRes, err := chaosClient.ChaosResults(cd.Namespace).Get(context.Background(), crd.Name+"-"+crd.Status.Experiments[0].Name, v1.GetOptions{}) if err != nil { return cd, err } // annotations sometimes cause failure in gql message escaping expRes.Annotations = nil cd.ChaosResult = expRes cd.ProbeSuccessPercentage = expRes.Status.ExperimentStatus.ProbeSuccessPercentage if expRes.Status.ExperimentStatus.ErrorOutput != nil { cd.FailStep = fmt.Sprintf("%s : %s", expRes.Status.ExperimentStatus.ErrorOutput.ErrorCode, expRes.Status.ExperimentStatus.ErrorOutput.Reason) } cd.ExperimentStatus = string(expRes.Status.ExperimentStatus.Phase) }这段代码印证了两个关键事实:
- ChaosResult 的对象名确实为
<ChaosEngine名>-<实验名>(这里拼接为crd.Name + "-" + crd.Status.Experiments[0].Name); - 订阅器直接从
expRes.Status.ExperimentStatus提取ProbeSuccessPercentage、Phase,并读取ErrorOutput(错误码 + 原因)拼接为FailStep,这些数据最终被打包进事件负载上报给控制平面(GraphQL 服务)。
对应的数据结构定义在 chaoscenter/subscriber/pkg/types/event.go:ChaosData中携带EngineName、ExperimentName、ExperimentVerdict、ProbeSuccessPercentage、FailStep以及完整的ChaosResult对象指针,并定义了Completed、Completed_With_Probe_Failure、Error、Stopped四种故障状态。这与phase/verdict的字段语义一一对应。
2. 前端模型:TypeScript 侧的字段映射
前端用于渲染实验运行详情与 Pipeline 节点的数据模型定义在 chaoscenter/web/src/models/chaosResult.ts,与文档字段逐项对应:
ChaosResultSpec:engine、experiment(与.spec.engine/.spec.experiment对应);ResultPhase:'Running' | 'Completed' | 'Stopped';ResultVerdict:'Pass' | 'Fail' | 'Stopped' | 'Awaited';ProbeVerdict:'Passed' | 'Failed' | 'N/A' | 'NA' | 'Awaited';ChaosResultStatus:experimentStatus(含phase、verdict、probeSuccessPercentage、failureOutput)、probeStatuses[](含name、type、mode、status)、history(passedRuns、failedRuns、stoppedRuns、targets[]);TargetDetails:name、kind、chaosStatus。
可见从 K8s CRD 到 Go 后端再到前端 TS 模型,ChaosResult 的字段体系始终保持一致,这也是它在 Web 控制台(ChaosCenter)中能直接展示实验通过率、失败步骤与目标信息的原因。
七、如何查看与使用 ChaosResult
由于 ChaosResult 是标准 Kubernetes CRD,可直接通过kubectl查看:
# 查看命名空间下所有 ChaosResult kubectl get chaosresults # 查看特定结果对象的完整 YAML(含 spec 与 status) kubectl get chaosresult engine-nginx-pod-delete -n default -o yaml # 关注关键字段:verdict、phase、probeSuccessPercentage kubectl get chaosresult engine-nginx-pod-delete -n default -o jsonpath='{.status.experimentStatus}'需要说明的是,读取 ChaosResult 需要相应的 RBAC 权限。在各类实验的安装清单(如 ebs-loss-by-id.md 的 RBAC 示例)中,ServiceAccount 通常被授予对chaosengines、chaosexperiments、chaosresults三类资源的 CRUD 权限,即:
resources: ["chaosengines","chaosexperiments","chaosresults"]实际排障时建议按以下顺序阅读结果对象:
- 看
spec.engine/spec.experiment,确认结果对象属于哪次实验; - 看
status.experimentStatus.verdict与phase,确认实验是 Pass / Fail 还是被 Stopped / Aborted; - 若为 Fail,看
failStep(以及源码中提到的errorOutput的错误码与原因)定位失败环节; - 看
probeSuccessPercentage与status.probeStatus,确认是哪个探针、哪个模式(Pre/Post/Continuous)未通过; - 最后看
history.targets,确认被攻击的目标应用及其混沌状态(targeted / injected / reverted)。
八、总结
ChaosResult 是 Litmus 混沌实验的"成绩单":spec用engine与experiment两个字段锚定结果归属;status.experimentStatus用phase、verdict、probeSuccessPercentage、failStep四个字段回答"实验处于什么阶段、结果如何、探针通过率多少、失败在哪一步";status.history累计多次运行的通过/失败/停止次数并记录目标应用;status.probeStatus则按 SOT / EOT / Edge / Continuous / OnChaos 五种模式分别记录每个探针的执行结果。
理解这些字段,是使用kubectl排查实验失败、接入 CI/CD 断言结果,以及阅读 ChaosCenter 前端展示数据的共同基础。建议继续阅读同目录下的 spec-specification.md、status-specification.md、probe-specification.md 三份规范原文,并结合 litmus-probes.md 理解探针模式对结果判定的影响,从而形成对 Litmus 实验结果体系的完整认知。
- 云原生
- 运维
- 可观测性
【免费下载链接】litmus
Litmus helps SREs and developers practice chaos engineering in a Cloud-native way. Chaos experiments are published at the ChaosHub (https://hub.litmuschaos.io). Community notes is at https://hackmd.io/a4Zu_sH4TZGeih-xCimi3Q
相关推荐
Elsa Core Shell Reload API 数据模型详解:实体定义、验证规则与状态转换
Elsa Core Shell Reload API 数据模型详解:实体定义、验证规则与状态转换 本指南基于 Elsa Core 仓库中 001 shell r
后端工作流自动化流程编排低代码Tendermint Core 协议核心规范详解:数据结构、编码、创世文件与状态验证
Tendermint Core 协议核心规范详解:数据结构、编码、创世文件与状态验证 本文以 Tendermint 仓库中 spec/core/readme.m
区块链共识算法MCProtocolLib数据包编解码原理:深入理解Minecraft协议序列化机制
MCProtocolLib数据包编解码原理:深入理解Minecraft协议序列化机制 MCProtocolLib是一个强大的Java库,专门用于与Minecra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考