Chaos engineering for Kates/Kafka on Kubernetes. Wraps the LitmusChaos execution plane (litmus-core subchart: chaos operator, exporter, CRDs) with Kafka-specific RBAC, ChaosExperiment/ChaosEngine templating, monitoring, network isolation, and admission policy.
For the full deployment narrative, troubleshooting, and architecture diagram, see the Kates Chaos Chart — Deployment Guide. For chaos-engineering theory, see the chaos book chapters.
This chart deploys the LitmusChaos execution plane only — it does not deploy the ChaosCenter web portal (frontend / GraphQL / auth-server / MongoDB). Chaos is driven declaratively through the engines: values or by applying ChaosEngine resources. If you want the UI, install ChaosCenter separately.
What it manages:
- RBAC — a
litmus-adminServiceAccount + Role in eachtargetnamespace, a coordinator ClusterRole binding in eachcoordinatornamespace, and optional cluster-scoped node-chaos RBAC. - ChaosExperiments — installed into your target namespaces via a post-install Job.
- ChaosEngines — rendered from
engines:, with first-class probes and pod components. - Monitoring — optional ServiceMonitor + Grafana dashboard.
- NetworkPolicy / Kyverno / PDB / GameDay — optional, all off by default.
| Requirement | Minimum | Notes |
|---|---|---|
| Kubernetes | 1.25+ | Any managed or self-managed cluster |
| Helm | 3.12+ | Uses the litmus-core subchart dependency |
| LitmusChaos CRDs | 3.28 | Applied before install (hooks depend on them) |
| Target namespaces | — | Every rbac.targetNamespaces entry must exist |
# 1. CRDs (hooks depend on them)
kubectl apply -f config/litmus/chaos-litmus-chaos-enable.yml
kubectl wait --for=condition=Established crd/chaosexperiments.litmuschaos.io --timeout=60s
# 2. Dependencies
helm dependency build charts/kates-chaos
# 3. Install
helm upgrade --install chaos charts/kates-chaos \
-n litmus --create-namespace \
-f charts/kates-chaos/values-generic.yaml --wait| Overlay | Use | Notable defaults |
|---|---|---|
values-kind.yaml |
Local Kind / dev | pullPolicy: IfNotPresent, NetworkPolicy off |
values-generic.yaml |
Production K8s | pullPolicy: Always, NetworkPolicy + Kyverno on |
| Parameter | Description | Default |
|---|---|---|
nameOverride |
Override chart name | "" |
fullnameOverride |
Override full release name | "" |
commonLabels |
Labels added to every resource | {} |
commonAnnotations |
Annotations added to every resource | {} |
serviceAccount.name |
Chaos service account (shared by RBAC + engines) | litmus-admin |
| Parameter | Description | Default |
|---|---|---|
global.imageRegistry |
Registry prefix for all chart-managed images | "" |
global.imagePullPolicy |
Pull policy for chart-managed pods | IfNotPresent |
global.imagePullSecrets |
Pull secrets for chart-managed pods | [] |
global.clusterDomain |
Cluster DNS domain | cluster.local |
images.kubectl.repository |
Image for installer Job / GameDay / tests | registry.k8s.io/kubectl |
images.kubectl.tag |
kubectl image tag | v1.33.0 |
images.kubectl.digest |
Pin by digest (wins over tag) | "" |
images.goRunner.repository |
Default runtime for experiments | litmuschaos/go-runner |
images.goRunner.tag |
go-runner image tag | 3.28.0 |
The litmus-core subchart images (operator/runner) are set under the litmus-core: key.
| Parameter | Description | Default |
|---|---|---|
rbac.enabled |
Render cross-namespace RBAC | true |
rbac.targetNamespaces |
List of {name, role} — target (fault injection) or coordinator (create engines/read results) |
[{kafka, target}, {kates, coordinator}] |
rbac.targetNamespaces[].serviceAccount |
SA bound for a coordinator entry |
default |
rbac.nodeChaos.enabled |
Cluster-scoped RBAC for node-level chaos | true |
rbac.kafkaNamespace |
Deprecated — use targetNamespaces |
"" |
rbac.katesNamespace |
Deprecated — use targetNamespaces |
"" |
| Parameter | Description | Default |
|---|---|---|
experiments.enabled |
Install ChaosExperiment definitions (post-install Job) | true |
experiments.targetNamespaces |
Namespaces to install into (empty = every target namespace) |
[] |
experiments.installer.backoffLimit |
Installer Job retries | 3 |
experiments.installer.ttlSecondsAfterFinished |
Installer Job TTL | 300 |
experiments.installer.resources / securityContext / nodeSelector / tolerations |
Installer pod tuning | {} / [] |
experiments.definitions[].name |
Experiment name | — |
experiments.definitions[].scope |
Namespaced or Cluster |
Namespaced |
experiments.definitions[].env |
Default env baked into the ChaosExperiment | — |
experiments.definitions[].permissions |
spec.definition.permissions (runner RBAC) |
— |
Default definitions: pod-delete, pod-cpu-hog, pod-memory-hog, pod-network-partition, pod-io-stress, pod-dns-error, node-drain.
Each key under engines: renders a ChaosEngine. Probes and pod components are first-class.
| Parameter | Description | Default |
|---|---|---|
engines.<name>.enabled |
Render this engine | false |
engines.<name>.appNamespace |
Target namespace | primary target ns |
engines.<name>.appLabel |
App selector, e.g. strimzi.io/kind=Kafka |
— |
engines.<name>.appKind |
statefulset / deployment / … |
statefulset |
engines.<name>.experiment |
Experiment name | <name> |
engines.<name>.serviceAccount |
Override the chaos SA | serviceAccount.name |
engines.<name>.engineState |
active / stop |
active |
engines.<name>.annotationCheck |
Require chaos annotation on the target | false |
engines.<name>.jobCleanUpPolicy |
delete / retain |
— |
engines.<name>.duration / interval |
TOTAL_CHAOS_DURATION / CHAOS_INTERVAL |
30 / 10 |
engines.<name>.force |
Set FORCE=true |
false |
engines.<name>.targetPods / podsAffectedPerc |
Scope the blast radius | — |
engines.<name>.env |
Extra experiment env (map) | {} |
engines.<name>.components |
nodeSelector / resources / tolerations for the runner |
{} |
engines.<name>.probes |
Litmus probes (cmdProbe/httpProbe/promProbe), passed through |
[] |
| Parameter | Description | Default |
|---|---|---|
networkPolicy.enabled |
Scope chaos-infra traffic | false |
networkPolicy.apiServer.enabled |
Egress to the Kubernetes API server (operator needs it) | true |
networkPolicy.apiServer.ports / ipBlock |
API-server ports / CIDR pin | [443,6443] / {} |
networkPolicy.dns.enabled |
DNS egress | true |
networkPolicy.monitoring.enabled |
Prometheus scrape ingress to the exporter | true |
networkPolicy.monitoring.namespace / port |
Scrape source ns / exporter port | monitoring / 8080 |
networkPolicy.targets.enabled |
Egress to rbac.targetNamespaces |
true |
networkPolicy.extraIngress / extraEgress |
Raw rules appended verbatim | [] |
networkPolicies.enabled |
Deprecated alias — OR'd with networkPolicy.enabled |
false |
| Parameter | Description | Default |
|---|---|---|
monitoring.serviceMonitor.enabled |
Create a ServiceMonitor for the exporter | false |
monitoring.serviceMonitor.selector |
Exporter Service label selector | {app: litmus} |
monitoring.serviceMonitor.port / path / interval |
Scrape endpoint | http / /metrics / 30s |
monitoring.serviceMonitor.scrapeTimeout / honorLabels |
Scrape tuning | "" / false |
monitoring.serviceMonitor.relabelings / metricRelabelings |
Relabel rules | [] |
monitoring.grafanaDashboard.* |
REMOVED in 2.2.0 — the board is delivered by charts/monitoring (dashboards.enabled there); setting any of these keys is refused with that location named |
— |
The
litmus-coresubchart can ship its own exporter ServiceMonitor — leavemonitoring.serviceMonitor.enabled=falseto avoid duplicate scrapes, and enable it only if you manage scraping here.
The board lives in
dashboards/kates-chaos-infra/and is delivered bycharts/monitoringwith every other board — chart 2.2.0 removed this chart's own copy. It is built fromboard.pybyscripts/gen-dashboards.py; 2.1.0 had moved it out of this chart's hand-written template and corrected four series or labels LitmusChaos does not publish — that README has the table. The board'suidis unchanged throughout, so existing Grafana links keep resolving. Its$namespaceand$operator_deploymentconstants default tolitmus; a Litmus under another name or namespace edits them on the board (or inboard.py), not in values.Every
litmuschaos_*panel on it needs the chaos-exporter, whichlitmus-core.exporter.enabledleaves off by default. The two kube-state-metrics panels fill regardless, which is what makes them the ones to read first.
| Parameter | Description | Default |
|---|---|---|
kyvernoPolicy.enabled |
Pod-security ClusterPolicy (needs Kyverno) | false |
kyvernoPolicy.action |
Audit / Enforce |
Audit |
kyvernoPolicy.namespaces |
Namespaces the policy applies to (empty = release ns) | [] |
kyvernoPolicy.excludeSelector |
Pods skipped (need privileges) | chaosUID Exists |
pdb.enabled |
PodDisruptionBudget (requires selector) |
false |
pdb.minAvailable / maxUnavailable / selector |
PDB config | 1 / "" / {} |
gameday.enabled |
Run the validation Job | false |
gameday.checks |
Data-driven {name, command} checks (empty = default set) |
[] |
engines:
kafka-leader-kill:
enabled: true
appLabel: "strimzi.io/kind=Kafka"
experiment: pod-delete
duration: 60
force: true
targetPods: "krafter-pool-alpha-0"
podsAffectedPerc: "100"
jobCleanUpPolicy: retain
probes:
- name: verify-isr-failover
type: cmdProbe
mode: PostChaos
runProperties: { probeTimeout: "120s", interval: "10s", retry: 6 }
cmdProbe/inputs:
command: "kubectl exec -n kafka krafter-pool-alpha-1 -- kafka-topics.sh --bootstrap-server localhost:9092 --list"
comparator: { type: string, criteria: contains, value: "orders" }rbac:
targetNamespaces:
- { name: kafka, role: target }
- { name: streaming, role: target }
- { name: kates, role: coordinator }
experiments:
targetNamespaces: [kafka, streaming] # install experiments into bothnetworkPolicy:
enabled: true
apiServer:
ipBlock: { cidr: 10.0.0.1/32 }
gameday:
enabled: true
checks:
- { name: CRDs installed, command: "kubectl get crd chaosengines.litmuschaos.io" }
- { name: Brokers Running, command: "kubectl get pods -n kafka -l strimzi.io/kind=Kafka | grep Running" }helm test chaos -n litmusRuns two hooks: the chaos operator is Available, and the Litmus CRDs are established with experiments installed. Both use a scoped, ephemeral test ServiceAccount.
2.0.0 rescopes the chart to the execution plane and removes portal assumptions. Renamed keys are still honored (deprecated, win when set):
| Old | New |
|---|---|
rbac.kafkaNamespace / rbac.katesNamespace |
rbac.targetNamespaces (list of {name, role}) |
networkPolicies.enabled |
networkPolicy.enabled (now structured) |
experiments.image (string) |
images.kubectl / experiments.installer.image |
Behavioral changes to review:
- No web portal. NOTES, Helm tests, and GameDay now validate the operator/CRDs, not a frontend/MongoDB. Install ChaosCenter separately for a UI.
pdb.enablednow requirespdb.selector(the chart ships no stateful workload to protect by default).kyvernoPolicy.excludeContainerswas removed — usekyvernoPolicy.excludeSelector(a real pod selector).- NetworkPolicy adds Kubernetes API-server egress — required by the operator; pin
apiServer.ipBlockon strict clusters.