# How the ChaosBlade Kubernetes Operator Manages the Chaos Experiment Lifecycle

> Discover how the ChaosBlade Kubernetes operator streamlines chaos experiment management. Learn about the create-monitor-destroy lifecycle powered by the ChaosBlade CRD for efficient chaos engineering.

- Repository: [ChaosBlade/chaosblade](https://github.com/chaosblade-io/chaosblade)
- Tags: how-to-guide
- Published: 2026-02-27

---

**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`](https://github.com/chaosblade-io/chaosblade/blob/main/exec/kubernetes/executor.go).

### The Executor Entry Point

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

```go
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/main/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 initialization** – `getClient(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`](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L107-L128)*

### 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`](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L55-L63)*

## 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 shaping** – `CreateStatusResult` 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/main/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/main/exec/kubernetes/executor.go)](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L95-L104) and [lines 64‑73](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go#L64-L73)*

## Practical CLI Examples

### Create a Kubernetes Node CPU Experiment

```bash
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

```bash
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

```bash
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`](https://github.com/chaosblade-io/chaosblade/blob/main/exec/kubernetes/executor.go).
- **State machine** – Lifecycle progression follows a strict **create → monitor → destroy** flow implemented through `Exec`, `create`, and `destroy` helper functions.
- **Polling mechanism** – `QueryStatus` 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`](https://github.com/chaosblade-io/chaosblade/blob/main/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`](https://github.com/chaosblade-io/chaosblade/blob/main/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`](https://github.com/chaosblade-io/chaosblade/blob/main/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.