How the ChaosBlade Kubernetes Operator Manages the Chaos Experiment Lifecycle

The ChaosBlade CLI delegates lifecycle management to a Kubernetes operator through a Go wrapper that implements a create‑monitor‑destroy state machine via the ChaosBlade Custom Resource Definition (CRD).

ChaosBlade implements cloud‑native chaos engineering by delegating experiment orchestration to a purpose‑built Kubernetes operator. The CLI communicates with this operator through a thin Go wrapper located in exec/kubernetes, which translates command‑line flags into ChaosBlade Custom Resources (CRs) and polls their status until the desired phase is reached.

State Machine Architecture

The Kubernetes executor follows a deterministic state machine orchestrated by the Executor struct in exec/kubernetes/executor.go.

The Executor Entry Point

The Exec function serves as the single entry point for all lifecycle operations:

func (e *Executor) Exec(uid string, ctx context.Context, expModel *spec.ExpModel) *spec.Response

Source: [exec/kubernetes/executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L30-L78)

  • Operation detection – The wrapper checks spec.IsDestroy(ctx) to branch between creation and destruction flows.
  • Client initializationgetClient(kubeconfig, proxyURL, token) builds a controller-runtime client that communicates with the operator’s API server.
  • Status polling – After issuing the initial request, the executor repeatedly invokes QueryStatus until the experiment reaches a terminal phase or the configured timeout expires (default 20 seconds).

Creating a Chaos Experiment

When IsDestroy returns false, the executor triggers the creation flow defined in the create helper function.

Model Conversion to CR

The convertExpModelToChaosBladeObject function (lines 107‑128) transforms the CLI’s experiment model into a structured CR containing:

  • Spec.Experiments – Scope, target, action, and flag list derived from expModel.
  • Metadata.Name – Set to the provided UID for unique identification.

Source: convertExpModelToChaosBladeObject

CR Creation and Phase Validation

The create function (lines 55‑63) persists the object via client.Create and immediately fetches the resulting CR:

  1. If Status.Phase equals ClusterPhaseRunning, the CLI returns immediate success.
  2. If the phase is pending, execution falls back to the QueryStatus polling loop to wait for operator reconciliation.

Source: create

Polling and Status Management

The QueryStatus function implements the observation layer of the lifecycle state machine.

Phase Interpretation

Located at lines 95‑117 and 122‑144, QueryStatus performs the following:

  • Fetch – Retrieves the ChaosBlade CR using the stored UID via get(client, uid).
  • Evaluate – Maps Status.Phase to CLI outcomes:
    • ClusterPhaseRunning → Success for create operations.
    • ClusterPhaseDestroyed → Success for destroy operations.
    • Error or other phases → Failure, with ExpStatuses propagated to the response.
  • Result shapingCreateStatusResult aggregates operator‑supplied status details into the generic spec.Response format.

Source: status handling in [exec/kubernetes/executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L95-L117)

Destroying Experiments

Destruction follows the reverse path of creation, ensuring clean removal of chaos resources.

Deletion Flow

The destroy function (lines 95‑104) orchestrates teardown:

  1. Retrieve client – Re‑initializes the controller‑runtime client using stored configuration.
  2. Issue deletion – Calls delete(ctx, cli) which executes client.Delete on the CR identified by the context UID.
  3. Confirm cleanup – Invokes QueryStatus with operation = QueryDestroy, polling until the operator reports ClusterPhaseDestroyed or the timeout elapses.

Source: destroy and delete functions in [exec/kubernetes/executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L95-L104) and lines 64‑73

Practical CLI Examples

Create a Kubernetes Node CPU Experiment

blade create k8s node-cpu fullload \
    --names cn-hangzhou.192.168.0.205 \
    --cpu-percent 80 \
    --kubeconfig ~/.kube/config

This command triggers convertExpModelToChaosBladeObject, creates the CR via client.Create, and polls QueryStatus until ClusterPhaseRunning is observed.

Destroy an Experiment by UID

blade destroy --uid a1b2c3d4-5678-90ab-cdef-111213141516

The wrapper extracts the UID, calls delete on the CR, and waits for ClusterPhaseDestroyed confirmation.

Custom Polling Interval

blade create k8s pod-network loss \
    --names mypod \
    --loss 60 \
    --waiting-time 30s

The --waiting-time flag overrides the default 20 second ticker interval in Executor.Exec (lines 64‑90).

Summary

  • Delegation model – The CLI does not inject faults directly; it delegates to the chaosblade-operator via CRD operations in exec/kubernetes/executor.go.
  • State machine – Lifecycle progression follows a strict create → monitor → destroy flow implemented through Exec, create, and destroy helper functions.
  • Polling mechanismQueryStatus translates Kubernetes CR phases (ClusterPhaseRunning, ClusterPhaseDestroyed, Error) into CLI‑level responses with a configurable waiting-time default.
  • Resource identification – Experiments are tracked by UID stored in Metadata.Name, persisted through data/experiment.go, and used for correlation during status queries and deletion.

Frequently Asked Questions

How does the ChaosBlade CLI communicate with the Kubernetes operator?

The CLI uses a controller-runtime client built by getClient in exec/kubernetes/executor.go to submit ChaosBlade CRs to the operator’s API server. This client authenticates via kubeconfig, proxy URL, or token, then performs standard create/delete operations while polling status until the operator reconciles the desired state.

What happens if a chaos experiment fails to start?

If QueryStatus detects any phase other than ClusterPhaseRunning during creation (or ClusterPhaseDestroyed during teardown), the CLI interprets this as failure. The function extracts detailed error context from ExpStatuses within the CR and returns a spec.Response containing the failure reason, allowing users to diagnose whether the fault injection preparation failed or the operator encountered reconciliation errors.

How is the chaos experiment uniquely identified across the lifecycle?

Each experiment receives a UID generated by the CLI (stored in Metadata.Name of the CR) that acts as the primary key. This UID is passed through Exec, persisted in data/experiment.go, and used by QueryStatus and delete to correlate CLI commands with the specific Custom Resource managed by the operator.

What is the default timeout for lifecycle operations?

The executor defaults to 20 seconds of polling via QueryStatus, configurable through the --waiting-time flag. This ticker loop (implemented in Executor.Exec lines 64‑90) repeatedly checks CR status until the operator reports a terminal phase or the duration expires, ensuring the CLI remains synchronous while the operator performs asynchronous reconciliation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →