Skip to main content

Chaos Mesh vs LitmusChaos: Which One Actually Fits Breaking Your Own Fleet on Purpose

12 min readDora NodaDora Noda
Share

A managed PaaS's SLA page is a promise you can't verify. "99.95% uptime" tells you what the vendor is contractually on the hook for, not what actually happens when a node dies at 3am — and you have no way to find out short of waiting for it to happen. A self-hosted platform running on Cluster API and owned hardware doesn't get that shortcut. If you claim your fleet survives a node loss, a network partition, or an etcd disk going slow, the only way to know if that's true is to break it yourself, on a schedule, and watch what happens.

That's the actual job the two CNCF chaos-engineering projects for Kubernetes are built for, and they're built differently enough that picking the wrong one costs you real incidents later. Chaos Mesh runs a privileged daemon on every node and reaches into the kernel, network stack, and filesystem directly. LitmusChaos spins up a disposable pod per experiment and coordinates them from a central, multi-cluster hub. For a fleet where "node" means a physical Hetzner box you own — not a cloud VM you can slide into another availability zone — that architectural split determines which tool tests your control plane convincingly and which one lets a multi-tenant fleet run those tests without occasionally taking down a tenant's app by accident. The short answer: you want both, doing different jobs. The rest of this post is why, with the actual experiments and the actual blast-radius mechanics that make each tool safe or unsafe for a shared fleet.

Two Architectures, Not Two Feature Lists

Comparisons of chaos-engineering tools tend to turn into feature-checklist tables — pod kill, network delay, IO fault, does it have a dashboard. That framing misses the part that actually matters for a self-hosted fleet: where the fault injection runs and what it's capable of touching.

Chaos Mesh deploys a Chaos Daemon as a Kubernetes DaemonSet — one privileged pod per node, running continuously. When you create a NetworkChaos or PodChaos custom resource, the Controller Manager tells the Chaos Daemon on the affected node to act directly: it enters the target pod's network namespace, manipulates tc (traffic control) rules, injects kernel-level faults, or kills processes — all from inside the node's own kernel, not through the Kubernetes API. That's why Chaos Mesh can do things like simulate a JVM exception, corrupt a filesystem read, or introduce clock skew: the daemon has host-level reach. It ships with a built-in web dashboard for designing and monitoring experiments without hand-writing YAML.

LitmusChaos takes the opposite approach. A Chaos Operator watches for ChaosEngine custom resources; when one appears, it spins up an ephemeral Chaos Runner pod scoped to that specific experiment, which executes a fault definition pulled from ChaosHub — a public library of reusable experiments (pod-delete, node-drain, node-cpu-hog, disk-fill, and dozens more) — against exactly the target the ChaosEngine declares. When the experiment ends, the Runner pod is gone. Orchestration, scheduling, and result visualization happen through ChaosCenter (formerly Litmus Portal), which is explicitly built to manage experiments across multiple clusters from one place, not just one.

Chaos MeshLitmusChaos
Execution unitPrivileged Chaos Daemon, persistent, one per node (DaemonSet)Ephemeral Chaos Runner pod, one per experiment
Fault reachKernel/host-level: network namespace, tc, filesystem, process signalsWhatever the experiment's own logic does against its declared target
Fault catalogPodChaos, NetworkChaos, IOChaos, TimeChaos, StressChaos, KernelChaos, DNSChaos, HTTPChaos, JVMChaosChaosHub library: pod-delete, node-drain, node-cpu-hog, disk-fill, container-kill, and more, contributed by the community
UISingle built-in dashboard, cluster-scopedChaosCenter, explicitly multi-cluster
CNCF status (2026)Incubating (accepted July 2020, Incubating Feb 2022)Incubating (Sandbox 2020, Incubating Jan 2022)
GitHub stars (2026)~7.7k~5.4k

Neither has graduated CNCF as of 2026 — both are still Incubating, several years into that stage, which says more about how conservatively the CNCF grades infrastructure-adjacent chaos tooling than about either project's maturity.

Breaking the Control Plane a Managed PaaS Never Has To Prove

