K3s: Kubernetes in a Single Binary
How K3s packs a certified Kubernetes distribution into one sub-70 MB binary — what it strips, what it embeds, and why it became the default choice for edge and IoT.
Published on • November 14, 2026
AI Assistant

A full Kubernetes install is a day of work: a package repository, a container runtime, a CNI plugin, CoreDNS, kube-proxy, and a dozen manifests to apply in the right order. K3s collapses all of that into one binary under 70 MB and one command — and it is still a CNCF-certified Kubernetes distribution, not a cut-down imitation.
What “single binary” actually means
The K3s project describes the product as a certified Kubernetes distribution “built for IoT & Edge computing,” packaged as a single binary that reduces the dependencies and the number of steps needed to install, run, and auto-update the cluster. The install is literally:
curl -sfL https://get.k3s.io | sh -
That script downloads k3s, installs a systemd unit (or OpenRC equivalent), and starts a server node. There is no package repository to configure, no runtime to install first, no containerd version to pin. The kubeconfig lands at /etc/rancher/k3s/k3s.yaml.
The packaging trick is embedding, not rewriting. K3s takes components that upstream Kubernetes expects you to assemble yourself and bakes them into the binary or ships them as payloads it unpacks at startup:
| Component | Upstream default | In K3s |
|---|---|---|
| Container runtime | containerd (separate install) | Embedded containerd |
| CNI plugin | You choose (Calico, Cilium…) | flannel built in |
| Cluster DNS | CoreDNS (separate manifest) | Embedded |
| Node proxy | kube-proxy | Embedded (iptables/ipvs) |
| Metrics | metrics-server (separate) | Embedded |
| Storage | No default | local-path provisioner |
| Ingress | No default | Traefik, on by default |
Nothing here is exotic. Every item is a stock upstream project — K3s just ships a sane, tested combination so that curl | sh gives you a working cluster instead of a pile of parts.
What it strips
The other half of the size story is removal. K3s deletes the parts of upstream Kubernetes that are optional in practice:
- No in-tree cloud providers — an edge box isn’t on GKE or EKS.
- No Docker shim — containerd talks to the kubelet directly.
- Alpha features and deprecated APIs off by default.
- No separate addon manifests — they’re compiled in or bundled.
The result is a binary small enough to fit on an SD card, download over a bad LTE link, and diff as a single artifact in your provisioning pipeline. That matters far more at the edge than it does in a data center.
Server and agent roles
K3s has exactly two node types, per the architecture docs:
- A server runs
k3s server: the full control plane (kube-apiserver, controller-manager, scheduler) plus a datastore managed by K3s itself, plus the workloads that make the cluster usable (CoreDNS, Traefik, metrics-server). - An agent runs
k3s agent: kubelet, the container runtime, and the CNI. No datastore, no control plane. It registers with a server and does work.
Both roles run the same kubelet/runtime/CNI stack — an agent is not a “lesser Kubernetes,” it’s a server with the control plane switched off. On a single box you run only a server; on three Pis you run one server and two agents; on a rack you run three or more servers.
A single-server setup uses embedded SQLite by default — no database to install. That’s the whole reason a Pi can be a production control plane.
Why it took over the edge
Kubernetes itself, as the upstream overview explains, is a system for automating deployment, scaling, and management of containerized applications. That value proposition applies to a factory-floor cluster just as much as to a cloud region — but upstream’s installation assumptions do not.
Compare the operational surface:
| Upstream (kubeadm) | K3s | |
|---|---|---|
| Install steps | Repo setup, runtime, kubeadm, CNI, manifests | One command |
| Artifact size | Multiple packages + images | One <70 MB binary |
| Default datastore | etcd (or external DB) | Embedded SQLite |
| Default CNI/ingress | None / none | flannel / Traefik |
| Architectures | x86_64, arm64 | x86_64, arm64, armv7 |
ARMv7 support alone keeps a decade of Raspberry Pi 2/3 hardware and a long tail of industrial boards in scope. K3s scales from a Raspberry Pi to a 32 GiB server without changing how you operate it.
It’s also a CNCF Sandbox project, originated by Rancher (now SUSE) — so the thing you curl | sh onto a production device has a governance story and a security disclosure process behind it.
What you’re signing up for
The trade-offs are real and worth stating plainly:
- You get K3s’ choices, not yours. flannel, Traefik, local-path storage, SQLite — all defaults, all overridable with flags, but you’re overriding rather than selecting from scratch. If your org mandates Cilium and an external Postgres, you configure that on day one or you don’t.
- The server is heavier than the name suggests. A server runs a full control plane; a Pi 3 with 1 GB RAM will swap. Agents are cheap — servers are not.
- Embedded datastore is a single-node convenience. SQLite survives a disk, not a machine loss. HA is a separate, deliberate step (three or more servers on embedded etcd, or an external MySQL/PostgreSQL).
- It’s Kubernetes, with Kubernetes’ failure modes. Network partitions, cert rotation, version skew, bad rollouts — none of that goes away because the binary is small. K3s changes the packaging, not the distributed system.
The honest summary: K3s did not invent anything. It noticed that the hard part of Kubernetes for most people was assembling Kubernetes, and it shipped the assembly.