Kubernetes-Testumgebung mit K3s
Die Simulation von netzwerkbasierten Systemen in virtuellen Maschinen ist insofern unrealistisch, als VM-Hypervisoren reale Latenzen nicht nachbilden können. Erfreulicherweise steht mit K3s eine Kubernetes-Version zur Verfügung, die sich auf verschiedensten Prozessrechnern ausführen lässt. Von der Cgroup-Konfiguration bis zum fertigen Cluster: Raspberry Pi, Orange Pi und K3s ergeben zusammen eine kostengünstige wie praxisnahe Testumgebung.
Kubernetes steht in unterschiedlichen Distributionen bereit, doch für unsere Testumgebung greifen wir auf K3s von SUSE zurück. Diese schlanke Kubernetes-Variante verursacht in Platform-as-a-Service-Umgebungen aufgrund geringerer Ressourcenanforderungen weniger Kosten und startet zudem schneller.
Um dieses Ziel zu erreichen, entfernten die Entwickler optionale Module und Sondercode, der zwar die Flexibilität von Kubernetes erhöht, für den Großteil realer Einsatzszenarien jedoch keine Rolle spielt. Alternative Mikro-Kubernetes-Varianten sind beispielsweise MicroK8s und Minikube. Diese Vergleichstabelle, stellt die Unterschiede und Einsatzschwerpunkte der Varianten dar.
K3s verzichtet auf verteilte Datenbanksysteme zum Speichern von Cluster-Strukturinformationen. Standardmäßig setzt es stattdessen auf eine lokale SQLite-Datei. Mit Dqlite existiert eine Alternative, die K3s-Deployments eine begrenzte Redundanz ermöglicht. In der kompakten Architektur von K3s sind die Unterservices in den beiden Systemrollen integriert. Auffällig dabei ist, dass sowohl der Server als auch die als Agenten bezeichneten Worker-Knoten ihre Container-Payloads über containerd ausführen. Docker ist in der K3s-Welt bereits seit längerer Zeit nicht mehr vorgesehen.
Test-Cluster mit K3s als Laborumgebung nutzen
Für den Aufbau eines Labors mit einem Einplatinencomputer ist nur wenig zusätzliche Hardware erforderlich. Neben einer Mehrfachsteckdose und qualitativ hochwertigen USB-C-Netzteilen empfiehlt sich der Einsatz eines Routers oder Switches, da WLAN erfahrungsgemäß unerwartete Latenzen in die Kommunikation einbringt. Für Experimente genügt dabei eine 100-MBit-Variante völlig – bei uns trat ein ausgemustertes Modell des Herstellers Surecom den entsprechenden Dienst an.
Als zentralen Server setzen wir einen Raspberry Pi 5 ein. Als Betriebssystem kommt das Image "2025-12-04-raspios-trixie-arm64.img.xz" zum Einsatz. Trotz der moderaten Ressourcenanforderungen von K3s empfiehlt es sich, eine schnelle Micro-SD-Karte mit mindestens 64 GByte Kapazität zu verwenden. Ein Raspberry Pi 5 ist dabei nicht zwingend erforderlich, da die benötigten CPU-Befehlssatz-Erweiterungen bereits auf älteren Modellen vorhanden sind, sodass der Betrieb theoretisch ab einem Raspberry Pi 3B möglich ist.
Mini-Server mit K3s anwerfen
Im Rahmen der Inbetriebnahme sollten Sie zunächst alle verfügbaren Betriebssystem-Updates installieren und einen SSH-Zugang einrichten. Der Wechsel zwischen Tastatur, Maus und Displaykabel erweist sich im Alltag schnell als hinderlich. Im nächsten Schritt legen Sie einen festen Hostnamen fest und führen anschließend einen Neustart durch:
sudo hostnamectl set-hostname <Raspi-Server>
Der Reboot stellt sicher, dass das System alle Netzwerkeinstellungen konsistent lädt. Andernfalls kann es vorkommen, dass Änderungen nicht vollständig übernommen wurden. Häufig ist zudem eine manuelle Anpassung der Datei "/etc/hosts" erforderlich. Auf einem typischen Server stellt sich deren Inhalt wie folgt dar:
127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspiserver
Für die Ausführung von Container-Payloads setzt Linux die Unterstützung von Control Groups (Cgroups) voraus. Da diese Funktion auf klassischen Desktopsystemen nicht erforderlich ist und die Systemleistung geringfügig beeinflusst, ist sie unter Raspberry Pi OS standardmäßig deaktiviert. Um dies zu ändern öffnen Sie die Datei "/boot/firmware/config.txt":
sudo nano /boot/firmware/config.txt
Scrollen Sie an das Ende der Datei und ergänzen Sie dort die folgenden Zeilen. Anschließend speichern Sie die Änderungen und starten das System neu:
[all] cgroup_memory=1 cgroup_enable=memory
Die Syntax orientiert sich an klassischen INI-Dateien. Ist der Header "[all]" bereits vorhanden, dürfen Sie ihn nicht erneut anlegen.
Zusätzlich passen Sie die Datei "/boot/ firmware/cmdline.txt" an und ergänzen die bestehende Parameterliste um:
cfg80211.ieee80211_regdom=GB cgroup_memory=1 cgroup_enable= memory
Nach einem erneuten Reboot überprüfen Sie die korrekte Übernahme der Parameter mittels cat/proc/cmdline. Wichtig dabei ist, dass die Cgroup-bezogenen Parameter in der Ausgabe erscheinen, wie in Bild 2 zu sehen.
Danach beginnt das Deployment von K3s und Sie starten die Installation mit:
curl -sfL https://get.k3s.io | sh -
Anschließnd prüfen Sie den Status des Diensts:
sudo systemctl status k3s
Der Befehl zeigt an, ob der K3s-Service erfolgreich gestartet wurde und der Server betriebsbereit ist.
Mehrere Worker für einen praxisnahen Cluster
In der Theorie ließe sich das bestehende System bereits zur Ausführung von Container-Payloads verwenden. Praxisnah ist ein solcher Aufbau jedoch nicht, da Kubernetes seine Stärken erst bei der Verfügbarkeit mehrerer Knoten ausspielt. Realistische Tests setzen daher mindestens einen zusätzlichen Worker voraus.
Als ersten Worker setzen wir einen Rasp-berry Pi 4 ein. Die Cgroups-Einrichtung und das Konfigurieren der übrigen Systemvoraussetzungen erfolgt analog zum Server. Zu beachten ist allerdings, dass dieses Modell lediglich über 4 GByte Arbeitsspeicher verfügt. Aus diesem Grund empfiehlt es sich dringend, nach Abschluss des Basissetups virtuellen Speicher zu aktivieren. Zunächst vergeben Sie auf dem Worker einen eindeutigen Hostnamen:
sudo hostnamectl set-hostname raspiworker
Anschließend passen Sie "/etc/hosts" manuell an – entscheidend ist, dass der Worker den Server über dessen Hostnamen erreichen und anpingen kann. Im nächsten Schritt aktivieren Sie das Swap-Subsystem. Auf aktuellen Versionen von Raspberry Pi OS ist der dafür notwendige Daemon nicht vorinstalliert und Sie müssen ihn zunächst einrichten:
sudo apt-get install dphys-swapfile sudo dphys-swapfile setup sudo dphys-swapfile swapon sudo systemctl enable dphys-swapfile
Der dritte dieser Befehle meldet mitunter eine Warnung, dass die berechnete und die erwartete Größe der Swap-Datei nicht übereinstimmen. Für unsere Tests ist dies unkritisch, relevant ist allein, dass der Befehl free -m sowohl den klassischen Swap als auch den im Arbeitsspeicher befindlichen Z-Swap ausweist.
Als zusätzlicher Hinweis sei angemerkt, dass es in Produktivumgebungen nicht empfehlenswert ist, Swap-Speicher auf MicroSD-Karten zu betreiben. Diese sind der permanenten Schreiblast nur unzureichend gewachsen. Besser geeignet sind über USB 3.0 oder PCIe angebundene SSDs.
Ein Token verbindet Worker und Server
Für die Aufnahme eines Workers in den Cluster benötigen Sie das Kubernetes-Pairing-Token des Servers. Dabei handelt es sich um einen kryptographischen Schlüssel, mit dem sich eine K3s-Agenteninstanz gegenüber dem Cluster authentifiziert. Sie ermitteln das Token direkt auf dem Server:
sudo cat /var/lib/rancher/k3s/ server/node-token
Anschließend wechseln Sie zurück in das SSH-Fenster des Workers. Dort stoßen Sie den Beitritt zum Cluster mit dem folgenden Befehl an. Achten Sie darauf, sowohl den Servernamen als auch das Token an Ihre eigene Umgebung anzupassen:
curl -sfL https://get.k3s.io | K3s_URL=https://raspiserver:6443 K3s_TOKEN=K10c76facbfee1fe609a200706c4b878c4920e1e43fa495e806b5182df09b07a7b2::server:bb2c0e949a0b5db04ee48791dc2714c0 sh -
Die eigentliche Verarbeitung dauert etwa eine Minute und bleibt dabei häufig bei der Meldung "[INFO] systemd: Starting k3s-agent" stehen. Wenn Sie den Fortschritt genauer beobachten möchten, öffnen Sie ein weiteres SSH-Fenster auf dem Worker und verfolgen die Logs mit:
sudo journalctl -u k3s-agent -f
Nach erfolgreichem Abschluss prüfen Sie auf dem Server, ob der neue Knoten korrekt registriert wurde:
sudo kubectl get nodes
Mehr Performance mit Orange Pi
Die kontinuierliche Weiterentwicklung der Halbleitertechnik hat auch im Bereich der Einplatinencomputer zu deutlichen Leistungssteigerungen geführt. Als weiteren Knoten nehmen wir einen Orange Pi 4 Pro in Betrieb. Das von Shenzhen Xunlong gefertigte System zeichnet sich durch eine stabile Thermik und ein leistungsfähiges, achtkerniges Allwinner-A733-SoC aus, das einem vergleichbaren Raspberry Pi überlegen ist.
Zunächst benötigen Sie ein passendes Betriebssystem-Image. Für den Orange Pi kommt die Datei "Orangepi4pro_1.0.4_ ubuntu_jammy_desktop_xfce_linux5.15.147" zum Einsatz. Schreiben Sie das Image auf eine MicroSD-Karte mit mindestens 64 GByte Kapazität. Beim ersten Start sind zwei Besonderheiten zu beachten: Zum einen benötigt das System vor der Initialisierung der Grafikhardware bis zu einer Minute, in der scheinbar keine Aktivität stattfindet. Zum anderen ist der SSH-Dienst nicht standardmäßig aktiviert. Sie schalten ihn über den orangepi-Konfigurator frei, der sich bequem aus dem grafischen Ubuntu-Interface starten lässt. Als Benutzername und Passwort dienen standardmäßig jeweils "orangepi". Den Hostnamen vergeben Sie anschließend wie gewohnt:
sudo hostnamectl set-hostname opiworker
Die Cgroups-Funktion ist in diesem Image bereits aktiviert. Nach Ausführung des bekannten Installationsbefehls – wiederum mit korrekt gesetztem Token – steht auch der Orange Pi als Worker im Kubernetes-Cluster zur Verfügung.
Einfache Cluster-Verwaltung via Dashboard
Derzeit erfolgt die Steuerung unseres Kubernetes-Clusters ausschließlich über das auf dem Raspberry Pi 5 installierte kubectl-Werkzeug. Diese Arbeitsweise ist funktional, in der Praxis jedoch wenig komfortabel. Für Analyse- und Kontrollaufgaben ist ein grafisches Frontend deutlich angenehmer. Als Vorbereitung statten wir den Cluster zunächst mit Helm aus. Helm fungiert als Paketmanager für Kubernetes und übernimmt das Herunterladen, Installieren und Aktualisieren von im Cluster ausgeführten Payloads. Die Installation der für das Dashboard benötigten Werkzeuge erfolgt mit den folgenden Kommandos:
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash helm installed into /usr/local/bin/helm helm repo add kubernetes-dashboard https://kubernetes.github.io/ dashboard/
Curl lädt dabei den Helm-Installer herunter, der mit K3s kompatibel ist. Da Helm über eine eigene Repository-Verwaltung verfügt, binden wir im zweiten Schritt das Repository ein, das die Inhalte des Kubernetes-Dashboards bereitstellt. Anschließend stoßen Sie die eigentliche Installation des Dashboardpakets an:
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/ kubernetes-dashboard --create- namespace --namespace kubernetes-dashboard
Nach erfolgreicher Abarbeitung erscheint eine Ausgabe, die auf eine korrekte Installation des Dashboard-Pakets hinweist.
Im Normalbetrieb empfiehlt es sich, das Dashboard auf der Maschine auszuführen, von der aus der Zugriff erfolgt. In unserem Demo-Cluster hosten wir das Dashboard jedoch bewusst auf dem Raspberry-Pi-Server. Ziel ist es, die Entwicklungs-Workstation vom Cluster-Betrieb zu trennen. Zunächst passen Sie die lokale Kubernetes-Konfiguration an, indem Sie die Konfigurationsdateien kopieren und die notwendigen Berechtigungen setzen:
sudo chmod 777 /etc/rancher/k3s/k3s.yaml cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chmod 777 ~/.kube/config
Im nächsten Schritt leiten Sie die Ports des Dashboards weiter. Dafür können Sie einen der beiden folgenden Befehle verwenden. Der Parameter "--address 0.0.0.0" sorgt dafür, dass das GUI auch von anderen Systemen im Netzwerk erreichbar ist.
Ohne diesen Parameter bleibt der Zugriff auf Localhost beschränkt, was aus sicherheitstechnischer Sicht sinnvoller ist, allerdings den Zugriff per VNC auf den Raspberry erforderlich macht, Variante 1:
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443
Oder Variante 2:
kubectl -n kubernetes-dashboard port-forward --address 0.0.0.0 svc/kubernetes-dashboard-kong-proxy 8443:443
Anschließend rufen Sie im Browser eine URL nach dem Schema "https://192. 168.1.73:8443/#/login" auf. Beachten Sie, dass die Portweiterleitung nur aktiv ist, solange der entsprechende Befehl aktiv ist. Wenn Sie das Terminal wieder nutzen möchten, können Sie den Befehl mit einem angehängten Ampersand im Hintergrund starten. Alternativ empfiehlt sich eine zweite SSH-Verbindung zwischen Workstation und Raspberry Pi.
Admin-Token für Dashboard-Zugriff
Der zuvor verwendete Bootstrap-Token eignet sich nicht für die Anmeldung am Kubernetes-Dashboard. Stattdessen benötigen Sie ein spezielles Token, das an einen Administratorbenutzer gebunden ist, der im Cluster zunächst noch nicht existiert. Zunächst legen Sie ein Arbeitsverzeichnis mit zwei YAML-Dateien an:
mkdir userworkdir cd userworkdir/ ~/userworkdir $ pico dashboard.admin-user.yml
Die erste Datei erhält folgenden Inhalt:
apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard
Anschließend erstellen Sie die zweite Datei "dashboard.admin-user-role.yml", die die erforderlichen Rolleninformationen enthält. Zu beachten ist, dass die API-Gruppe unabhängig von der verwendeten Distribution weiterhin auf den Namen "k8s" hört:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: * kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard
Anschließend laden Sie die Konfiguration in den Cluster:
~/userworkdir $ kubectl create -f dashboard.admin-user.yml -f dashboard.admin-user-role.yml serviceaccount/admin-user created clusterrolebinding.rbac.authorization.k8s.io/admin-user created
Jetzt erzeugen Sie das für die Anmeldung benötigte Token:
~/userworkdir $ kubectl -n kubernetes-dashboard create token admin-user
Der Rückgabewert ist ein mehrere hundert Zeichen langer String, der typischerweise mit der Sequenz "ey" beginnt. Diesen Wert tragen Sie in das Loginfeld des Dashboards ein. Nach erfolgreicher Anmeldung wird das Dashboard freigeschaltet. Bild 3 zeigt einen Zustand, in dem ein Orange Pi und zwei Raspberry Pis als Worker aktiv sind.
Fazit
Die rasante Weiterentwicklung der Halbleitertechnik ermöglicht es heutigen Einplatinencomputern, Leistungsklassen zu erreichen, die vor wenigen Jahren noch klassischen Servern vorbehalten waren. Die hier gezeigten Experimente verdeutlichen, wie sich diese Systeme für den Aufbau eines realitätsnahen Kubernetes-Test-Clusters nutzen lassen. Damit sind Kubernetes-Testumgebungen einfach und kostengünstig realisierbar. (jp)