Here's what "own the hardware" actually changes: on a managed PaaS, node loss is the vendor's problem, and their failover is opaque to you by design. On a Cluster-API-managed fleet running on Hetzner-owned machines, there is no cross-AZ fabric to fall back on if your own redundancy design has a hole in it — the physical box either has a healthy sibling doing its job, or it doesn't, and CAPI's MachineHealthCheck either catches that and remediates it, or it doesn't. Nobody proves that for you. Below are three specific experiments a self-hosted operator runs to find out, each using a Chaos Mesh custom resource against the daemon's host-level reach — Litmus's pod-scoped Runner model can approximate the first, but not the latter two, which is the point.

Node loss. A PodChaos experiment with action: pod-kill targets the etcd or kube-apiserver pod on one control-plane node; separately, draining the underlying Hetzner machine simulates a harder failure (disk death, host crash). Pass criteria: CAPI's MachineHealthCheck flags the unhealthy Machine within its configured timeout, a replacement is provisioned, and etcd re-establishes quorum with the surviving members without a full cluster restart. Fail mode you're actually looking for: a MachineHealthCheck that never fires because its node-condition thresholds were copied from a cloud-vendor example and don't match how your bare-metal kubelet reports unhealthy state.

Network partition between two owned Hetzner machines. A NetworkChaos resource with action: partition cuts traffic between two control-plane nodes — something you can't casually simulate on a managed control plane, because you don't control the network path between the vendor's redundant instances. On owned hardware, this is a tc-level rule Chaos Mesh's daemon installs directly. What you're checking: does etcd's Raft implementation correctly detect the partition and trigger leader election among the reachable quorum, or does the split produce two nodes each convinced they're the leader — a failure mode that's silent until a write conflict surfaces days later. This experiment is the actual point of running your own control plane instead of renting one: you get to find that bug in a scheduled test instead of an incident.

etcd latency and IO injection. An IOChaos fault targeting the etcd data volume on one node — injecting read/write latency to simulate a degrading Hetzner NVMe device, a real failure mode, not a hypothetical one — checks whether etcd's own slow-disk alarm (etcdserver: apply request took too long) fires before that node drags down consensus latency for the whole quorum, and whether your fleet's automation reacts to the alarm or just logs it. This is the experiment that most directly validates "my control plane degrades gracefully" instead of "my control plane works when nothing is wrong," which is the only claim a demo ever tests.

What Happens to a Tenant's App While the Control Plane Is on Fire

Breaking the control plane in isolation only answers half the question. The topic that actually matters to anyone running tenant workloads on the same fleet is whether a tenant's app survives the same event — because a control plane that recovers perfectly while every tenant's app drops requests for ninety seconds hasn't proven what you think it proved.

Run this as a fourth, parallel experiment: during the node-drain test above, place a tenant-representative workload — one stateless web service and one stateful service backed by a PVC — on the node being drained, and watch what happens to them, not just to the control plane. Pass criteria: the stateless service's pods reschedule onto a healthy node and pass readiness checks within your target window (for most self-hosted setups, under 30 seconds is a reasonable bar), with no more than a handful of dropped requests during the gap if you're running a load balancer that retries; the stateful service's PVC detaches from the drained node's CSI mount and reattaches to wherever the rescheduled pod lands, without silent data corruption or a stuck Terminating pod that never actually releases the volume. That last failure mode — a PVC that CSI won't cleanly detach — is the one that turns a clean control-plane failover into a multi-hour tenant incident, and it's specifically a storage-layer interaction that a control-plane-only chaos test will never surface, because the control plane itself reports healthy the entire time.

This is the deliverable a managed PaaS's SLA page structurally can't give you: not "the platform stayed up," but "here is what actually happened to a representative tenant app during a real failure, measured, on a schedule, not inferred from a vendor's aggregate uptime number."

Blast Radius: The Question That Actually Decides Which Tool You Trust

Here's the tension the architecture section sets up: Chaos Mesh's Chaos Daemon is inherently node-wide-capable — it's a privileged process with kernel-level reach on every node in the cluster, which is exactly what makes it able to run the etcd and network-partition experiments above. On a single-tenant test cluster, that's fine. On a fleet where node N might be running three different tenants' apps alongside the control-plane component you're actually trying to break, "the daemon can reach anything on that node" is not an answer to "will it only touch what I told it to."

