Releases: mazrean/kanata
Releases · mazrean/kanata
Release list
kanata v0.1.0
The first public release of kanata — a Kubernetes agent that turns your Mac into a real Kubernetes worker node using Apple's Containerization framework. Every Pod runs in its own lightweight Linux microVM: no Docker Desktop, no always-on background VM, nothing running when you have no clusters.
Highlights
- Zero idle cost. When no cluster exists, 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 required.
- 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.
Installation
brew tap mazrean/tap
brew install mazrean/tap/kanataQuick Start
kanata create cluster dev
kubectl --context kanata-dev get nodes
kubectl --context kanata-dev run hello --image=nginx:alpine --port=80What's Included
Cluster Lifecycle
- Single-node and multi-node clusters via
kanata create cluster <name> - kind-compatible YAML config (
--config cluster.yaml) - Embedded control plane (etcd, kube-apiserver, kube-controller-manager, kube-scheduler) — all as static pods
- Automatic kubeconfig merge into
~/.kube/config(non-destructive, preserves your current context) - Persistent etcd storage — cluster state survives restarts
- launchd integration — clusters survive macOS reboots
Pod Lifecycle
- Init containers, multi-container Pods
- postStart / preStop lifecycle hooks
- Liveness, readiness, and startup probes (exec, httpGet, tcpSocket)
- Named port resolution for probes, lifecycle hooks, and Services
- ConfigMap, Secret, emptyDir, PVC, downwardAPI, and projected volumes
- Image ENV variable merging
Networking
- ClusterIP — fully functional, with DNS-based discovery
- NodePort — automatically reachable at
localhost:<nodePort>on the Mac host - LoadBalancer — VIP allocation (pool .200–.250), reachable from the host
- Ingress — standard controllers (e.g. Traefik) deploy and work as-is
- Cluster DNS — CoreDNS with
<svc>.<ns>.svc.cluster.localresolution and external domain forwarding via the Mac's active resolvers - Cross-node Pod-to-Pod — works out of the box in multi-node clusters
extraPortMappings— kind-compatible stable host port bindings
Storage
- Built-in
standardStorageClass with automatic PVC provisioning volumeClaimTemplatesfor StatefulSets
Observability
kubectl logs/kubectl logs -fkubectl exec/kubectl attachkubectl port-forwardkubectl cpkubectl top nodes/kubectl top pods— metrics-server deployed automatically
Security
- RBAC fully enforced (ClusterRole, Role, RoleBinding, ServiceAccount)
- mTLS between kubelet and API server (bootstrap token flow)
- Node authorizer with proper RBAC scoping
Requirements
- macOS 26 (Tahoe) or later
- Apple Silicon (arm64)
- Kubernetes 1.36+
Known Limitations
- macOS 26 + Apple Silicon only — no Intel, no macOS 15 or earlier
- Single control-plane node only (no HA)
- No
kanata start/kanata stop— cluster lifecycle is managed vialaunchctl - Headless Services (
clusterIP: None), ExternalName Services, NetworkPolicy, and sessionAffinity are not supported hostPathvolumes are not supported — use a PVC instead- Pod IPv6 egress is not available (macOS NAT66 does not NAT ULA source addresses)
- Some Pod security fields are unsupported and will send the Pod to
Failed