- 云原生
- 运维
- 可观测性
【免费下载链接】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
导读
本文围绕 CNF Test Suite 采用 Litmus 的实践说明,讲解云原生网络功能(Cloud Native Network Function,CNF)开发者和网络运维人员如何借助 LitmusChaos 将电信服务(平台或网络应用)暴露在真实故障中,以评估其对云原生最佳实践(尤其是韧性 resilience)的遵循程度。读完本文,你将掌握 CNF Test Suite 的韧性测试思路,理解pod-network-duplication、pod-network-corruption、pod-io-stress、pod-memory-hog、pod-delete、disk-fill、pod-network-latency七个 Litmus 实验的底层原理与全部可调参数,并能在自己的 CNF 工作负载上直接复刻这些韧性测试场景。
背景:电信服务与云原生韧性
电信服务(电信平台或网络应用,即 CNF)在向云原生架构演进的过程中,一个核心问题是:当底层基础设施或应用自身出现常见故障时,业务是否依然可用、可恢复。CNF Test Suite 正是面向这一评估场景的开源测试套件,它面向 CNF 开发者与网络运营商,用来衡量电信服务在多大程度上遵循云原生原则与最佳实践,其中韧性(resilience)是评估的关键维度之一。
该文档的选择路径非常清晰:要对韧性进行测试,就必须主动注入故障。因此 CNF Test Suite 将混沌测试作为 workload tests(工作负载测试)的重要组成部分,用真实的故障注入来发现失败点(failure points),并据此给出改进韧性的修复建议(remediation steps)。
CNF Test Suite 为何选择 Litmus
根据 adopters/organizations/cnftestsuite.md 的说明,CNF Test Suite 选用 Litmus 的核心理由有三点:
- 属于 CNCF 生态:LitmusChaos 是 CNCF 下的开源混沌工程项目(README.md 中自述为 "100% open source & a CNCF project"),与 CNF 所处的云原生生态天然契合;
- 专为 Kubernetes 工作负载设计:混沌实验以 Kubernetes 自定义资源(CR)表达混沌意图与稳态假设,能直接在 Pod/Deployment 级别执行故障注入;
- 社区活跃且维护良好:有持续维护的文档、实验模板与活跃社区支撑。
从实现角度验证,Litmus 的实验体系确实以 Kubernetes CR 为核心(详见 README.md):ChaosExperiment是描述某类故障配置参数的模板资源(可安装、含权限声明与默认值);ChaosEngine将应用工作负载与 ChaosExperiment 关联起来,提供运行属性调节与探针(probes)稳态校验;ChaosResult记录实验运行结果、回滚状态与判定结论。三者共同构成了可被自动化套件(如 CNF Test Suite)驱动执行的基础设施。
韧性测试实验清单总览
CNF Test Suite 通过将 Litmus 实验纳入其工作负载测试,对电信服务执行以下韧性实验:
| 实验 | 故障注入效果 | 仓库内用户指南 |
|---|---|---|
pod-network-duplication | 复制目标 Pod 的网络数据包 | pod-network-duplication.md |
pod-network-corruption | 损坏目标 Pod 的网络数据包 | pod-network-corruption.md |
pod-io-stress | 对目标 Pod 造成磁盘 IO 压力 | pod-io-stress.md |
pod-memory-hog | 消耗目标容器内存资源 | pod-memory-hog.md |
pod-delete | 删除应用 Pod 副本(强制/优雅) | pod-delete.md |
disk-fill | 填满 Pod 临时存储,触发驱逐 | disk-fill.md |
pod-network-latency | 为目标 Pod 注入网络延迟/抖动 | pod-network-latency.md |
这些实验覆盖了电信服务最常见的几类故障形态:网络链路异常(丢包/复制/损坏/延迟)、资源耗尽(内存、IO、磁盘)、实例不可用(Pod 被删除)。在 CNF Test Suite 的语境下,跑完一轮实验即可让最终用户直观看到:当这些常见应用故障发生时,自己的电信服务表现如何、哪些薄弱环节需要加固。
Litmus 混沌实验的执行机制与权限模型
ChaosEngine:实验的入口资源
所有上述实验的注入动作都由 ChaosEngine 资源触发。以网络类实验为例,一个最小可用的 ChaosEngine 模板如下(来源于 pod-network-duplication.md 的示例,其余实验结构一致,仅替换实验名与chaosServiceAccount):
# 示例:注入 pod-network-duplication 故障 apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-network-duplication-sa experiments: - name: pod-network-duplication spec: components: env: - name: NETWORK_PACKET_DUPLICATION_PERCENTAGE value: '100' - name: TOTAL_CHAOS_DURATION value: '60'其中appinfo用于定位目标工作负载(命名空间、标签、资源类型),chaosServiceAccount指定执行实验所需的 RBAC 账号,experiments[].spec.components.env则用于覆盖 ChaosExperiment 模板中的默认参数。
最小 RBAC 权限
实验的执行依赖混沌算子创建 runner/helper Pod 并在目标容器内执行命令。仓库为每个实验都给出了最小权限示例,以pod-network-duplication为例(见 pod-network-duplication.md),其 Role 规则覆盖:
pods的增删改查与deletecollection(创建并监控实验与 helper Pod);events的写操作(记录 chaosengine/chaosresult 内事件);configmaps的读取(按需挂载到实验 Pod);pods/log与pods/exec(跟踪日志、在目标容器内执行命令);deployments、statefulsets、replicasets、daemonsets、deploymentconfigs、replicationcontrollers、rollouts的读取(推导目标 Pod 的父级/属主信息);batch/jobs的完整管理(chaos-runner 配置与监控实验 Job);litmuschaos.io组下chaosengines、chaosexperiments、chaosresults的完整操作(在混沌工作流内创建、轮询状态并删除混沌资源)。
以上规则配合ServiceAccount与RoleBinding(命名空间为default,可迁移到目标应用命名空间)即可构成执行实验的最小权限集。如果实验是在 chaos-center 构造并调度的 Litmus 工作流中执行,则通常直接复用 agent 安装时预置的litmus-adminRBAC(仓库中对应清单见 litmus-admin-rbac.yaml)。
网络类故障:复制、损坏与延迟
三个网络类实验(pod-network-duplication、pod-network-corruption、pod-network-latency)的注入机制高度一致:在指定容器上启动 traffic control(tc)进程,通过 netem 规则作用于 egress(出站)流量,从而在不杀死 Pod 的情况下模拟真实的网络劣化。它们最适合用来验证 CNF 对"有损/不稳定网络"(lossy/flaky network)的韧性,例如跨可用区/跨地域的微服务通信。
各实验特有参数
| 实验 | 特有 ENV | 说明 | 默认值 |
|---|---|---|---|
pod-network-duplication | NETWORK_PACKET_DUPLICATION_PERCENTAGE | 网络数据包复制比例(%) | 100 |
pod-network-corruption | NETWORK_PACKET_CORRUPTION_PERCENTAGE | 网络数据包损坏比例(%) | 100 |
pod-network-latency | NETWORK_LATENCY | 网络延迟(毫秒) | 2000 |
pod-network-latency | JITTER | 网络抖动(毫秒),制造延迟波动 | 0 |
以延迟实验为例(完整示例见 pod-network-latency.md):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-network-latency-sa experiments: - name: pod-network-latency spec: components: env: # 注入的网络延迟(毫秒) - name: NETWORK_LATENCY value: '2000' - name: TOTAL_CHAOS_DURATION value: '60'pod-network-latency的"用途"章节(原文档)特别说明了这类实验的价值:网络劣化通常不会让 Pod 被 kube-proxy 标记为不健康从而摘除流量(除非有专门测量延迟的存活探针),因此它能真实模拟 Pod 网络或跨区域微服务通信中的延迟问题。缓解手段可以是基于 SLO/性能参数切换流量的中间件,或者至少通过告警/通知让 SRE 及时介入;同时该实验也能量化"下游微服务延迟对最终用户体验的冲击是否可接受"。这类实验的典型场景示意见下方网络故障示意图(详见 mkdocs/docs/experiments/images/network-chaos.png)。
网络实验通用参数与爆炸半径控制
三个网络实验共享一组控制"打击范围"(blast radius)的参数,这是电信服务韧性测试中最有价值的能力——只劣化你想测试的流量,而不影响其余业务:
| ENV | 作用 | 说明 |
|---|---|---|
NETWORK_INTERFACE | 进行流量整形考虑的以太网接口名 | 默认eth0 |
TARGET_CONTAINER | 被注入网络故障的容器名 | 仅 containerd/CRI-O 运行时适用;不填则作用于 Pod 第一个容器 |
DESTINATION_IPS | 被影响可达性的目标 IP/CIDR | 逗号分隔,如8.8.8.8,192.168.5.6;不填则作用于全部 IP |
DESTINATION_HOSTS | 被影响可达性的目标 DNS/FQDN 名 | 如nginx.default.svc.cluster.local,google.com |
SOURCE_PORTS | 被影响的源端口 | 逗号分隔;不填则作用于全部端口 |
DESTINATION_PORTS | 被影响的目标端口 | 逗号分隔;不填则作用于全部端口 |
PODS_AFFECTED_PERC | 需要被打击的 Pod 百分比 | 默认 0(对应 1 个副本) |
TARGET_PODS | 明确的被打击 Pod 名单 | 逗号分隔;不填则按 appLabels 随机挑选 |
例如,只针对特定目标 IP/主机注入复制故障(示例来自 pod-network-duplication/destination-ips-and-hosts.yaml):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-network-duplication-sa experiments: - name: pod-network-duplication spec: components: env: - name: DESTINATION_IPS value: '8.8.8.8,192.168.5.6' - name: DESTINATION_HOSTS value: 'nginx.default.svc.cluster.local,google.com' - name: TOTAL_CHAOS_DURATION value: '60'按端口定向注入时,可用SOURCE_PORTS/DESTINATION_PORTS限定范围;若想保护关键端口(如控制面信令),则用!前缀实现端口黑名单,例如value: '!80,8080'表示源端口 80、8080 不参与混沌(完整示例见 pod-network-duplication/blacklist-source-and-destination-ports.yaml)。
运行时与注入库选择
网络类实验还需指定容器运行时与注入库:
CONTAINER_RUNTIME:支持docker、containerd、crio(使用 litmus 库时),默认 containerd;使用 pumba 库时仅支持 docker;SOCKET_PATH:容器运行时 socket 文件路径,默认/run/containerd/containerd.sock;LIB:注入库,默认litmus,可选pumba;使用 pumba 时还需通过TC_IMAGE(默认gaiadocker/iproute2)指定 Linux 流量控制镜像,LIB_IMAGE(默认litmuschaos/go-runner:latest)用于执行 netem 命令。
对应的完整配置示例见 pod-network-duplication/pumba-lib.yaml 与 pod-network-duplication/container-runtime-and-socket-path.yaml。
资源压力类故障:IO、内存与磁盘
电信服务在 Kubernetes 上最常见的运行期风险之一,就是资源耗尽导致的副本驱逐与服务劣化。CNF Test Suite 使用以下三个实验覆盖此类场景。
pod-io-stress:共享磁盘的"噪音邻居"
该实验对应用 Pod 制造持续的重 IO 压力,以验证共享同一磁盘资源(临时或持久存储)的应用的韧性。原文档明确指出:Kubernetes 中磁盘压力(Disk Pressure)或 CPU 占用过高的"噪音邻居"(Noisy Neighbour)问题非常普遍——持续的重 IO 会拖慢共享磁盘上其他微服务的读写;节点 scratch 空间被耗尽后,新容器无法调度,kubelet 甚至会打上disk-pressure驱逐污点,导致 Pod 大规模迁移。
| ENV | 作用 | 默认值 |
|---|---|---|
FILESYSTEM_UTILIZATION_PERCENTAGE | 按文件系统空闲空间的百分比进行 IO 压力 | 10% |
FILESYSTEM_UTILIZATION_BYTES | 按绝对大小(GB)进行 IO 压力;与百分比互斥,两者都设时百分比优先 | 无 |
NUMBER_OF_WORKERS | 参与磁盘 IO 压力的 worker 数 | 4 |
VOLUME_MOUNT_PATH | 指定需要被填充的卷挂载路径 | 无 |
TOTAL_CHAOS_DURATION | 混沌持续时间(秒) | 120s |
LIB/LIB_IMAGE | 注入库及执行压力命令的镜像 | litmus/litmuschaos/go-runner:latest |
按百分比注入的示例(来源于 pod-io-stress/filesystem-utilization-percentage.yaml):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-io-stress-sa experiments: - name: pod-io-stress spec: components: env: - name: FILESYSTEM_UTILIZATION_PERCENTAGE value: '10' # 按空闲空间百分比 - name: TOTAL_CHAOS_DURATION value: '60'pod-memory-hog:内存突刺与 OOM 行为
该实验在目标容器内按指定 MB 数消耗内存,模拟应用 Pod 因预期/非预期进程导致的内存突刺,观察整体应用栈在 OOM 场景下的表现。原文档的"用途"章节解释了 Kubernetes 内存约束的两条路径:
- 容器设置了 limits:超过限制会触发 OOMKill(常为主进程 pid 1),随后 kubelet 按重启策略重启容器;
- 容器未设置 limits:内存占用不受约束,直到节点级 OOM 机制接管——此时节点上所有 Pod 都可能按
oom_score与 QoS 等级被选择性杀掉(bestEffort 类最先遭殃),爆炸半径显著扩大。
| ENV | 作用 | 默认值 |
|---|---|---|
MEMORY_CONSUMPTION | 内存消耗量(MB) | 500MB |
NUMBER_OF_WORKERS | 运行压力进程的 worker 数 | 1 |
TOTAL_CHAOS_DURATION | 混沌持续时间(秒) | 60s |
LIB/LIB_IMAGE | 注入库及 helper 镜像 | litmus/litmuschaos/go-runner:1.13.8 |
STRESS_IMAGE | pumba 库在节点上运行压力器的镜像 | alexeiled/stress-ng:latest-ubuntu(仅LIB=pumba时使用) |
核心配置示例(来源于 pod-memory-hog/memory-consumption.yaml):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-memory-hog-sa experiments: - name: pod-memory-hog spec: components: env: - name: MEMORY_CONSUMPTION value: '500' # 单位 MB - name: TOTAL_CHAOS_DURATION value: '60'disk-fill:临时存储限额与驱逐验证
disk-fill通过填满 Pod 的 ephemeral storage(临时存储)制造磁盘压力,当填充量超过 Pod 的临时存储限制时,应用 Pod 会被驱逐。它用于验证:临时存储的 Requests/Limits 参数是否设置得足够合理,以及应用面对磁盘压力/副本驱逐的韧性。
前置条件:运行前目标应用必须设置合适的临时存储请求与限制。原文档给出了如下 Pod 规格示例:
apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: ephemeral-storage: "2Gi" limits: ephemeral-storage: "4Gi" - name: wp image: wordpress resources: requests: ephemeral-storage: "2Gi" limits: ephemeral-storage: "4Gi"该实验的必填参数(二选一):
| ENV | 作用 | 说明 |
|---|---|---|
FILL_PERCENTAGE | 按临时存储限额的百分比填充 | 可设置超过 100以强制驱逐 Pod;使用前提是目标 Pod 已设置 ephemeral-storage limits |
EPHEMERAL_STORAGE_MEBIBYTES | 按绝对大小填充(MiBi) | 与FILL_PERCENTAGE互斥,两者都设时FILL_PERCENTAGE优先 |
常用可选参数包括:DATA_BLOCK_SIZE(填充磁盘的数据块大小,单位 KB,默认 256)、TARGET_CONTAINER(默认作用于 Pod 第一个容器)、TOTAL_CHAOS_DURATION(默认 60s)、LIB(该实验仅支持litmus库)等。按百分比填充的示例(来源于 disk-fill/fill-percentage.yaml):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: disk-fill-sa experiments: - name: disk-fill spec: components: env: - name: FILL_PERCENTAGE value: '80' # 占 ephemeral-storage 限额的百分比 - name: TOTAL_CHAOS_DURATION value: '60'可用性故障:pod-delete
pod-delete对应用资源的特定/随机副本执行(强制/优雅)Pod 删除,用于验证部署的健全性(副本可用性与服务不中断)以及应用的恢复流程。原文档"用途"章节指出,在 Kubernetes 这类分布式系统中,当部分副本因系统或应用故障不可用时,应用必须仍满足 SLO——这就需要在副本压力上升时验证:HPA 是否会基于观测到的资源利用率扩容、PV 在重调度时挂载需要多久、副本的 MTTR(平均修复时间)、Kafka 这类应用的 leader/follower 重选、Percona 等应用的最小 quorum 是否仍可运行、以及数据重同步/重分发是否正常。
删除模式与节奏
| ENV | 作用 | 默认值 |
|---|---|---|
FORCE | false表示优雅删除(默认 30s 终止周期);true表示立即强制删除(0s grace period) | true(配合terminationGracePeriodSeconds=0) |
TOTAL_CHAOS_DURATION | 混沌持续时间(秒)。注意:实验整体运行时长可能超出该值数分钟 | 15s |
CHAOS_INTERVAL | 两次连续 Pod 故障之间的时间间隔(秒) | 5s |
RANDOMNESS | 是否引入随机删除间隔,支持true/false | false |
PODS_AFFECTED_PERC | 被打击的 Pod 百分比 | 0(对应 1 副本) |
RANDOMNESS=true时,CHAOS_INTERVAL支持两种写法:l-r形式(如5-10)表示在上下界之间随机取值;单值形式(如10)表示在 0 与该值之间随机取值。
确定性终止顺序(serial 模式)
当SEQUENCE=serial时,可用POD_TERMINATION_ORDER控制 Pod 终止顺序:random(默认)、alphabetical(按名称升序)、reverse(按名称降序)。若显式提供了有序的TARGET_PODS列表,则以列表顺序为准,POD_TERMINATION_ORDER被忽略——这可以保证固定命名的击杀顺序(例如总是最后杀session-pod)。还可叠加INTER_POD_KILL_INTERVAL_SECONDS(serial 模式下一次 Pod 击杀后的额外等待秒数,与CHAOS_INTERVAL叠加,默认 0)以观察部分恢复过程。综合示例(来源于 pod-delete.md):
apiVersion: litmuschaos.io/v1alpha1 kind: ChaosEngine metadata: name: engine-nginx spec: engineState: "active" annotationCheck: "false" appinfo: appns: "default" applabel: "app=nginx" appkind: "deployment" chaosServiceAccount: pod-delete-sa experiments: - name: pod-delete spec: components: env: - name: POD_TERMINATION_ORDER value: 'alphabetical' - name: SEQUENCE value: 'serial' - name: INTER_POD_KILL_INTERVAL_SECONDS value: '5' - name: TOTAL_CHAOS_DURATION value: '60'所有实验共享的公共参数
上述七个实验都支持一组公共 tunables,在 ChaosEngine 的experiments[].spec.components.env中设置(详见 common-tunables-for-all-experiments.md):
| ENV | 作用 | 默认值/取值 |
|---|---|---|
TOTAL_CHAOS_DURATION | 混沌注入总时长(秒) | 各实验不同(如网络实验 60s、io-stress 120s、pod-delete 15s) |
RAMP_TIME | 混沌注入前/后的等待期(秒) | 无 |
SEQUENCE | 多目标时的执行顺序 | parallel(默认,同时注入)、serial(逐个注入) |
LIB | 混沌注入库 | 默认litmus,部分实验支持pumba |
LIB_IMAGE | helper Pod 使用的镜像 | 默认litmuschaos/go-runner:latest(container-kill、网络、压力、DNS、disk-fill、kubelet-service-kill、docker-service-kill、node-restart 等实验适用) |
INSTANCE_ID | 用户自定义字符串,作为后缀附加在 chaosresult CR 名称上,便于标识某次运行 | 如04-05-2020-9-00 |
此外,实验运行前的默认校验(Default Validations)是:混沌注入前后应用 Pod 必须处于 running 状态,这构成了 CNF 韧性测试的基本稳态条件。
收益与落地建议
从 CNF Test Suite 的实践来看,Litmus 带来的收益可归纳为四点:CNCF 生态背书(与云原生技术栈同源)、面向 Kubernetes 工作负载的设计(以 CR 表达混沌意图,天然适配 CNF 平台)、活跃且维护良好的社区(实验模板持续更新)、以及可编程可嵌入的自动化能力(ChaosEngine/ChaosResult 的 CR 形态使韧性测试可以像其他 workload tests 一样被套件调度、结果被采集)。电信服务团队落地时可以参照以下路径:
- 先定稳态:为每个 CNF 定义运行期稳态条件(Pod 存活、SLO 指标),即默认校验的延伸;
- 逐类注入:从网络类(延迟/损坏/复制)、资源类(IO/内存/磁盘)、可用性类(Pod 删除)三个维度逐步扩大故障面;
- 控制爆炸半径:善用
DESTINATION_IPS、DESTINATION_PORTS、PODS_AFFECTED_PERC等参数,把故障限制在待评估的流量或副本上; - 沉淀为工作流:将多个实验串入 Litmus Chaos Workflow,借助 chaos-center 统一调度与可视化结果(相关分类索引见 experiments/categories/contents.md)。
通过这套基于 Litmus 的韧性实验体系,CNF 开发者和网络运营商能够持续发现电信服务中的失败点,并依据实验结果给出明确的韧性改进方向——这正是云原生网络功能"韧性可度量"的关键一步。
- 云原生
- 运维
- 可观测性
【免费下载链接】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
相关推荐
3分钟创建专业级PBR材质:免费开源工具Materialize终极指南
3分钟创建专业级PBR材质:免费开源工具Materialize终极指南 还在为游戏开发中复杂的材质制作而烦恼吗?Materialize这款免费开源的PBR材质生
图形学开发工具如何构建企业级AI质量保障体系:DeepEval框架的完整解决方案
如何构建企业级AI质量保障体系:DeepEval框架的完整解决方案 在AI应用快速普及的今天,我们面临着一个关键挑战:如何确保大语言模型在实际业务中的表现既准确
人工智能大模型模型评测AI 评测测试红蓝对抗提示工程如何评估 LiDAR SLAM 精度?MULLS 集成 kitti_eval 与 evo 的完整评测教程
如何评估 LiDAR SLAM 精度?MULLS 集成 kitti_eval 与 evo 的完整评测教程 对于做机器人、自动驾驶或测绘的朋友来说, LiDAR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考