k3sm licensed apache-2.0 (DCO)

Quickstart


Bring up a single-node k3sm cluster on your Mac and run your first native Pod. This is the fastest path; Install explains what happens underneath.

Requirements: Apple Silicon (arm64), macOS 26+. k3sm runs Pods as native Darwin processes; see Concepts.

1. Install#

curl -fsSL https://k3sm.io/install.sh | sh

The script checks that this is an Apple silicon Mac on macOS 26+, downloads the release tarball and its checksums from GitHub Releases, verifies the sha256, prints exactly what it is about to do, and then runs sudo k3sm install. It installs the newest published release. Until the first stable version is tagged, that means the newest pre-release. Pin a particular one with K3SM_INSTALL_VERSION=v0.1.0, or set K3SM_INSTALL_DOWNLOAD_ONLY=1 to download and verify into the current directory without running anything as root.

Two alternatives:

  • Homebrew is planned, and the k3sm-io/tap is not published yet. When it ships, run brew install k3sm-io/tap/k3sm && sudo k3sm install.
  • From source, if you would rather build it yourself: clone the four k3sm.io repositories side by side, build with CGO_ENABLED=1 go build -o k3sm ./cmd/k3sm, then run sudo ./k3sm install. The full steps are in the repository README.

The one-time admin step (sudo k3sm install, which the script runs for you after printing what it is about to do) creates the unprivileged _k3sm user, installs the LaunchDaemons, and writes an admin kubeconfig to your home directory. After that, day-to-day use needs no sudo. See Install for the install-channel generations and the script’s options.

2. Confirm the Cluster Is Up#

Do not run k3sm server yourself. The install step registered the io.k3sm.server LaunchDaemon with RunAtLoad and KeepAlive, so the control plane and the node are already running and will come back after a reboot. A second, foreground k3sm server would contend with it for the work directory and the apiserver port.

k3sm status         # one screen: daemons, apiserver, node, workloads, data root
kubectl get nodes   # one Ready darwin node

The install row names the two LaunchDaemons. They are what makes the cluster survive a reboot, and k3sm status is how you check they came back. Its exit code is the verdict, so a script can branch on it; k3sm status --help lists the codes.

Install merged an admin context into your ~/.kube/config, so your own kubectl reaches the cluster with no further setup. See kubectl access for the details, and Install for what the daemons do.

Running a foreground cluster instead (no daemons, for a throwaway experiment)? Then skip step 1 entirely and run k3sm server in a terminal. Never run both.

3. Run a Native Binary as a Pod#

k3sm workloads are native Darwin executables, not OCI Linux images; see Images. The image: native sentinel runs an absolute host binary as a confined pod. Every k3sm Pod must declare the darwin node selector and tolerate the node’s provider taint, so use a manifest rather than kubectl run:

kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: hello
spec:
  nodeSelector:
    kubernetes.io/os: darwin
  tolerations:
    - key: k3sm.io/provider
      operator: Exists
      effect: NoSchedule
  restartPolicy: Never
  containers:
    - name: hello
      image: native
      command: ["/usr/bin/sw_vers"]
EOF

kubectl get pods
kubectl logs hello

Drop the nodeSelector and the cluster rejects the Pod at admission. That guardrail keeps Linux-assuming workloads off these nodes. examples/hello-native.yaml in the repo is the same shape.

For your own workload, build a darwin/arm64 binary with your normal toolchain and point command[0] at its absolute path (or set image: /abs/path with no command).

Before You Go Further#

k3sm is not a drop-in Linux Kubernetes. Before building anything you depend on, read Limitations, especially the notes on DNS, restartPolicy per runtime path, and the resource model.

Next#

  • Install covers the install model and the _k3sm posture.
  • Concepts explains how Kubernetes maps onto Darwin processes.
  • Troubleshooting helps when something does not come up.