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.
Components
| Component | Role |
|---|---|
| marina CLI | The 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 VM | One Apple Virtualization.framework (vmType: vz) guest, auto-provisioned on first marina up. Gets a dynamic lima0 IP over vzNAT. |
| Docker | Installed 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). |
| kind | Creates and manages the Kubernetes clusters (up to 99) as Docker "nodes" on the shared kind bridge network. |
| MetalLB | Installed in every cluster, each with a dedicated slice of the bridge CIDR so LoadBalancer services get a real, routable VIP. |
| CoreDNS | Patched 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 DNS | An 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. |
| Registries | Pull-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. |
| Networking | A 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:
| Resource | Value for slot N |
|---|---|
| API-server host port | 700N (e.g. 7001) |
| Service subnet | 10.N.0.0/16 |
| Pod subnet | 10.1N.0.0/16 |
| MetalLB pool | 172.30.N.1–7 and 172.30.N.16–254 |
| kubeconfig | ~/.kube/marina/<name>.kubeconfig |
| Topology labels | topology.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
lima0IP 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 upre-applies VM, networking, and registry state safely on every run.