☸ Kubernetes im Heimlabor

Kurs › Folge 05

Linux vorbereiten: swap aus, containerd, sysctl

Die Arbeit vor kubeadm — hier scheitern die meisten ersten Versuche.

Das Video zu dieser Folge ist noch nicht veröffentlicht. Die Notizen stehen trotzdem schon hier.

Was du danach kannst

  • containerd als Laufzeit einrichten und den cgroup-Treiber richtig setzen
  • swap dauerhaft abschalten und begruenden, warum
  • die noetigen Kernelmodule und sysctl-Werte setzen
  • die Kubernetes-Pakete in einer festen Version installieren

Worum es geht

kubeadm init ist ein einziger Befehl. Damit er durchläuft, muss das System darunter aber fünf Dinge mitbringen. Diese Folge macht genau die — einmal von Hand, damit klar ist was passiert, und danach als Skript für alle weiteren Knoten.

Das Skript

Alles aus dieser Folge in einem Durchlauf, wiederholbar und ohne Rückfragen:

apt update && apt install -y curl
curl -fsSLO https://lab.boothtml.com/skripte/node-vorbereiten.sh
less node-vorbereiten.sh          # erst lesen, dann ausführen
bash node-vorbereiten.sh

Direktlink: node-vorbereiten.sh

Das Skript ist absichtlich lesbar geschrieben und kommentiert. Lies es, bevor du es ausführst — ein fremdes Skript als root laufen zu lassen, ohne hineingesehen zu haben, ist keine gute Angewohnheit. Es ändert nur, was noch nicht stimmt, löscht nichts, und ein zweiter Durchlauf ist unschädlich.

Es bricht bewusst ab, wenn der Hostname Großbuchstaben enthält oder weniger als zwei CPU-Kerne da sind: Beides würde später beim Cluster-Beitritt scheitern, und dort ist es viel teurer zu reparieren.

Andere Kubernetes-Version:

K8S_MINOR=v1.33 bash node-vorbereiten.sh

Was das Skript tut

1. swap abschalten. Der Scheduler verteilt Pods anhand des verfügbaren Speichers. Läge ausgelagerter Speicher dazwischen, wären seine Entscheidungen Zufall — deshalb verweigert das kubelet den Dienst, solange swap aktiv ist. Wichtig: nicht nur swapoff -a, sondern auch die Zeile in /etc/fstab auskommentieren, sonst ist swap nach dem nächsten Neustart wieder da.

2. Kernelmodule overlay und br_netfilter laden — und über /etc/modules-load.d/ dauerhaft eintragen.

3. sysctl: bridge-nf-call-iptables und ip_forward einschalten. Ohne diese Werte findet Pod-Verkehr den Weg nicht.

4. containerd installieren, Standardkonfiguration schreiben und SystemdCgroup = true setzen.

5. kubeadm, kubelet, kubectl aus dem offiziellen Paketspeicher installieren und mit apt-mark hold einfrieren.

Die Fallen

Diese sieben Punkte stammen aus dem echten Aufbau, nicht aus der Dokumentation. Jeder einzelne hat mich Zeit gekostet.

Beim minimalen Debian fehlen sudo und curl. Wer bei der Softwareauswahl alles abwählt, bekommt ein sehr nacktes System — und der erste Benutzer landet nicht in der sudo-Gruppe, wenn man ein Root-Passwort vergeben hat.

su -
apt update && apt install -y sudo curl
usermod -aG sudo <benutzer>       # danach ab- und wieder anmelden

su ohne Bindestrich. su behält die Umgebung des normalen Benutzers, und darin fehlt /usr/sbin. Die Folge: swapoff: Kommando nicht gefunden für einen Befehl, der eindeutig installiert ist. Mit su - wird die Umgebung von root geladen. Deshalb setzt das Skript den PATH selbst.

Sprachabhängige Ausgaben. Auf einem deutschen System sagt free nicht Mem:, sondern Speicher:. Jedes Skript, das Ausgaben nach englischen Wörtern durchsucht, läuft dort ins Leere — ohne Fehlermeldung, einfach mit leerem Ergebnis. Ein export LC_ALL=C am Anfang löst das.

hostnamectl ändert /etc/hosts nicht. Bleibt dort der alte Name stehen, hängt jedes sudo ein paar Sekunden und meldet „unable to resolve host". Der Fehler sieht aus wie ein Netzwerkproblem, ist aber keins.

Großbuchstaben im Hostnamen. Kubernetes-Knotennamen müssen RFC-1123-konform sein, also kleingeschrieben. Umbenennen vor dem Beitritt — danach heißt es: Knoten rauswerfen und neu beitreten lassen.

SystemdCgroup = false. Der Klassiker. Das kubelet benutzt systemd als cgroup-Treiber, containerd per Vorgabe nicht. Die Pods bleiben dann hängen, und in keiner Fehlermeldung steht das Wort „cgroup".

Versionen driften auseinander. Ein beiläufiges apt upgrade hebt kubelet auf eine neuere Version als den Rest — und der Beitritt scheitert mit einer Meldung, die nach einem Zertifikatsproblem aussieht. apt-mark hold verhindert das.

Kontrolle

Vier Zeilen, die sagen ob der Knoten bereit ist:

swapon --show                                    # muss leer sein
grep SystemdCgroup /etc/containerd/config.toml   # muss true zeigen
sysctl net.ipv4.ip_forward                       # muss 1 sein
apt-mark showhold                                # kubelet, kubeadm, kubectl

Zum Nachlesen

Eine geordnete Übersicht über die offizielle Dokumentation — welcher Bereich wann hilft und was zu welchem Modul gehört — steht unter Nachlesen.

Befehle aus dieser Folge

  • apt update && apt install -y curl
  • curl -fsSLO https://lab.boothtml.com/skripte/node-vorbereiten.sh
  • bash node-vorbereiten.sh
  • swapon --show
  • grep SystemdCgroup /etc/containerd/config.toml
  • kubeadm version -o short

Begriffe

containerd
die Container-Laufzeit, mit der Kubernetes tatsaechlich spricht — Docker ist hier nicht noetig
SystemdCgroup
die Einstellung in containerd, die zum cgroup-Treiber des kubelet passen muss
br_netfilter
Kernelmodul, ohne das Pod-Verkehr nicht durch iptables laeuft
apt-mark hold
friert eine Paketversion ein, damit kein apt upgrade das Cluster auseinanderreisst

Übung — mach es selbst

Bereite einen zweiten Knoten vor — aber von Hand, ohne das Skript. Danach vergleichst du:

  1. swapon --show — muss leer sein
  2. grep SystemdCgroup /etc/containerd/config.toml — muss true zeigen
  3. sysctl net.ipv4.ip_forward — muss 1 sein
  4. apt-mark showhold — muss kubelet, kubeadm und kubectl nennen

Zusatzaufgabe: Schalte SystemdCgroup absichtlich wieder auf false, starte containerd neu und sieh dir an, wie der Fehler sich spaeter zeigt. Wer diese Meldung einmal gesehen hat, erkennt sie beim naechsten Mal in zehn Sekunden statt in zwei Stunden.