CI for Apple platforms
Build agents and test runners are already native macOS binaries. Run them as Deployments, Jobs and CronJobs under the upstream controllers, on Macs you already have.
k3sm is the macOS/Apple-Silicon analog of k3s, a single-binary Kubernetes distribution whose Pods run as native Darwin processes by default. The vm RuntimeClass runs linux/arm64 images in a per-pod micro-VM.
$ k3sm kubectl apply -f examples/hello-native.yaml
pod/hello-native created
$ k3sm kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-native 1/1 Running 0 4s
$ pgrep -fl 'tail -f /dev/null'
48213 /usr/bin/tail -f /dev/null
k3sm is the macOS and Apple-Silicon analog of k3s. It runs the
upstream Kubernetes control plane in one binary, and a Pod is a Mac binary running as a native
Darwin process. Seatbelt, the macOS sandbox, confines each Pod. Pod IPs are lo0 loopback aliases,
wireguard-go links Macs, launchd supervises the daemons, and APFS clones each Pod’s root. Linux
images take the vm RuntimeClass, which boots linux/arm64 images in per-pod micro-VMs on a
single node.
The current release is v0.1.6. The Homebrew tap and a notarized package land with the first stable release.
Apple Silicon, macOS 26 or newer:
curl -fsSL https://k3sm.io/install.sh | sh
The script resolves the newest release, verifies its checksums, and runs sudo k3sm install. It
shows you exactly what it will do before asking for anything. install covers
pinning a version and every other channel. To build from source instead:
for r in apis runtimed darwin-net k3sm; do git clone https://github.com/k3sm-io/$r; done
go work init ./apis ./runtimed ./darwin-net ./k3sm
cd k3sm && CGO_ENABLED=1 go build -o k3sm ./cmd/k3sm
sudo ./k3sm install
The installed launchd daemon starts the control plane and registers the Mac as a node. The
quickstart has the first manifest, including the
kubernetes.io/os: darwin selector every k3sm Pod needs.
A Pod is then a native binary your Mac sandboxed and is supervising:
$ k3sm kubectl apply -f examples/hello-native.yaml
pod/hello-native created
$ k3sm kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-native 1/1 Running 0 4s
$ pgrep -fl 'tail -f /dev/null'
48213 /usr/bin/tail -f /dev/null
No container or VM sits between the Pod and the process table. kubectl scheduled it, Seatbelt
confines it, launchd keeps its supervisor alive, and ps sees an ordinary macOS process.
Build agents and test runners are already native macOS binaries. Run them as Deployments, Jobs and CronJobs under the upstream controllers, on Macs you already have.
An MLXModel custom resource and an mlx.k3sm.io/gpu extended resource reconcile a model into a
served /v1/chat/completions endpoint in the Mac’s unified memory.
A Pod that names the vm RuntimeClass boots a linux/arm64 OCI image in its own
Virtualization.framework guest and reaches Running, on a single node.
kubectl exec -it and kubectl attach give it a terminal. linux/amd64 is a later release.
k3sm build -t myapp:dev . builds any Dockerfile into the node’s store. A copy-only one becomes a
darwin/arm64 image; one that RUNs commands becomes a linux/arm64 image, built by BuildKit in a
micro-VM that starts on first use. No external build service or container engine is needed.
Join more Macs with a single token over a wireguard-go mesh. Each node keeps its own pod range, routed without NAT. A worker schedules Pods, serves NodePorts across nodes, and resolves cluster DNS in-Pod. Multi-node is experimental until v0.3.
1signed binary
One binary supervises kube-apiserver, scheduler and controller-manager, built from source for
darwin/arm64, over kine → SQLite. RBAC, admission, CRDs and the scheduler are the same
upstream components.
0VMs on the default path
Containers are posix_spawn’d at host paths under a generated default-deny Seatbelt profile with
an APFS clonefile root, so your app reaches the Mac’s frameworks with nothing in between. Linux
images opt in to vm.
26+macOS, on Apple silicon
Seatbelt-confined Pods run the full lifecycle: logs / exec / top, and they keep running
when the node daemon restarts. what runs lists what the default path takes.
k3sm keeps the upstream control plane and rebuilds everything that assumed Linux on macOS. The
walk-through from kubectl apply down to posix_spawn is on architecture.
k3s (Linux) k3sm (macOS-native)
getaddrinfo shim in pods upstream + nativek3sm-runtimed (Seatbelt at host paths, APFS, posix_spawn, userspace limits) nativelo0-alias pod IPs and a wireguard-go mesh nativeHelmChart and HelmChartConfig in helm.k3sm.io/v1, with the same fields as k3s, and manifests in a root-owned directory applied automatically nativevm
RuntimeClass runs linux/arm64 images; linux/amd64 is a later release.[Conformance], which requires Linux containers, cgroups and CNI. The
conformance profile states what is claimed._k3sm
user under its own Seatbelt profile.limits. Memory is sampled and can drive an OOMKill or an eviction; CPU
gets QoS and no ceiling.limitations has the complete list, including volumes, DNS, restartPolicy,
and which addresses Services answer on.