Documentation menu

Architecture

klimax is one Go binary driving one Lima VM. Everything else — Docker, kind, MetalLB, CoreDNS, and the registry mirrors — lives inside that VM. The only thing that touches your Mac is a single route.

macOS HOST klimax CLI + kubectl ~/.kube/config dev · staging route 172.30.0.0/16 → lima0 vzNAT · lima0 IP LIMA VZ VM DOCKER ENGINE kind bridge  ·  br-xxxx  ·  172.30.0.1/16 CLUSTER · dev control-plane node kindest/node v1.35.0 API :7001 MetalLB → 172.30.1.x CoreDNS forward pods 10.11.0.0/16 CLUSTER · staging control-plane node kindest/node v1.35.0 API :7002 MetalLB → 172.30.2.x CoreDNS forward pods 10.12.0.0/16 Pull-through mirrors: registry-dockerio:5030 · registry-quayio:5010 · registry-gcrio:5020 registry-us-docker-pkgdev:5040 · registry-us-central1-docker-pkgdev:5050
One VM, one bridge, many clusters — all reachable from the host over the single routed CIDR.

Components

ComponentRole
klimax CLIThe single Go binary on your Mac. Drives the Lima VM lifecycle, applies the host route, and orchestrates kind, MetalLB, CoreDNS, and the registries inside the VM.
Lima VZ VMOne Apple Virtualization.framework (vmType: vz) guest, auto-provisioned on first klimax up. Gets a dynamic lima0 IP over vzNAT.
DockerInstalled inside the VM via get.docker.com. Its socket is exposed to the host at ~/.<vmname>.docker.sock (use it with klimax docker-env / docker-context).
kindCreates and manages the Kubernetes clusters (up to 99) as Docker "nodes" on the shared kind bridge network.
MetalLBInstalled in every cluster, each with a dedicated slice of the bridge CIDR so LoadBalancer services get a real, routable VIP.
CoreDNSPatched at cluster creation to forward configured domains (e.g. runlocal.dev) to chosen upstream resolvers.
RegistriesPull-through mirrors for docker.io, quay.io, gcr.io, and Google Artifact Registry (us-docker.pkg.dev, us-central1-docker.pkg.dev), all on the kind network. Cache persists on the host by default.
NetworkingA macOS route sends the bridge CIDR to lima0; iptables rules in the VM exempt cluster→host traffic from SNAT so source IPs are preserved end to end.

Per-cluster allocation

Each cluster gets a slot number N — auto-assigned to the lowest free value (or pinned via a Fleet manifest's num:). klimax derives non-overlapping resources from N:

ResourceValue for slot N
API-server host port700N (e.g. 7001)
Service subnet10.N.0.0/16
Pod subnet10.1N.0.0/16
MetalLB pool172.30.N.1–7 and 172.30.N.16–254
kubeconfig~/.kube/klimax/<name>.kubeconfig
Topology labelstopology.kubernetes.io/region & zone
📐

The product repo also ships rendered high- and low-level diagrams: docs/KLIMAX-HLD-architecture.png and docs/KLIMAX-LLD-architecture.png in bcollard/klimax.

Design principles

  • One VM, many clusters. A single guest amortizes boot cost and RAM across every cluster instead of one VM per cluster.
  • Nothing hardcoded. The lima0 IP is detected at runtime, so klimax coexists with other Lima/Colima VMs that each get their own bridge.
  • No host pollution. Docker, kind, and kubectl live in the VM; the host gets one route and an optional Docker socket — nothing more.
  • Idempotent. klimax up re-applies VM, networking, and registry state safely on every run.