Skip to content

protocol-security/kurtosis-chaos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kurtosis-chaos

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.

Prerequisites

go get github.com/protocol-security/kurtosis-chaos

Local Setup with Minikube

# 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 gateway

Keep kurtosis gateway running in a separate terminal — it proxies traffic between the Kurtosis engine and the cluster.

Quickstart

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)
    }
}

CLI

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-check

Attach Mode

If 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-check

You 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

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)

Plugin System

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"
)

License

See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages