Kubernetes auf dem Raspberry Pi läuft am einfachsten mit k3s, einer leichtgewichtigen Kubernetes-Distribution, die sich mit einem einzigen Skript installiert. Zwei Raspberry Pi 4 mit je 4 GB Arbeitsspeicher reichen für ein echtes Cluster mit einer Control-Plane-Node und einer Worker-Node. Damit hast du das, was Minikube und kind dir nicht geben: zwei physische Rechner, ein echtes Netzwerk dazwischen und Services und Ingress, die sich wie in Produktion verhalten.
Ich habe genau so ein Cluster für mein Kubernetes-Buch aufgebaut und betreibe es seitdem als Übungsumgebung. Beruflich baue ich produktionsreife k3s-Cluster in der deutschen Cloud für mittelständische Unternehmen, und die Erfahrung sagt: Wer k3s einmal auf zwei Pis installiert hat, versteht danach viel besser, was in einem großen Cluster passiert. Alle meine Beiträge zum Thema findest du gesammelt auf der Seite Kubernetes.
Warum ein Raspberry Pi Cluster und nicht nur Minikube
Minikube, kind und Docker Desktop sind für die ersten Schritte völlig ausreichend, das habe ich in Kubernetes lokal: Cluster auf dem Rechner beschrieben. Alle drei laufen aber in einer Virtualisierung oder in Docker-Containern auf einem einzigen Rechner. Genau da stoßen sie an eine Grenze: Netzwerk-Themen wie ein Service vom Typ NodePort, ein Ingress mit echter IP-Adresse oder ein Pod, der auf einer anderen Node landet als sein Nachbar, lassen sich damit nur simulieren.
Ein Cluster aus zwei Raspberry Pis hat dieses Problem nicht. Die Control-Plane läuft auf dem einen Gerät, der Worker auf dem anderen, und dazwischen liegt ein Netzwerkkabel. Wenn du ein Deployment mit zwei Replicas anlegst, siehst du in der Ausgabe von kubectl, wie Kubernetes die Pods auf beide Nodes verteilt. Wenn du einen Pi vom Strom nimmst, siehst du, wie das Cluster reagiert. Das ist Lernen mit Anfassen, und es kostet einen Bruchteil dessen, was ein zweiter Server kosten würde.
Es gibt noch einen zweiten Grund, der mir wichtig ist: k3s auf dem Pi ist dasselbe k3s, das ich in Produktion einsetze. Die Konfigurationsdateien, die Pfade, die systemd-Unit, das Node-Token: alles identisch. Was du im Homelab lernst, nimmst du eins zu eins mit in den Job.
Hardware für das Kubernetes Raspberry Pi Cluster
Ich war am Anfang unschlüssig, welche Modelle sinnvoll sind, und habe mich am Ende für ein bewusst kleines Setup entschieden, das trotzdem Reserven hat. Die Teile, die bei mir seit Monaten im Dauerbetrieb laufen:
| Teil |
Menge |
Wozu |
| Raspberry Pi 4 mit 4 GB RAM |
2 |
eine Control-Plane-Node, eine Worker-Node |
| microSD-Karte mit 64 GB |
2 |
Betriebssystem und Container-Images |
| Offizielles Raspberry Pi Netzteil |
2 |
stabile Stromversorgung, spart Ärger mit Neustarts |
| 5-Port-Switch plus Netzwerkkabel |
1 |
kabelgebundene Verbindung zwischen den Nodes |
| Stapelbares Acrylgehäuse |
1 |
Ordnung auf dem Schreibtisch, passive Kühlung |
Der Switch ist streng genommen optional, denn die Pis haben WLAN eingebaut. Ich habe ihn trotzdem gekauft, weil die Verbindung zwischen Control-Plane und Worker damit stabiler ist und ich beim Debuggen nicht rätseln will, ob das WLAN oder Kubernetes das Problem ist. Für ein reines Testcluster reicht WLAN aus.
Meine Erfahrung mit dem Einkauf: Je länger du recherchierst, desto teurer wird es. Lüfter und Kühlkörper-Sets sind für ein Übungscluster nicht nötig, bei mir läuft es tagelang ohne Anzeichen von Überhitzung. Speicherkarten und Netzteile, die du noch zu Hause hast, kannst du verwenden; eine 32-GB-Karte reicht vermutlich ebenfalls.
Ein Punkt, der beim Pi wichtiger ist als auf jedem Laptop: Der Prozessor ist ein ARM-Chip. Jedes Container-Image, das du auf dem Cluster starten willst, muss für arm64 gebaut sein. Die großen offiziellen Images wie nginx, Redis oder PostgreSQL gibt es als Multi-Architektur-Images, bei kleineren Projekten lohnt ein Blick in die Tags, bevor du dich über einen Pod im Status CrashLoopBackOff wunderst.
Raspberry Pi OS einrichten: Imager, Hostnamen, SSH
Die Pis kommen ohne Betriebssystem. Du brauchst den Raspberry Pi Imager, der dir das System auf die SD-Karte schreibt. Als Betriebssystem wählst du Raspberry Pi OS Lite in der 64-Bit-Variante. Lite bedeutet: ohne Desktop, und den brauchst du auf einer Kubernetes-Node auch nicht. Im Imager versteckt sich die Variante unter dem Eintrag für weitere Betriebssysteme.
Bevor der Imager schreibt, bietet er dir an, das System anzupassen. Diese Einstellungen solltest du nutzen, weil sie dir später viel Tipparbeit sparen. Ich vergebe als Hostnamen raspberrypi1 für die Control-Plane und raspberrypi2 für den Worker, lege meinen Benutzer an und hinterlege unter den Diensten meinen öffentlichen SSH-Schlüssel. Dadurch kann ich mich nach dem ersten Start ohne Passwort anmelden.
Mit beiden beschriebenen Karten in den Pis und angeschlossenem Netzteil starten die Geräte von allein. Der Login funktioniert über den Hostnamen mit dem Zusatz .local, ich arbeite dabei mit zwei Terminalfenstern nebeneinander:
ssh -i ~/.ssh/pi_key kevinwelter@raspberrypi1.local
ssh -i ~/.ssh/pi_key kevinwelter@raspberrypi2.local
Wenn der Hostname nicht aufgelöst wird, hilft ein Blick in die Geräteliste deines Routers, dort siehst du die IP-Adressen der Pis und kannst sie direkt verwenden.
k3s auf dem Raspberry Pi installieren
Für die Kubernetes-Installation nutze ich k3s, eine leicht angepasste und sehr schlanke Kubernetes-Distribution, die genau für kleine Geräte und Edge-Umgebungen gebaut wurde. Zuerst müssen beide Pis zwei kleine Anpassungen bekommen, denn der Kernel des Raspberry Pi OS hat die cgroups für Speicher standardmäßig nicht aktiviert, und ohne die startet kein Kubelet.
Öffne dafür auf beiden Pis die Kernel-Kommandozeile mit sudo nano und hänge am Ende der einzigen Zeile, durch ein Leerzeichen getrennt, die drei Parameter an. Je nach Version des Raspberry Pi OS liegt die Datei unter /boot/firmware/cmdline.txt oder unter /boot/cmdline.txt:
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
Bei älteren Versionen des Raspberry Pi OS musst du außerdem iptables auf die Legacy-Variante umstellen, weil k3s sonst mit dem nftables-Modus des Systems in Konflikt gerät. Danach in jedem Fall neu starten:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo reboot
Jetzt kommt der Teil, der bei kubeadm mehrere Seiten Anleitung füllt und bei k3s aus einer Zeile besteht. Auf raspberrypi1, der Control-Plane-Node, installierst du den k3s-Server. Die Umgebungsvariable sorgt dafür, dass die Kubeconfig später für deinen Benutzer lesbar ist:
export K3S_KUBECONFIG_MODE="644"
curl -sfL https://get.k3s.io | sh -
Das Skript lädt k3s, legt eine systemd-Unit an und startet den Dienst. Mit sudo systemctl status k3s prüfst du, ob alles läuft. Danach brauchst du das Node-Token, mit dem sich Worker am Server anmelden:
sudo cat /var/lib/rancher/k3s/server/node-token
Auf raspberrypi2 läuft dasselbe Skript, aber mit zwei zusätzlichen Variablen: der URL der Control-Plane und dem Token aus dem letzten Schritt. Das Skript erkennt an den Variablen, dass es einen Agent installieren soll und keinen Server:
export K3S_KUBECONFIG_MODE="644"
export K3S_URL="https://raspberrypi1.local:6443"
export K3S_TOKEN="K10...abc"
curl -sfL https://get.k3s.io | sh -
Der Name mit .local funktioniert nur, solange mDNS im Netz läuft und die Pis ihren Namen dort bekanntgeben. Für einen Cluster, der dauerhaft stehen soll, ist die feste IP-Adresse der Control-Plane die verlässlichere Wahl, weil eine ausgefallene Namensauflösung sonst den Join und später jeden Neustart des Agents blockiert. Zurück auf raspberrypi1 zeigt dir sudo k3s kubectl get node, ob der Worker angekommen ist. Die Ausgabe sieht dann so aus:
NAME STATUS ROLES AGE
raspberrypi1 Ready control-plane,master 3m
raspberrypi2 Ready <none> 40s
Damit läuft Kubernetes auf deinen Raspberry Pis. Das Skript installiert immer die aktuelle Version von k3s; für Übungen ist das kein Problem, in Produktion würde ich die Version festpinnen.
Kubeconfig auf den eigenen Rechner holen
Auf der Control-Plane kannst du direkt mit dem eingebauten kubectl arbeiten. Angenehmer ist es, das Cluster von deinem Laptop aus zu bedienen, mit deinem kubectl, deinen Aliasen und einem Werkzeug wie Lens. Dafür brauchst du die Kubeconfig, die k3s auf dem Server unter /etc/rancher/k3s/k3s.yaml ablegt.
Kopiere den Inhalt in einen Editor und ändere die Zeile server: https://127.0.0.1:6443 auf den Namen oder die IP der Control-Plane, also zum Beispiel server: https://raspberrypi1.local:6443. Ohne diese Änderung würde dein kubectl versuchen, auf deinem eigenen Rechner ein Cluster zu finden. Die angepasste Datei kannst du auf drei Wegen nutzen: nur in Lens importieren, als eigene Datei unter ~/.kube/pi-cluster.yaml ablegen und über die Variable KUBECONFIG ansprechen, oder mit deiner bestehenden Kubeconfig zusammenführen. Den dritten Weg finde ich am elegantesten, weil du danach mit kubectx zwischen Minikube und Pi-Cluster wechselst, ohne Variablen zu setzen:
cp ~/.kube/config ~/.kube/config-backup
export KUBECONFIG=~/.kube/config:~/.kube/pi-cluster.yaml
kubectl config view --flatten > ~/.kube/config-merged
mv ~/.kube/config-merged ~/.kube/config
kubectl config get-clusters
Die letzte Zeile listet alle bekannten Cluster auf. Taucht dein Pi-Cluster dort auf, bist du fertig. Wie die Zusammenführung von Kubeconfigs im Detail funktioniert, beschreibt die Kubernetes-Dokumentation.
Erster Test: ein Deployment auf beiden Nodes
Der schnellste Beweis, dass dein Cluster mehr ist als ein Minikube, ist ein Deployment mit zwei Replicas. Kubernetes verteilt die Pods standardmäßig auf beide Nodes, und genau das siehst du in der Ausgabe:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hallo-pi
spec:
replicas: 2
selector:
matchLabels:
app: hallo-pi
template:
metadata:
labels:
app: hallo-pi
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
Speichere die Datei als hallo-pi.yaml und wende sie an. Mit dem Zusatz -o wide zeigt dir kubectl, auf welcher Node jeder Pod gelandet ist:
kubectl apply -f hallo-pi.yaml
kubectl get pods -o wide
In der Spalte NODE sollte je ein Pod auf raspberrypi1 und raspberrypi2 stehen. Das nginx-Image liegt als Multi-Architektur-Image vor, deshalb zieht sich der Pi automatisch die arm64-Variante. Ab hier kannst du alles ausprobieren, was in einem Ein-Node-Cluster nur halb funktioniert: einen Service vom Typ NodePort über beide IP-Adressen aufrufen, den Ingress-Controller Traefik nutzen, den k3s gleich mitbringt, oder einen Pi ausschalten und beobachten, wie Kubernetes den Pod auf der anderen Node neu startet.
Grenzen des Pi-Clusters und wann die Cloud besser ist
Ein Cluster aus zwei Raspberry Pis ist eine Lernumgebung, keine Plattform für Kundenprojekte. Die 4 GB Arbeitsspeicher je Node sind schnell belegt, wenn du Monitoring, eine Datenbank und ein paar Anwendungen gleichzeitig laufen lässt. Die SD-Karte ist langsamer als jede SSD, und Container-Images für arm64 gibt es nicht für jedes Nischenprojekt. Schön an Kubernetes ist: Wenn das Cluster an seine Grenze kommt, steckst du einen dritten Pi dazu und führst das Agent-Skript noch einmal aus.
|
Minikube oder kind |
Zwei Raspberry Pis |
Cluster in der Cloud |
| Nodes |
eine, virtualisiert |
zwei, physisch |
beliebig viele |
| Netzwerk |
simuliert |
echt, mit eigener IP je Node |
echt, mit Load Balancer |
| Laufende Kosten |
keine |
Strom |
monatlich, je nach Größe |
| Geeignet für |
erste Schritte, YAML testen |
Services, Ingress, Node-Ausfall üben |
Produktion, Hochverfügbarkeit |
| Nicht geeignet für |
Netzwerk-Themen |
Kundenprojekte, Daten mit Wert |
reines Lernen, wenn das Budget knapp ist |
Ein Detail zur Ausfallsicherheit, das viele überrascht: Genau weil dein Pi-Cluster nur eine Control-Plane hat, kannst du die Pis jederzeit aus- und wieder einschalten. Das Cluster baut sich danach sauber wieder auf. Bei drei Control-Plane-Nodes ist das heikler: Fallen zwei davon gleichzeitig aus, verliert etcd seine Mehrheit, und der Cluster nimmt keine Änderungen mehr an, bis genug Nodes zurück sind. Warum das so ist, erkläre ich in Kubernetes-Architektur: die Komponenten. Für Produktion brauchst du diese Hochverfügbarkeit, für das Homelab ist die einzelne Control-Plane ein Vorteil.
Wann ist die Cloud die bessere Wahl? Sobald etwas anderen Menschen dienen soll, sobald du Daten hast, deren Verlust wehtut, oder sobald du Hochverfügbarkeit testen willst. Bei mir läuft Produktion auf k3s-Clustern mit drei Control-Plane-Nodes in drei Rechenzentren, mit GitOps über ArgoCD und Helm. Das Pi-Cluster ist die Werkbank daneben, auf der ich neue Charts und Policies ausprobiere.
Häufige Fragen
Reicht ein einzelner Raspberry Pi für Kubernetes?
Ja, k3s läuft auch auf einem einzelnen Pi als Server, der dann gleichzeitig Control-Plane und Worker ist. Damit kannst du Pods, Deployments, ConfigMaps und Secrets üben. Den eigentlichen Mehrwert gegenüber Minikube, also Scheduling über mehrere Nodes und echte Netzwerke, bekommst du aber erst mit dem zweiten Pi.
k3s oder Kubernetes mit kubeadm auf dem Raspberry Pi?
Für den Pi ist k3s die klar bessere Wahl. Es ist ein vollwertiges, zertifiziertes Kubernetes, nur schlanker verpackt: eine Binärdatei, SQLite statt etcd bei einer einzelnen Control-Plane, Traefik und ein Load Balancer schon dabei. kubeadm funktioniert auf dem Pi ebenfalls, braucht aber deutlich mehr Handarbeit und mehr Arbeitsspeicher. Wer kubeadm für eine Zertifizierung üben will, macht das besser in virtuellen Maschinen.
Wie viele Raspberry Pis brauche ich für ein Kubernetes Homelab?
Zwei reichen, um alle Kubernetes-Konzepte auszuprobieren, die Multi-Node-Verhalten zeigen. Drei oder mehr lohnen sich, wenn du Node-Ausfälle mit mehreren Workern testen oder Anwendungen mit mehr Speicherbedarf betreiben willst. Ein Cluster mit drei Control-Plane-Nodes für echte Hochverfügbarkeit würde ich auf Pis nicht empfehlen, dafür sind Strom- und Netzwerkabbrüche im Homelab zu häufig.
Kann ich das Cluster über WLAN betreiben?
Ja, die Pis haben WLAN eingebaut und k3s stellt keine besonderen Anforderungen an das Netzwerk. Ich nutze trotzdem einen Switch mit Kabeln, weil die Verbindung zwischen Control-Plane und Worker damit stabiler ist und ich beim Debuggen eine Fehlerquelle weniger habe.
Warum startet mein Pod auf dem Pi nicht, obwohl er auf dem Laptop läuft?
Der häufigste Grund ist die Prozessorarchitektur. Der Raspberry Pi hat einen ARM-Chip, und ein Image, das nur für amd64 gebaut wurde, lässt sich dort nicht starten. Der Pod landet dann im Status CrashLoopBackOff oder ImagePullBackOff. Prüfe im Image-Repository, ob ein arm64-Tag oder ein Multi-Architektur-Image existiert, oder baue das Image selbst für arm64.
Wie du weitermachst
Wenn dein Cluster läuft, ist der nächste Schritt, es zu benutzen: ein Deployment mit Service und Ingress, ein Node-Ausfall, ein zweiter Namespace. Die passende Reihenfolge für den Einstieg beschreibe ich in Kubernetes lernen, und die Alternativen für den Fall, dass du erst einmal keine Hardware kaufen willst, in Kubernetes lokal: Cluster auf dem Rechner.
Ausführlich mit allen Beispielen steht das in Kapitel 2 meines Buchs „Kubernetes: Das Praxisbuch für Entwickler und DevOps-Teams" (Rheinwerk). Dort baue ich das Pi-Cluster Schritt für Schritt auf und nutze es in den späteren Kapiteln für Netzwerk-, Storage- und Monitoring-Übungen.