Real Kubernetes on your Mac, without an always-on VM.
- Zero idle cost. No cluster? Nothing runs — no background VM, no daemon. Delete a cluster and your Mac returns to baseline.
- No external runtime. Built on Apple's Containerization framework, which ships with macOS. No Docker Desktop, no Rancher Desktop, no extra download.
- microVM isolation per Pod. Each Pod gets its own lightweight Linux VM, created on demand and freed when the Pod stops.
- kind-compatible config. Multi-node clusters,
extraPortMappings, nodeSelectors — bring your existing cluster config.
| kanata | kind | colima / OrbStack | |
|---|---|---|---|
| When no cluster exists | Nothing runs | Container runtime VM stays up | Linux VM stays up |
| Runtime dependency | None (built into macOS) | Container runtime required | — |
| Pod isolation | microVM per Pod | Container namespace | Container namespace |
| NodePort from Mac | localhost:<port> automatically |
Needs extraPortMappings |
Yes |
| Persistence across restart | Yes (etcd + PVC) | No | Yes |
RAM while a cluster is running is comparable across all tools (~1-2 GB for a single idle node). kanata's difference is what happens when you're not working: it costs nothing.
macOS 26 (Tahoe) or later · Apple Silicon (arm64) · Kubernetes 1.36+
brew tap mazrean/tap
brew install mazrean/tap/kanataOn first use, macOS may prompt for system permissions (vmnet framework). Grant access under System Settings → Privacy & Security.
# Create a cluster — first cluster takes ~1–2 min
kanata create cluster dev
# Verify the node is Ready
kubectl --context kanata-dev get nodes
# Deploy nginx
kubectl --context kanata-dev apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- name: hello
image: nginx:alpine
ports:
- containerPort: 80
EOF
kubectl --context kanata-dev wait pod/hello --for=condition=Ready --timeout=120s
# Access it
kubectl --context kanata-dev port-forward pod/hello 8080:80
# → http://localhost:8080- Single-node and multi-node clusters —
kanata create cluster dev --config cluster.yamlaccepts kind-compatible YAML - Pod lifecycle — init containers, multi-container Pods, ConfigMap/Secret/emptyDir/PVC/downwardAPI/projected volumes, postStart/preStop hooks, liveness/readiness/startup probes (exec, httpGet, tcpSocket)
kubectl logs/exec/attach/port-forward/cp- ClusterIP, NodePort, and LoadBalancer Services — NodePort and LoadBalancer Services are reachable at
localhost:<nodePort>on your Mac automatically, noport-forwardneeded - Ingress — no bundled controller, but standard controllers (e.g. Traefik) deploy and work as-is
- Cluster DNS —
<svc>.<ns>.svc.cluster.localresolves via CoreDNS; external queries forwarded to the Mac's active resolvers - Persistent storage — built-in
standardStorageClass; PVCs andvolumeClaimTemplatesprovisioned automatically kubectl top nodes/kubectl top pods— metrics-server deployed automatically- RBAC fully enforced — ClusterRole, Role, RoleBinding, ServiceAccount all work; Helm charts that create RBAC resources work without modification
- Automatic kubeconfig merge —
~/.kube/configupdated non-destructively oncreate cluster; your current context is untouched
- macOS 26 + Apple Silicon only — no Intel, no macOS 15 or earlier
- No
kanata start/kanata stop— cluster lifecycle is managed vialaunchctl; see Operations - Single control-plane node only (no HA)
- Some Pod security fields are unsupported and send the Pod to
Failed— see Troubleshooting - Headless Services (
clusterIP: None), ExternalName Services, NetworkPolicy enforcement, and sessionAffinity are not supported volumes[].hostPathis not supported — use a PVC instead
For full details, see the docs.
- User Guide — installation, configuration, networking, operations, troubleshooting
- Developer Guide — architecture, build setup, testing, contributing