Skip to content

Vanilla (Kind)

Kind (Kubernetes in Docker) runs upstream Kubernetes clusters using Docker containers as nodes. It is fast (30–60 s), Docker-only, and uses standard kind.yaml files with no vendor lock-in. For common workflows and use cases, see Use Cases.

Requires Docker (installation prerequisites).

Terminal window
ksail cluster init --name my-cluster --distribution Vanilla --control-planes 1 --workers 2
ksail cluster create
ksail cluster info && kubectl get nodes # verify
ksail cluster delete # cleanup

ksail cluster init creates ksail.yaml (KSail config) and kind.yaml (Kind cluster config).

The ksail.yaml file controls your cluster:

# yaml-language-server: $schema=https://raw.githubusercontent.com/devantler-tech/ksail/main/schemas/ksail-config.schema.json
apiVersion: ksail.io/v1alpha1
kind: Cluster
spec:
cluster:
distribution: Vanilla
distributionConfig: kind.yaml

Customize Kind behavior in kind.yaml:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
# Port mapping for accessing services
extraPortMappings:
- containerPort: 80
hostPort: 8080
protocol: TCP
- role: worker
- role: worker

Enable LoadBalancer services with Cloud Provider KIND:

ksail.yaml
apiVersion: ksail.io/v1alpha1
kind: Cluster
spec:
cluster:
distribution: Vanilla
loadBalancer: Enabled

When enabled, KSail installs Cloud Provider KIND, which creates cpk-* Docker containers as LoadBalancer proxies and assigns external IPs. See LoadBalancer Configuration for details.

KSail enables docker.io, ghcr.io, quay.io, and registry.k8s.io mirrors by default. The --mirror-registry flag uses replace semantics: any values you provide completely replace the full default list, so omitting a registry removes it. To customize mirrors while keeping the defaults, include all four:

Terminal window
ksail cluster init --name my-cluster --distribution Vanilla \
--mirror-registry 'docker.io=https://registry-1.docker.io' \
--mirror-registry 'ghcr.io=https://ghcr.io' \
--mirror-registry 'quay.io=https://quay.io' \
--mirror-registry 'registry.k8s.io=https://registry.k8s.io'

Symptom: ksail cluster create fails with Docker errors.

Terminal window
docker ps # Verify Docker is running
df -h # Check disk space
docker system prune -f
ksail cluster create

Symptom: kubectl get nodes shows NotReady status.

Terminal window
kubectl describe node <node-name>
kubectl get pods -n kube-system | grep cilium
kubectl rollout restart daemonset/cilium -n kube-system

Symptom: LoadBalancer service never gets EXTERNAL-IP. Ensure loadBalancer: Enabled is set in ksail.yaml, then run ksail cluster update. See LoadBalancer Configuration.

Symptom: address already in use error during cluster creation. List and delete conflicting Kind clusters:

Terminal window
kind get clusters
kind delete cluster --name <conflicting-cluster>

Symptom: Cluster creation fails with resource errors.

Terminal window
ksail cluster init --name my-cluster --distribution Vanilla --control-planes 1 --workers 0
# WARNING: removes ALL unused images and volumes — can affect other Docker projects
docker system prune -a --volumes

Create production-like topologies:

Terminal window
ksail cluster init --name multi-node --distribution Vanilla --control-planes 3 --workers 5

Set the node image in kind.yaml to pin a Kubernetes version. Check Kind release notes for available images. Edit the nodes: section of the generated kind.yaml:

# kind.yaml (partial — nodes: section)
nodes:
- role: control-plane
image: kindest/node:v1.35.1
- role: worker
image: kindest/node:v1.35.1

Override the default CNI:

Terminal window
ksail cluster init --name my-cluster --distribution Vanilla --cni Calico

Expose services on host ports. Edit the nodes: section of the generated kind.yaml:

# kind.yaml (partial — nodes: section)
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080 # NodePort service
hostPort: 8080
protocol: TCP

Access services at http://localhost:8080.

Enable persistent storage:

Terminal window
ksail cluster init --name my-cluster --distribution Vanilla --csi Enabled

The kind.yaml generated by ksail cluster init is standard Kind config — use it directly without KSail:

Terminal window
kind create cluster --config kind.yaml
kind export kubeconfig