Architecture
Big picture
Litmus has two planes. The Chaos Control Plane (ChaosCenter) is the central tool that constructs, schedules, and visualizes chaos workflows. The Chaos Execution Plane is a chaos agent plus operators that run and monitor the experiment inside a target Kubernetes cluster. This split is stated directly in the README (README.md:31-52).
This repository holds the control plane (under chaoscenter/). The execution plane operators live in separate repositories: chaos-operator reconciles the ChaosEngine resource, chaos-runner starts the experiment job, litmus-go injects the fault, and chaos-exporter exposes results as Prometheus metrics.
Components
graphql/server
The GraphQL API and the heart of the control plane. It is a gqlgen-generated schema served over Gin, with MongoDB as the state store. The server entry point is chaoscenter/graphql/server/server.go:94, the executable schema is built at server.go:124, services are wired at server.go:185, and the /query endpoint is mounted at server.go:192.
authentication
A separate REST authentication service under chaoscenter/authentication/, with a dex integration under chaoscenter/authentication/dex-server/. The entry point is chaoscenter/authentication/api/main.go.
subscriber
The chaos agent that runs in each target cluster. It dials back to the control plane over a websocket and applies pushed manifests to the cluster. Its entry point is chaoscenter/subscriber/subscriber.go:138, and it starts listening for actions at subscriber.go:159.
web, event-tracker, upgrade-agents
The React UI (chaoscenter/web/), an event tracker, and upgrade agents round out the control plane services.
How a request flows
This traces re-running an existing experiment (the RunChaosExperiment mutation) from the API to the target cluster. All anchors are at the pinned commit.
chaoscenter/graphql/server/graph/chaos_experiment_run.resolvers.go:24RunChaosExperimentis the resolver entry point. It runs an RBAC check withauthorization.ValidateRoleat:31, loads the experiment from MongoDB at:43, and callsRunChaosWorkFlowat:50.chaoscenter/graphql/server/pkg/chaos_experiment_run/handler/handler.go:670RunChaosWorkFlowconfirms the target infra is active, sorts revisions newest-first to pick the latest manifest, and branches toRunCronExperimentif the kind iscronworkflow.handler.go:934GenerateExperimentManifestWithProbesexpands probes into the manifest, thenhandler.go:944callschaos_infrastructure.SendExperimentToSubscriber(...).chaoscenter/graphql/server/pkg/chaos_infrastructure/infra_utils.go:226SendExperimentToSubscriberdelegates toSendRequestToSubscriberatinfra_utils.go:206, which pushes the action onto the agent's in-memory channel atinfra_utils.go:220(observer <- newAction).- The subscriber in the target cluster receives the action.
chaoscenter/subscriber/subscriber.go:159startsAgentConnect(chaoscenter/subscriber/pkg/requests/webhook.go:16), which builds thesubscription { infraConnect(...) }query atwebhook.go:17and dials the websocket atwebhook.go:30, then applies the pushed manifest to Kubernetes. - On the server side, the subscription resolver is
chaoscenter/graphql/server/graph/chaos_infrastructure.resolvers.go:272InfraConnect. It registers the channel indata_store.Store.ConnectedInfra[infraID]at:287, then waits onctx.Done()to delete the channel and mark the infra inactive on disconnect.
Key design decisions
The control plane never connects out to a target cluster. Instead, each target cluster's subscriber dials back to the control plane on startup and holds an infraConnect GraphQL subscription open (chaoscenter/subscriber/pkg/requests/webhook.go:17, chaos_infrastructure.resolvers.go:272). At experiment time the server just pushes an action onto that open channel (infra_utils.go:219).
The benefit is reach: a target cluster behind NAT or a firewall only needs outbound connectivity, and one ChaosCenter can govern many clusters.
The trade-off is that connection state lives in the GraphQL server process memory. The ConnectedInfra map of channels is part of StateData in chaoscenter/graphql/server/pkg/data-store/store.go:10-18. A server restart drops every agent connection until each redials, and the state is not shared across replicas. The InfraConnect resolver force-disconnects a duplicate connection for the same infra ID (chaos_infrastructure.resolvers.go:281-285), so the control plane effectively assumes a singleton.
Extension points
- Chaos custom resources (
README.md:39-52): ChaosExperiment is the installable fault template and supports BYOC (bring-your-own-chaos) for third-party fault tooling; ChaosEngine binds a fault to a target and defines steady-state probes; ChaosResult holds the verdict that the exporter reads. - ChaosHub: experiment bundles shared and versioned through
litmuschaos/chaos-charts. - Resilience probes: http, cmd, k8s, and prom probes defined under
chaoscenter/graphql/server/pkg/probe/. - GitOps: experiment sync under
chaoscenter/graphql/server/pkg/gitops.