Note: This package is still evolving. A stable API will be available in version 1.
A Go chaos engineering toolkit for Kurtosis enclaves. It manages Kurtosis enclaves, injects Chaos Mesh workflows, monitors health metrics, and collects artifacts.
- Go 1.25+
- Kubernetes cluster (x86_64) with Chaos Mesh installed
- Kurtosis engine running
go get github.com/protocol-security/kurtosis-chaos
# Start a minikube cluster (x86_64 required — Chaos Mesh does not support ARM).
minikube start --cpus=4 --memory=8192 --driver=kvm2 --container-runtime=containerd
# Install Chaos Mesh.
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm install chaos-mesh chaos-mesh/chaos-mesh \
-n chaos-mesh --create-namespace \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock
# Start the Kurtosis engine and open a gateway to the cluster.
kurtosis engine start
kurtosis gatewayKeep kurtosis gateway running in a separate terminal — it proxies traffic between the Kurtosis engine and the cluster.
package main
import (
"context"
"fmt"
"log"
"github.com/protocol-security/kurtosis-chaos/chaos"
"github.com/protocol-security/kurtosis-chaos/kurtosis"
"github.com/protocol-security/kurtosis-chaos/session"
_ "github.com/protocol-security/kurtosis-chaos/artifact/collectors"
_ "github.com/protocol-security/kurtosis-chaos/chaos/generators"
_ "github.com/protocol-security/kurtosis-chaos/health/metrics"
)
func main() {
ctx := context.Background()
client, err := session.NewClient("./results")
if err != nil {
log.Fatal(err)
}
cfg := session.Config{
KurtosisConfig: kurtosis.Config{
PackageID: "github.com/example/my-package",
PackageConfig: `{"participants": 4}`,
},
}
// Each workflow gets a fresh enclave via NewExperiment.
workflows := []chaos.WorkflowGenerator{
networkDelayWorkflow(),
podKillWorkflow(),
stressCPUWorkflow(),
}
for i, wf := range workflows {
expName := fmt.Sprintf("experiment-%d", i)
enclaveName := fmt.Sprintf("enclave-%d", i)
exp, err := client.NewExperiment(expName, enclaveName, cfg)
if err != nil {
log.Fatal(err)
}
report, err := exp.Run(ctx, wf)
if err != nil {
log.Printf("%s failed: %v", expName, err)
continue
}
log.Printf("%s passed: %v, duration: %v", expName, report.Passed, report.Duration)
}
}Build with make build, then run experiments directly from the command line:
./build/kurtosis-chaos session run \
--workflow examples/session/stress-workflow.yaml \
--config examples/session/config.yaml \
--enclave test-enclave \
--output /tmp/stress-test \
--skip-version-checkIf you already have a running enclave, use --attach to skip enclave creation and inject directly into it:
# Start an enclave with Kurtosis.
kurtosis run --enclave test-enclave testutil/testing-package/ \
--args-file testutil/example_package_config.yaml
# Attach and run chaos against the existing enclave.
./build/kurtosis-chaos session run \
--workflow examples/session/stress-workflow.yaml \
--attach \
--enclave test-enclave \
--output /tmp/stress-test-attach \
--skip-version-checkYou can also embed the CLI commands in your own binary, registering custom collectors or health metrics alongside the defaults:
package main
import (
"context"
"os"
"github.com/urfave/cli/v2"
"github.com/protocol-security/kurtosis-chaos/cmd/commands/session"
"github.com/protocol-security/kurtosis-chaos/cmd/commands/version"
"github.com/protocol-security/kurtosis-chaos/cmd/commands/workflow"
// Default plugins.
_ "github.com/protocol-security/kurtosis-chaos/artifact/collectors"
_ "github.com/protocol-security/kurtosis-chaos/chaos/generators"
_ "github.com/protocol-security/kurtosis-chaos/health/metrics"
// Your custom plugins — register via init().
_ "github.com/your-org/your-project/collectors/custom"
_ "github.com/your-org/your-project/metrics/custom"
)
func main() {
app := &cli.App{
Name: "my-chaos-tool",
Commands: []*cli.Command{
version.NewCommand(),
workflow.NewCommand(),
session.NewCommand(),
},
}
app.RunContext(context.Background(), os.Args)
}See /examples for example workflow and config files.
session.NewClient validates the K8s environment, then creates Experiment instances per enclave. Experiment.Run executes the full lifecycle: setup, pre-injection health checks, workflow injection, post-injection checks, and teardown.
client, _ := session.NewClient("./output",
session.WithKubeConfigPath("/path/to/kubeconfig"),
session.WithChaosMeshNamespace("chaos-mesh"),
)
exp, _ := client.NewExperiment("name", "enclave", cfg)
report, err := exp.Run(ctx, workflowConfig)Use AttachExperiment to target an enclave that is already running. Attach mode verifies the enclave exists but does not start or destroy it.
exp, _ := client.AttachExperiment("name", "enclave", cfg)
report, err := exp.Run(ctx, workflowConfig)Health metrics, chaos generators, and artifact collectors use a generic registry.Registry[T] with tag-based presets. Plugins self-register via init() and are activated by blank import:
import (
_ "github.com/protocol-security/kurtosis-chaos/artifact/collectors"
_ "github.com/protocol-security/kurtosis-chaos/health/metrics"
)See LICENSE for details.