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

Getting started

From an empty Mac to a routable, multi-cluster kind lab in a few commands. By the end you'll curl a LoadBalancer service by its real IP — straight from your shell, no port-forwarding.

Prerequisites

  • macOS 13 Ventura or later — Apple Virtualization.framework (vz) is required.
  • Apple Silicon (arm64). x86_64 is untested.
  • sudo access — prompted once on marina up to add the host route (and on marina destroy to remove it). marina down needs no sudo, and marina sudoers retires the prompt for good.

Docker, kind, kubectl, and the Lima guest agent are downloaded and provisioned inside the VM on the first marina up — you don't install them yourself.

1. Install

The recommended path is the Homebrew cask:

$ brew tap bcollard/marina
$ brew trust --tap bcollard/marina
$ brew install --cask marina

Prefer to build from source? See the README on GitHub.

⬆

Already have marina installed? Upgrading is brew upgrade --cask marina followed by a VM rebuild — see Upgrading marina.

Shell completion (optional)

# zsh — add to ~/.zshrc to persist
$ source <(marina completion zsh)

2. Bring up the VM

This single, idempotent command creates the Lima VM, installs Docker, applies the L3 networking, and starts the registry mirrors:

$ marina up
🔑

The first run prompts for sudo once — it adds a macOS route for the kind bridge CIDR (172.30.0.0/16 by default) pointing at the VM. After that, host→cluster traffic is pure L3. See Networking & L3 routing.

🔀

Already running another Lima-based tool? No action needed — network.disablePortMirroring defaults to true, so marina coexists with Rancher Desktop, Colima, or another Lima/kind manager out of the box: its kubeconfigs address the VM's lima0 IP directly instead of racing for 127.0.0.1. Only if you run a single marina VM and want stable loopback kubeconfigs should you set it to false in ~/.marina/config.yaml before your first marina up (it's a VM-level setting; changing it later needs a marina destroy && marina up). Details in Networking.

Stop up prompting for a password

That route is the only thing marina needs root for. Grant just those two /sbin/route commands and every later marina up runs unattended:

$ marina sudoers | sudo tee /etc/sudoers.d/marina >/dev/null
$ sudo chmod 0440 /etc/sudoers.d/marina
$ marina sudoers --check
✓ Passwordless route rules for 172.30.0.0/16 are in effect.

The rules are scoped to your configured bridge CIDR, with the gateway wildcarded because macOS assigns the VM's address dynamically — regenerate them if you change network.kindBridgeCIDR. Full detail in the CLI reference.

Start the VM at login (optional)

With those rules in place, marina can bring the VM up for you at login via a per-user launchd agent:

$ marina autostart install
$ marina autostart status

Output lands in ~/.marina/logs/autostart.log; marina autostart uninstall removes it again.

🔑

Do the sudoers step first. launchd can't answer a password prompt, so without those rules the VM starts at login but the host route is never added — and nothing in 172.30.0.0/16 is reachable from your Mac.

3. Create your first cluster

$ marina cluster create dev

marina provisions a kind cluster, installs MetalLB with a dedicated IP pool, wires CoreDNS forwarding, and (by default) merges the new context into ~/.kube/config. Switch to it like any other context:

$ kubectl config use-context dev
# or, if you use kubectx:
$ kubectx dev

4. Prove the routing works

Run the built-in smoke test — it deploys an nginx Deployment and a LoadBalancer Service, then waits for MetalLB to assign a VIP:

$ marina cluster e2e-test-nginx

Now reach that service by its real IP, from your Mac — no kubectl port-forward:

$ VIP=$(kubectl get svc nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ curl http://$VIP/
<!DOCTYPE html> ... Welcome to nginx!

It also has a name. marina publishes every LoadBalancer Service as <service>.<namespace>.<cluster>.demo.internal:

$ curl http://nginx.default.dev.demo.internal/
<!DOCTYPE html> ... Welcome to nginx!
❄

That VIP comes from the cluster's MetalLB pool inside 172.30.0.0/16, which your Mac routes directly to the VM. Pod IPs and Service ClusterIPs are reachable the same way.

5. Go multi-cluster

The whole point of marina — spin up as many clusters as you need (up to 99). Each gets its own API-server port, subnets, and MetalLB pool:

$ marina cluster create staging
$ marina cluster list
$ kubectx staging

6. Stop or tear down

# Stop the VM — keeps clusters and the registry cache
$ marina down

# Delete everything: VM, clusters, and the host route (sudo)
$ marina destroy
💾

With the default cacheStorage: "host", pulled images survive even marina destroy — your next lab rebuilds from the local cache instead of re-pulling. See Registry mirrors.

Two related lifecycle flows have their own pages: Upgrading marina (pull a release, then rebuild the VM) and Reset & reinstall (wipe to a clean baseline).

Where to next