Local Kubernetes cheatsheet.
kind (Kubernetes in Docker)
brew install kind
kind create cluster
kind create cluster --name dev --image kindest/node:v1.30.0
kind get clusters
kind delete cluster --name dev
With config:
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- { containerPort: 80, hostPort: 80 }
- { containerPort: 443, hostPort: 443 }
- role: worker
- role: worker
kind create cluster --config kind-config.yaml
Load image into kind
docker build -t myapp:dev .
kind load docker-image myapp:dev --name dev
Or use imagePullPolicy: Never to use locally built.
k3d (k3s in Docker)
brew install k3d
k3d cluster create dev --agents 2 -p "80:80@loadbalancer" -p "443:443@loadbalancer"
k3d cluster delete dev
k3d image import myapp:dev -c dev
Lighter than kind; bundles Traefik + LoadBalancer.
minikube
brew install minikube
minikube start
minikube start --driver=docker --cpus=4 --memory=8g
minikube tunnel # exposes LoadBalancer locally
minikube addons enable ingress
minikube image load myapp:dev
More features (addons), heavier.
k3s (single-node Linux)
curl -sfL https://get.k3s.io | sh -
sudo cat /etc/rancher/k3s/k3s.yaml > ~/.kube/config
For lightweight server / edge use.
microk8s (Ubuntu)
sudo snap install microk8s --classic
microk8s status --wait-ready
microk8s enable dashboard dns ingress
Tilt (dev loop)
brew install tilt-dev/tap/tilt
# Tiltfile
docker_build('myreg/web', '.', dockerfile='Dockerfile.dev')
k8s_yaml('manifests/web.yaml')
k8s_resource('web', port_forwards='3000:3000')
tilt up
Auto-rebuilds image + redeploys on file change. Lives in browser dashboard.
Skaffold (alternative)
skaffold init
skaffold dev
# skaffold.yaml
apiVersion: skaffold/v4beta11
kind: Config
build:
artifacts: [{ image: myreg/web, context: . }]
deploy:
kubectl: { manifests: ["manifests/*.yaml"] }
DevSpace, Garden, Telepresence
Other dev workflow tools. Pick whichever fits.
Locally test ingress
# /etc/hosts
127.0.0.1 myapp.local
kind with port mappings + ingress controller → curl myapp.local works.
Local registry
docker run -d --restart=always -p 5000:5000 --name registry registry:2
# Configure kind to use local registry
# See https://kind.sigs.k8s.io/docs/user/local-registry/
Push to localhost:5000 and reference in pod yaml.
Resources
Local clusters need RAM + CPU:
- kind: 2-4 GB minimum.
- k3d: 1-2 GB.
- minikube: 4-8 GB.
Allocate accordingly in Docker Desktop/Colima.
Persistence across restarts
kind clusters survive Docker restarts. To clean: kind delete cluster.
minikube: VM-based, persists.
Cross-platform images
For Apple Silicon: ensure CNI / kube components support arm64. Modern kind/k3d/minikube do.
Connecting host → cluster
kubectl port-forward svc/web 8080:80
kubectl proxy # API access at localhost:8001
Connecting cluster → host
host.docker.internal # Docker Desktop
host.lima.internal # Lima / OrbStack
host.k3d.internal # k3d default
Multi-node testing
# kind config with 3 workers
nodes:
- { role: control-plane }
- { role: worker }
- { role: worker }
- { role: worker }
Test pod anti-affinity, topology, etc.
Common mistakes
- Heavy K8s + heavy Docker Desktop → laptop melts.
- Forgetting to load image → ImagePullBackOff.
- Wrong context → kubectl modifies remote cluster.
- LoadBalancer without
kind: cloud-provider-kindor k3d’s built-in. - Not deleting clusters → wasted resources.
Read this next
If you want my Tilt + kind dev setup, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .