Event-Driven Triggers

Delay chaos injection until specific conditions are met

The Triggers framework allows you to delay chaos injection until specific environmental conditions are met. Instead of simply waiting a fixed amount of time or relying entirely on manual signaling, Krkn can actively poll your environment and automatically proceed with the scenario once all your defined triggers are satisfied.

This is especially useful for event-driven chaos, such as waiting for a background deployment to finish, waiting for a service to become healthy, or synchronizing Krkn with an external CI/CD pipeline.

Configuration

Triggers are configured inside your Krkn scenario files under the triggers block.

triggers:
  mode: all_of      # Optional: all_of | any_of (default: all_of)
  timeout: 300      # Optional: Max time to wait in seconds (default: 300)
  interval: 5       # Optional: Polling interval in seconds (default: 5)
  on_timeout: skip  # Optional: skip | fail | run_anyway (default: skip)
  conditions:
    - type: command
      cmd: "kubectl get pods -n my-app | grep Running"
    - type: http
      url: "http://my-service.default.svc:8080/health"
      expected_status: 200
    - type: k8s
      apiVersion: apps/v1
      kind: Deployment
      name: nginx
      namespace: default
      condition: "status.readyReplicas >= 1"

Global Trigger Settings

Parameter Description Default
mode all_of requires all conditions to pass. any_of proceeds when at least one condition passes. all_of
timeout Maximum time (in seconds) to wait for conditions to be met before timing out. 300
interval How often (in seconds) Krkn polls the conditions. 5
on_timeout Behavior if timeout is reached. skip: skips scenario. fail: fails scenario. run_anyway: proceeds with chaos anyway. skip

Trigger Types

1. Command Trigger

The command trigger runs a shell command and passes if the command exits with a 0 (success) return code.

  - type: command
    cmd: "kubectl get nodes | grep Ready"
Field Description
type Must be command
cmd The shell command to execute.

2. HTTP Trigger

The http trigger polls an HTTP/HTTPS endpoint and passes when the endpoint returns the expected status code and (optionally) matches a substring in the response body.

  - type: http
    url: "https://api.my-app.com/ready"
    method: "GET"
    expected_status: 200
    bearer_token: "my-secret-token"
    body_contains: "status: healthy"
Field Description Default
type Must be http
url The URL to poll. (Required)
method The HTTP method (GET, POST, etc.). GET
expected_status The HTTP status code required to pass. 200
headers A dictionary of custom HTTP headers. {}
bearer_token Automatically sets the Authorization: Bearer <token> header.
body_contains If set, the response body must contain this exact substring.

3. Kubernetes Trigger

The k8s trigger polls a Kubernetes resource and passes when a field on the resource matches a condition. It is kind-agnostic — the same code path handles built-in resources (Deployments, Pods, Nodes) and CRDs (e.g. KubeVirt VirtualMachineInstanceMigration) using the Kubernetes dynamic client.

This is useful for waiting on rollout readiness, catching narrow timing windows during live migrations, or any case where a native API check replaces a brittle kubectl wrapper.

Basic example — wait for a Deployment to be ready

  - type: k8s
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
    namespace: default
    condition: "status.readyReplicas >= 1"

CRD example — wait for a KubeVirt live migration to reach Running

  - type: k8s
    apiVersion: kubevirt.io/v1
    kind: VirtualMachineInstanceMigration
    name: test-migration
    namespace: vm-ns
    condition: "status.phase == Running"

Cross-cluster example — use a specific kubeconfig context

  - type: k8s
    context: staging-cluster
    apiVersion: apps/v1
    kind: Deployment
    name: frontend
    namespace: production
    condition: "status.readyReplicas >= 3"
Field Description Default
type Must be k8s
apiVersion Kubernetes API version (e.g. apps/v1, v1, kubevirt.io/v1). (Required)
kind Resource kind (e.g. Deployment, Pod, Node, or any CRD kind). (Required)
name Name of the specific resource to watch. (Required)
namespace Namespace of the resource. Omit for cluster-scoped resources like Nodes.
context Kubeconfig context to use. Omit to use the default context. Useful for cross-cluster triggers.
condition Expression to evaluate against the resource. Uses dot-path field access and a comparison operator. (Required)

Condition syntax

Conditions follow the format field.path <operator> value:

Operator Description Example
== Equal (numeric-aware) status.phase == Running
!= Not equal status.phase != Pending
>= Greater than or equal status.readyReplicas >= 1
<= Less than or equal status.replicas <= 5
> Greater than status.availableReplicas > 0
< Less than status.unavailableReplicas < 1

The field path uses dot notation to traverse nested fields (e.g. status.readyReplicas). For == and !=, numeric values are compared numerically when possible, falling back to string comparison. For ordering operators (>=, <=, >, <), both sides must be numeric.