Skip to content

KWOK

KWOK creates ultra-fast simulated Kubernetes clusters for control-plane-level testing. This guide walks you through creating your first KWOK cluster, understanding when to use it, and exploring common use cases.

KWOK (Kubernetes WithOut Kubelet) is a toolkit that enables simulating thousands of Kubernetes nodes and pods without running actual containers. KSail uses kwokctl’s Docker runtime to run etcd, kube-apiserver, and the kwok-controller as Docker containers. Nodes and pods are simulated at the API level — they appear Ready and Running but consume no compute resources.

Use caseNotes
Control-plane testingValidates API operations, RBAC, and admission webhook configuration. Webhook objects are accepted by the API server, but in-cluster webhook execution is not supported — no real pod serves the endpoint.
CI/CD speedClusters start in seconds with minimal resource usage.
Scale testingSimulate thousands of nodes/pods without real infrastructure.
Tooling validationTest kubectl, Helm, and GitOps workflows against a real API server.

Consider other distributions when you need real containers (Vanilla, K3s), production-grade immutable infrastructure (Talos), or isolated virtual clusters (VCluster).

Create a new KWOK configuration:

Terminal window
mkdir my-kwok-cluster
cd my-kwok-cluster
ksail cluster init \
--name dev-cluster \
--distribution KWOK \
--gitops-engine ArgoCD

This generates:

  • ksail.yaml — KSail cluster configuration
  • kwok/ — KWOK kustomize configuration directory:
    • kustomization.yaml — Kustomize entrypoint referencing simulation CRDs
    • simulation.yaml — ClusterLogs, ClusterExec, ClusterAttach, ClusterPortForward CRDs
    • node-not-ready.yaml — CEL-based node NotReady chaos stage (opt-in)
    • pod-failure.yaml — CEL-based pod failure chaos stage (opt-in)
  • k8s/kustomization.yaml — Directory for Kubernetes manifests
Terminal window
ksail cluster create

KSail creates Docker containers for the control plane (etcd, kube-apiserver, kwok-controller), configures simulation CRDs, and sets up kubectl automatically.

Terminal window
# Check cluster info
ksail cluster info
# List running containers
docker ps | grep kwok
# Test kubectl access
kubectl get nodes
kubectl get pods --all-namespaces
Terminal window
# Create a deployment — pods are simulated as Running
kubectl create deployment nginx --image=nginx:1.25
kubectl get pods -w # Pods transition to Running via KWOK Stage simulation
# Logs work via ClusterLogs CRD
kubectl logs deploy/nginx
Terminal window
ksail cluster delete

For general KSail YAML options, see the Configuration Reference. KSail scaffolds a kwok/ kustomize directory (shown in Quick Start) that KWOK’s config loader assembles automatically.

The kustomization.yaml references simulation.yaml by default. Chaos stages are included as commented-out resources — uncomment them to enable:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- simulation.yaml
# Uncomment to enable chaos simulation stages (KWOK v0.7.0+ CEL support):
# - node-not-ready.yaml
# - pod-failure.yaml

The simulation.yaml file contains four Cluster-level CRDs that KWOK does not provide by default:

CRDEnables
ClusterLogskubectl logs to return configurable output
ClusterExeckubectl exec to run commands
ClusterAttachkubectl attach
ClusterPortForwardkubectl port-forward

See the KWOK documentation for all available CRDs and configuration options.

KSail includes two example chaos stages that use KWOK v0.7.0 CEL expression support for conditional node and pod simulation. These stages use label-based selectors with CEL expressions instead of the older JQ-based syntax.

Node NotReady (node-not-ready.yaml) — Transitions nodes to NotReady status when labeled:

Terminal window
# Enable the stage by uncommenting it in kwok/kustomization.yaml, then:
kubectl label node <name> node-not-ready.stage.kwok.x-k8s.io=true

Pod Failure (pod-failure.yaml) — Fails running pods when labeled:

Terminal window
# Enable the stage by uncommenting it in kwok/kustomization.yaml, then:
kubectl label pod <name> pod-failure.stage.kwok.x-k8s.io=true

You can create additional custom stages by adding YAML files to the kwok/ directory and referencing them in kustomization.yaml. See the KWOK Stages Configuration documentation for the full Stage API.

The following components are not installed on KWOK clusters because they require real container execution:

ComponentReason
CNI (Cilium, Calico)KWOK has no real network dataplane. spec.cluster.cni has no effect.
CSI (Local Path Provisioner)Requires real container execution; would never become truly ready.
cert-managerWebhook pods must serve real TLS endpoints.
FluxSimulated flux-operator pod never registers Flux CRDs; use ArgoCD instead.
Policy engines (Kyverno, Gatekeeper)Register global MutatingWebhookConfigurations whose endpoints are never served, breaking subsequent Helm installs.

KSail emits a warning and skips each of these when spec.cluster.distribution: KWOK is set. For a full compatibility overview, see the Support Matrix.

Symptom: ksail cluster create fails.

Terminal window
docker ps # Docker must be running
docker info # Ensure Docker daemon is healthy

Symptom: kubectl get nodes returns connection errors.

Terminal window
kubectl config current-context # Should show kwok-<cluster-name>
kubectl config use-context kwok-dev-cluster # Switch if needed

Symptom: Pods stay in Pending state.

This typically means KWOK’s Stage configurations are missing. Ensure the kwok/ directory is present or recreate the cluster:

Terminal window
ksail cluster delete
ksail cluster init --distribution KWOK
ksail cluster create