Event-Driven Triggers
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.