klimax is now marina. Same tool, new name since v0.3. Existing install? Migrate with marina migrate →
Documentation menu

Architecture

marina is one Go binary driving one Lima VM. Everything else — Docker, kind, MetalLB, CoreDNS, the registry mirrors and the local DNS server — lives inside that VM. All marina changes on your Mac itself are a single route and one resolver file.

macOS HOST marina CLI + kubectl ~/.kube/config dev · staging route 172.30.0.0/16 → lima0 /etc/resolver/demo.internal → 172.30.255.53 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.36.1 API :7001 MetalLB → 172.30.1.x CoreDNS forward · ExternalDNS pods 10.11.0.0/16 CLUSTER · staging control-plane node kindest/node v1.36.1 API :7002 MetalLB → 172.30.2.x CoreDNS forward · ExternalDNS 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 Local DNS for *.demo.internal: marina-dns-etcd 172.30.255.52 marina-dns (CoreDNS) 172.30.255.53 — fed by each cluster's ExternalDNS
One VM, one bridge, many clusters — all reachable from the host over the single routed CIDR.

Components

ComponentRole
marina CLIThe single Go binary on your Mac. Drives the Lima VM lifecycle, applies the host route, and orchestrates kind, MetalLB, CoreDNS, the registries and the local DNS zone inside the VM.
Lima VZ VMOne Apple Virtualization.framework (vmType: vz) guest, auto-provisioned on first marina 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 marina 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 demo.internal to the local DNS server, plus any configured domains (e.g. runlocal.dev) to chosen upstream resolvers.
Local DNSAn etcd and a CoreDNS container on the kind network serve demo.internal; ExternalDNS in each cluster publishes its LoadBalancer Services there, and /etc/resolver/demo.internal sends the Mac's lookups to it. See Local DNS names.
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:). marina 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/marina/<name>.kubeconfig
Topology labelstopology.kubernetes.io/region & zone
📐

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

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 marina 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. marina up re-applies VM, networking, and registry state safely on every run.