Edge-Containerisierung & Leichtgewichtiges K3s-Clustering
Moderne Softwarearchitekturen im industriellen Edge-Bereich betreiben Anwendungen längst nicht mehr monolithisch direkt auf dem Host-Betriebssystem. Stattdessen nutzen professionelle Edge-Umgebungen OCI-konforme Container (Docker und Podman) sowie leichtgewichtige Orchestratoren wie K3s (Lightweight Kubernetes), um Microservices sauber zu kapseln, Abhängigkeiten zu isolieren und unterbrechungsfreie Rolling Updates durchzuführen.
Der Betrieb von Kubernetes auf ARM-Einplatinencomputern verlangt jedoch ein striktes Ressourcenmanagement: Unbegrenzte Speichernutzung führt unweigerlich zu Kernel-OOM-Panics, und die Schreiblatenzen gewöhnlicher MicroSD-Karten zerstören das Quorum der internen Datenbank. Diese Anleitung liefert den praxiserprobten Leitfaden für performante Edge-Cluster auf Raspberry Pi 4 und 5.
1. Edge-Container-Engines: Docker vs. Podman auf ARM64
Bei der Wahl der Container-Laufzeitumgebung für Edge-Appliances stehen Sicherheitsarchitektur und systemd-Integration an erster Stelle:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph DockerArch["Docker (Daemon-Basiert)"]
direction TB
D_CLI["docker CLI"] -->|REST API| D_SOCK["/var/run/docker.sock"]
D_SOCK --> D_DAEMON["dockerd (Root-Daemon)"]
D_DAEMON --> D_SHIM["containerd-shim"]
D_SHIM --> D_CONT["Container (Root)"]
end
subgraph PodmanArch["Podman (Daemonless & Rootless)"]
direction TB
P_CLI["podman CLI"] -->|Fork / Exec| P_FORK["conmon (Prozess-Monitor)"]
P_SYS["systemd Unit"] -.->|Ueberwacht| P_FORK
P_FORK --> P_CONT["Container (User-UID)"]
end
DockerArch -->|"Edge-Alternative"| PodmanArch
Gegenüberstellung der Architekturen
| Kriterium | Docker CE | Podman |
|---|---|---|
| Hintergrunddienst | Zentraler Daemon (dockerd) |
Daemonless (Direkter conmon Prozess) |
| Rechte-Modell | Läuft mit Root-Rechten | Natives Rootless (Unprivilegierter Benutzer) |
| systemd-Integration | Eigene Restart-Policies | Direkte Einbindung über systemd Units (Quadlets) |
| RAM-Overhead im Leerlauf | ca. 90 MB RAM für den Daemon | 0 MB RAM (Kein dauerhafter Hintergrunddienst) |
| Einsatzbereich | Entwickler-Systeme & K3s-Backend | Abgesicherte Edge-Appliances & Gateways |
Zwingende Voraussetzung: 64-Bit ARM (aarch64)
Verwende für Container und Kubernetes ausnahmslos 64-Bit-Versionen von Raspberry Pi OS. Praktisch alle relevanten Infrastruktur-Container (PostgreSQL, Redis, Envoy, K3s, InfluxDB) haben die Unterstützung für 32-Bit ARM (armhf) auf Docker Hub und GitHub Container Registry eingestellt.
2. Kernel-Voraussetzungen: cgroups v2 & Speicher-Accounting
Bevor K3s oder Docker installiert werden können, muss der Linux-Kernel angewiesen werden, cgroups v2 mit Speicher-Accounting zu aktivieren. Ohne diese Kernel-Parameter können Container-Laufzeitumgebungen keine RAM-Grenzen durchsetzen, was zum sofortigen Absturz des Kubernetes-Agenten führt.
Kernel-Bootzeile anpassen
Datei /boot/firmware/cmdline.txt bearbeiten:
Folgende Parameter am Ende der bestehenden Zeile anhängen (keine neue Zeile beginnen!):
Beispiel:
console=serial0,115200 console=tty1 root=PARTUUID=7c8d9e0f-02 rootfstype=ext4 fsck.repair=yes rootwait cgroup_memory=1 cgroup_enable=memory
Speichern und das System neu starten:
Speicher-cgroups überprüfen
Prüfen, ob die Parameter vom Kernel geladen wurden:
Erwartete Ausgabe (dritte Spalte muss eine 1 sein):
3. Leichtgewichtiges Kubernetes: K3s-Architektur
Ein Standard-Kubernetes (K8s) verbraucht allein für seine Control-Plane (etcd, kube-apiserver, kube-scheduler, kube-controller-manager) mehrere Gigabyte RAM. K3s, entwickelt von Rancher Labs (SUSE) und zertifiziert von der CNCF, bündelt alle Komponenten in einer einzigen Binärdatei unter 60 MB.
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph ControlPlane["K3s Server-Node (rpi-node01)"]
direction TB
API["k3s API Server / SQLite"]
KUBE_S["Kubelet + Containerd"]
API --> KUBE_S
end
subgraph Worker1["K3s Agent 1 (rpi-node02)"]
direction TB
KUBE_A1["Kubelet + Containerd"]
end
subgraph Worker2["K3s Agent 2 (rpi-node03)"]
direction TB
KUBE_A2["Kubelet + Containerd"]
end
ControlPlane ==>|TLS Port 6443| Worker1
Worker1 --> Worker2
Warum K3s ideal für den Raspberry Pi ist
- Leichtgewichtige Datenbank: Ersetzt das ressourcenintensive etcd auf Einzelknoten durch eine integrierte SQLite-Engine (ermöglicht dennoch eingebettetes etcd für 3-Knoten-HA-Cluster).
- Entfernte Altlasten: Entfernt veraltete Cloud-Provider-Treiber zugunsten moderner, schlanker CSI-Schnittstellen.
- Geringer Speicherverbrauch: Die Master-Control-Plane belegt weniger als 512 MB RAM, Worker-Knoten begnügen sich mit ca. 150 MB RAM.
4. Single-Node K3s-Installation & Produktions-Tuning
Um den verfügbaren Arbeitsspeicher auf dem Raspberry Pi optimal für eigene Anwendungen zu nutzen, wird K3s unter Deaktivierung ressourcenintensiver Standardkomponenten (wie dem integrierten Alt-Traefik) installiert.
Installationsbefehl auf dem Master-Node (rpi-node01) ausführen:
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik --disable servicelb --write-kubeconfig-mode 644" sh -
Erklärung der Parameter
--disable traefik: Deaktiviert den integrierten Traefik-Ingress. (In der Produktion empfiehlt sich die gezielte Installation eines modernen Ingress per Helm).--disable servicelb: Deaktiviert den Klipper-Load-Balancer, um Ports für professionelle Lösungen wie MetalLB freizuhalten.--write-kubeconfig-mode 644: Erlaubt normalen Benutzern die Ausführung vonkubectl-Befehlen ohnesudo.
Cluster-Status überprüfen
Prüfen, ob der Knoten betriebsbereit ist:
Ausgabe:
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE KERNEL-VERSION
rpi-node01 Ready control-plane,master 45s v1.30.2+k3s1 192.168.10.51 Debian GNU/Linux 12 (bookworm) 6.6.31+rpt-rpi-2712
Laufende System-Pods kontrollieren:
5. Multi-Node-Cluster: Worker-Knoten hinzufügen
Um die Ausfallsicherheit und Rechenkapazität zu erhöhen, können weitere Raspberry Pis (rpi-node02, rpi-node03) als Worker-Knoten hinzugefügt werden.
Schritt 1: Cluster-Token abrufen
Auf dem Master-Knoten (rpi-node01) den Sicherheitstoken auslesen:
Beispiel-Token:
Schritt 2: Worker-Node beitreten lassen
Per SSH auf dem Worker-Knoten (rpi-node02) einloggen (sicherstellen, dass cgroup_memory=1 aktiv ist) und den K3s-Agent-Installationsbefehl ausführen:
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.10.51:6443 \
K3S_TOKEN="K10398f7e2d9a8c...::server:7b2a9e4d018fca65b21" \
sh -
Schritt 3: Cluster-Status kontrollieren
Zurück auf dem Master-Knoten prüfen, ob alle Knoten im Cluster registriert sind:
Erwartete Ausgabe:
NAME STATUS ROLES AGE VERSION
rpi-node01 Ready control-plane,master 10m v1.30.2+k3s1
rpi-node02 Ready <none> 2m15s v1.30.2+k3s1
rpi-node03 Ready <none> 45s v1.30.2+k3s1
6. Produktions-Workload mit strikten Ressourcen-Limits
Auf Embedded-Systemen kann ein einziger fehlerhafter Container mit Speicherleck das gesamte Betriebssystem lahmlegen. Jedes Deployment auf einem Raspberry Pi Edge-Cluster muss zwingend CPU- und Memory-Limits definieren.
Manifest edge-sensor-collector.yaml erstellen:
apiVersion: apps/v1
kind: Deployment
metadata:
name: edge-sensor-collector
namespace: default
labels:
app: sensor-telemetrie
spec:
replicas: 2
selector:
matchLabels:
app: sensor-telemetrie
template:
metadata:
labels:
app: sensor-telemetrie
spec:
containers:
- name: collector
image: alpine:latest
command: ["/bin/sh", "-c"]
args:
- while true; do
echo "[$(date -u +%FT%TZ)] Telemetrie-Heartbeat von Pod auf $(hostname)" >> /tmp/telemetrie.log;
sleep 5;
done
resources:
requests:
cpu: "50m" # 5% eines CPU-Kerns garantiert reserviert
memory: "32Mi" # 32 MB Arbeitsspeicher garantiert reserviert
limits:
cpu: "250m" # Maximal 25% eines Kerns zulaessig
memory: "64Mi" # Maximal 64 MB RAM (bei Ueberschreitung OOMKilled)
livenessProbe:
exec:
command:
- test
- -f
- /tmp/telemetrie.log
initialDelaySeconds: 10
periodSeconds: 15
Workload im Cluster bereitstellen:
Pod-Verteilung auf die Nodes überprüfen:
7. Speicher-Flaschenhals: NVMe vs. MicroSD bei K3s-Clustern
Wird ein Hochverfügbarkeits-Cluster mit 3 Master-Knoten und eingebettetem etcd betrieben, dürfen keinesfalls gewöhnliche MicroSD-Karten als Datenträger verwendet werden.
Das etcd-Latenzproblem
Das etcd-Konsensprotokoll setzt voraus, dass synchrone Schreibvorgänge (fsync) in unter 10 Millisekunden abgeschlossen werden.
- MicroSD-Karten erreichen bei paralleler Last oft nur Latenzen zwischen 50 ms und 250 ms.
- Überschreitet etcd das Timeout, verliert der Cluster seine Leader-Wahl, Knoten fallen auf NotReady und der Cluster friert ein.
- Lösung: Betreibe K3s-Master immer auf M.2 NVMe SSDs über PCIe Gen 2/3 (Latenzen typischerweise < 0,8 ms).
Nächste Schritte
Bringe deine Edge-Infrastruktur zur Vollendung, indem du physische lokale Festplatten komplett überflüssig machst:
- Festplattenloser Netzwerk-Boot (PXE): Boote deine gesamte Raspberry Pi Flotte über Gigabit-Ethernet von einem zentralen TrueNAS- oder Debian-Server.
- Modbus-Energiemonitor-Workshop: Erfasse Messwerte realer Hutschienenzähler und leite sie in containerisierte Datenbanken weiter.