K3s Tutorial 2026: Lightweight Kubernetes for Raspberry Pi, Edge, and Home Lab

K3s Tutorial 2026: Lightweight Kubernetes for Raspberry Pi, Edge, and Home Lab

Kubernetes is the de-facto standard for container orchestration, but its full installation weighs in at hundreds of megabytes and requires significant resources — too much for a Raspberry Pi cluster, a cheap $5 VPS, or an IoT gateway running on the factory floor. That is the exact gap K3s was built to fill. Released by Rancher (now SUSE) in 2019, K3s packages a certified, production-grade Kubernetes distribution into a single binary under 100 MB. Its simplicity has driven roughly 200% year-over-year growth in edge and IoT deployments, and it has become the default choice for home labs and lightweight production clusters alike.

This tutorial covers everything you need to get a working K3s cluster: single-node server setup, adding worker nodes, deploying applications, configuring the built-in Traefik ingress controller, managing persistent storage, setting up a multi-node Raspberry Pi cluster, enabling high-availability mode, and a head-to-head comparison with competing distributions.

Prerequisites

  • A Linux host (x86_64 or arm64) running Ubuntu 22.04 / Debian 12 or later, or a Raspberry Pi with a 64-bit OS.
  • sudo or root access.
  • Basic familiarity with Linux and containers. You do not need prior Kubernetes experience.
  • For multi-node setups: two or more machines on the same network with SSH access between them.

1. What K3s Is and When to Use It

K3s is a fully conformant Kubernetes distribution, but it strips out everything that is not required for the core orchestration runtime:

Removed from upstream K8sWhat K3s uses instead
etcd (external datastore)SQLite (default, single-node) or embedded etcd (HA mode)
Cloud-provider integrations (AWS, GCP, Azure)Removed — add via Helm if needed
Alpha and deprecated featuresRemoved to reduce attack surface
In-tree storage driversReplaced by the Local Path Provisioner

The result is a single binary (k3s) that includes the API server, scheduler, controller manager, kubelet, kube-proxy, containerd, and a CNI plugin (Flannel by default). No separate install steps for each component.

When K3s is the right choice:

  • Raspberry Pi clusters — the arm64 binary runs natively on Pi 4 / Pi 5; full K8s is impractical.
  • Home lab or development — spin up a cluster on a spare machine or a cheap VPS in under two minutes.
  • Edge and IoT deployments — field devices with limited RAM (512 MB minimum) and intermittent connectivity.
  • CI runners — ephemeral single-node clusters for integration tests cost pennies per run.

When to use full Kubernetes instead: large-scale multi-cloud environments where cloud-provider integrations, advanced scheduler plugins, or alpha features are mandatory. For everything else, K3s handles the load.

2. Install K3s Server (Single-Node)

The entire server installation is a single curl command:

curl -sfL https://get.k3s.io | sh -

The script detects your architecture, downloads the appropriate binary, installs a systemd service, and starts K3s. On a modern machine this takes about 30 seconds.

Verify the node is ready:

sudo kubectl get nodes

Expected output:

NAME        STATUS   ROLES                  AGE   VERSION
my-server   Ready    control-plane,master   60s   v1.29.4+k3s1

Copy the kubeconfig to your home directory so you can run kubectl without sudo:

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config

To use this config from a remote workstation, replace 127.0.0.1 with the server's actual IP address in the copied file.

Check that core system pods are running:

kubectl get pods -n kube-system

You should see pods for coredns, traefik, local-path-provisioner, and metrics-server all in Running state.

3. Add Worker Nodes

First, retrieve the node join token from the server:

sudo cat /var/lib/rancher/k3s/server/node-token

This prints a long string. Copy it, then run the following on each worker node — replace <server-ip> with the control plane's IP and <token> with the value you just copied:

curl -sfL https://get.k3s.io | \
  K3S_URL=https://<server-ip>:6443 \
  K3S_TOKEN=<token> \
  sh -

Back on the server, confirm the worker has joined:

kubectl get nodes
NAME        STATUS   ROLES                  AGE    VERSION
my-server   Ready    control-plane,master   5m     v1.29.4+k3s1
worker-01   Ready    <none>                 30s    v1.29.4+k3s1

Repeat for as many workers as you need. K3s agents are also a single binary; the same k3s binary used on the server runs in agent mode when K3S_URL is set.

4. Deploy a Sample Application

Create a file named nginx-demo.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-demo
spec:
  selector:
    app: nginx-demo
  ports:
    - port: 80
      targetPort: 80

Apply it:

kubectl apply -f nginx-demo.yaml
kubectl rollout status deployment/nginx-demo

Test with a quick port-forward:

kubectl port-forward svc/nginx-demo 8080:80 &
curl http://localhost:8080

You should see the nginx welcome page HTML. Kill the port-forward with kill %1 when done.

5. Traefik Ingress (Built-In)

K3s ships Traefik 2.x as its default ingress controller — it is already running. You only need to create an Ingress resource to expose a service at a hostname.

Create nginx-ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-demo
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
    - host: nginx.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-demo
                port:
                  number: 80
kubectl apply -f nginx-ingress.yaml

Point nginx.example.com to your server's IP via DNS (or /etc/hosts for local testing), then visit the hostname in a browser.

TLS with cert-manager and Let's Encrypt — install cert-manager first:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

Create a ClusterIssuer for Let's Encrypt, then add these annotations to your Ingress:

annotations:
  cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - nginx.example.com
      secretName: nginx-demo-tls

cert-manager will automatically obtain and renew the certificate. Traefik picks up the secret and serves HTTPS without any further configuration.

6. Persistent Storage with Local Path Provisioner

K3s bundles the Rancher Local Path Provisioner, which dynamically provisions hostPath volumes. The default StorageClass is named local-path.

Create a PersistentVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: demo-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 1Gi

Mount it in a pod:

volumes:
  - name: data
    persistentVolumeClaim:
      claimName: demo-pvc
containers:
  - name: app
    image: busybox
    volumeMounts:
      - mountPath: /data
        name: data

The provisioner creates the directory under /var/lib/rancher/k3s/storage/ on the node that schedules the pod. For production multi-node clusters, consider Longhorn (also from SUSE/Rancher) which provides replicated block storage and is installable via Helm with full K3s support.

7. K3s on Raspberry Pi

Requirements: - Raspberry Pi 4 or 5 (2 GB RAM minimum; 4 GB recommended for control plane) - Raspberry Pi OS Lite 64-bit — K3s requires a 64-bit kernel. The 32-bit OS is not supported. - A Class 10 microSD or, preferably, a USB SSD for the control plane node.

Enable cgroup memory — without this, the kubelet will fail to start. Edit /boot/firmware/cmdline.txt (Raspberry Pi OS Bookworm) or /boot/cmdline.txt (older) and append the following to the existing single line (do not add a newline):

cgroup_memory=1 cgroup_enable=memory

Reboot, then install K3s exactly as described in section 2. The install script detects arm64 automatically.

Multi-node Pi cluster: use one Pi as the server (control plane) and the remaining Pis as agents. Run the agent join command from section 3 on each worker Pi. A three-node Pi 5 cluster with 8 GB RAM per node is powerful enough to run a complete production-like environment including monitoring (Prometheus + Grafana), logging, and several microservices.

8. High-Availability K3s (Embedded etcd)

For production workloads, a single control plane is a single point of failure. K3s supports HA with an embedded etcd cluster using three or more server nodes.

Bootstrap the first server with the --cluster-init flag:

curl -sfL https://get.k3s.io | K3S_TOKEN=<shared-token> sh -s - \
  --cluster-init

Join the second and third server nodes (not agents — these are also control-plane members):

curl -sfL https://get.k3s.io | K3S_TOKEN=<shared-token> sh -s - \
  --server https://<first-server-ip>:6443

All three servers participate in etcd consensus. You can lose one server and the cluster keeps running. Place a load balancer (HAProxy, nginx, or a cloud NLB) in front of the three API server addresses and point your kubeconfig at the load balancer's IP.

For worker nodes in an HA setup, the join command is identical to section 3 — point K3S_URL at the load balancer address.

9. K3s vs K8s vs MicroK8s vs k0s

FeatureK3sFull Kubernetes (kubeadm)MicroK8sk0s
Binary size< 100 MB~700 MB+ (multiple binaries)Snap package (~200 MB)~150 MB
Min. RAM512 MB2 GB540 MB512 MB
Default datastoreSQLiteetcdetcd (dqlite for HA)SQLite / etcd
Arm64 supportYes (official)YesYesYes
Built-in ingressTraefikNoneNGINX (addon)None
Built-in storageLocal PathNoneHostpath (addon)None
HA modeEmbedded etcdExternal or stacked etcddqlite / etcdEmbedded / external etcd
Best forEdge, Pi, home lab, devLarge-scale productionUbuntu/Snap ecosystemsAir-gapped, immutable OS
CNCF certifiedYesYesYesYes

TL;DR: K3s wins on simplicity and resource efficiency. Full Kubernetes wins for large teams that need advanced scheduler extensions or cloud-provider integrations. MicroK8s is a strong option on Ubuntu desktops. k0s is worth evaluating if you need an immutable or air-gapped setup.

10. FAQ

Q: Can I use kubectl from my laptop to manage a K3s cluster? Yes. Copy /etc/rancher/k3s/k3s.yaml from the server to ~/.kube/config on your laptop, change 127.0.0.1 to the server's public IP, and ensure port 6443 is reachable. Any standard kubectl binary works.

Q: Is K3s production-ready? Yes. K3s is CNCF-certified Kubernetes and used in production by companies like SUSE, various telcos, and countless edge deployments. The embedded SQLite datastore is fine for small single-node clusters; use embedded etcd (section 8) for anything that needs high availability.

Q: How do I upgrade K3s? Re-run the install script — it will upgrade in place:

curl -sfL https://get.k3s.io | sh -

For agents, run the same command with the K3S_URL and K3S_TOKEN environment variables set.

Q: Can K3s run on Docker instead of containerd? Yes, though it is not recommended. Pass --docker to the install script and ensure Docker is installed. The default containerd runtime has better integration and performance.

Q: How do I uninstall K3s?

# Server
/usr/local/bin/k3s-uninstall.sh

# Agent
/usr/local/bin/k3s-agent-uninstall.sh

Q: Can I replace Traefik with NGINX ingress? Yes. Disable Traefik during install and install NGINX ingress via Helm:

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -
helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

K3s removes the operational complexity that makes Kubernetes feel unapproachable for small teams and resource-constrained environments, while preserving full API compatibility. A working cluster is one curl command away, Traefik and storage come pre-configured, and the same YAML you write for K3s runs unchanged on any other Kubernetes distribution. For home labs, edge deployments, and anyone taking their first serious steps with Kubernetes, K3s is the right starting point in 2026.

Leonardo Lazzaro

Software engineer and technical writer. 10+ years experience in DevOps, Python, and Linux systems.

More articles by Leonardo Lazzaro