Chaos Mesh's answer is a namespace-whitelist and RBAC restrict-authorization model: an admin-configured allowlist of namespaces where experiments are permitted at all, layered under native Kubernetes RBAC binding specific roles to specific service accounts scoped to specific namespaces. The daemon still runs privileged on the node, but the API surface that lets someone create a NetworkChaos or PodChaos object is fenced off at the namespace boundary the same way any other Kubernetes RBAC restriction works. It's a safety mechanism bolted onto a capability that's structurally broader than it — which means it's exactly as strong as your namespace-whitelist configuration and no stronger, and a misconfigured whitelist is a real, not hypothetical, way to chaos-test a tenant's app you didn't mean to touch.

LitmusChaos's model is different in kind, not just degree: every ChaosEngine custom resource declares its own target — a namespace plus a label selector, written directly into the experiment definition — and the Chaos Runner pod that executes it only ever acts against that declared target, because that's the only thing the experiment's own logic was pointed at. There's no separate allowlist to misconfigure, because the scoping is the experiment definition itself, enforced further by RBAC on who can create ChaosEngine objects via litmusctl in the first place.

The honest answer for a multi-tenant fleet: LitmusChaos's per-experiment declarative scoping is the safer default for anything that isn't explicitly a host-level test, precisely because there's no daemon sitting on every node with more reach than the experiment needs. Chaos Mesh's node-wide daemon is the only way to run the kernel-level and cross-node experiments in the previous two sections — nothing about LitmusChaos's Runner-pod model can partition two physical nodes' network stacks or inject IO latency into an etcd volume — but that power is exactly why it needs the namespace whitelist locked down before it runs anywhere near a shared node, and why "we installed Chaos Mesh with default RBAC" is a real finding to look for in a platform security review, not a theoretical one.

The Multi-Cluster Hub Problem

A Cluster-API-managed platform doesn't run one cluster — it runs a fleet, provisioning and tearing down clusters per tenant or per environment. Chaos Mesh's dashboard is scoped to whichever cluster it's deployed into; running the same node-loss experiment across twelve clusters means deploying, configuring, and monitoring Chaos Mesh twelve separate times, with no shared view of results.

LitmusChaos's ChaosCenter is built for exactly this: a central control plane where each managed cluster registers as an agent, experiments get scheduled and results aggregated across all of them from one place. For a fleet operator who wants "run the same partition test against every control plane in the fleet every Sunday night and get one report," ChaosCenter is the piece that makes that operationally real instead of a script gluing twelve dashboards together by hand.

The Actual Recommendation: Different Tools for Different Layers

Put together, the pattern that fits a self-hosted, multi-tenant, Cluster-API-managed fleet isn't "pick one" — it's assigning each tool to the layer its architecture actually earns:

  • Chaos Mesh, deployed with a locked-down namespace whitelist covering only designated control-plane test namespaces, runs the node-loss, network-partition, and etcd-IO experiments from earlier — the ones that require host-level reach and can't be done any other way. It never gets whitelisted into tenant namespaces.
  • LitmusChaos, via ChaosCenter, runs the tenant-workload-resilience experiments (pod-delete, node-drain from the tenant's-app perspective) across every cluster in the fleet, because its per-ChaosEngine declarative scoping means an experiment against tenant namespace A structurally cannot reach tenant namespace B, and ChaosCenter gives you one place to schedule and review results fleet-wide.

A concrete weekly schedule: Sunday 02:00 UTC, Chaos Mesh runs the network-partition experiment against one randomly selected control-plane node pair, with the tenant-workload check from the previous section running in parallel via a Litmus ChaosEngine targeting a canary tenant namespace on the same node. Both results land in the same incident channel. If either fails, that's a finding — not a postmortem waiting to happen.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on Cluster-API-managed machines you own. Owning the fleet means owning the burden of proving it survives a bad night, not just claiming it does. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex