Feldnotizen


6 Min. Lesezeit

Kubernetes auf Bare Metal

Voraussetzungen

Das sind die Mindestanforderungen, um einen Kubernetes-Cluster auf Bare Metal aufzusetzen:

  • Ein kompatibler Linux-Host. Das Kubernetes-Projekt stellt allgemeine Anleitungen für Debian- und Red-Hat-basierte Distributionen bereit, und für Distributionen ohne Paketmanager.

  • Mindestens 2 GB RAM pro Maschine (mit weniger bleibt kaum Platz für deine Apps).

  • Mindestens 2 CPUs pro Maschine.

  • Volle Netzwerkverbindung zwischen allen Maschinen im Cluster (öffentliches oder privates Netz spielt keine Rolle).

    Bestimmte Ports müssen auf deinen Maschinen offen sein. Details weiter unten.

1. Den Server einrichten

Bevor du Kubernetes auf einem Bare-Metal-Server installierst, müssen die physischen Maschinen richtig konfiguriert sein. Diese Schritte sind nötig:

  • Betriebssystem installieren: Wähl eine schlanke Linux-Distribution wie Ubuntu oder eine andere deiner Wahl. In dieser Anleitung nehmen wir Ubuntu, weil es weit verbreitet und sehr gut dokumentiert ist.

  • Netzwerk konfigurieren: Geh nach der Installation die Netzwerkkonfiguration durch und gib jeder Maschine eine eindeutige IP-Adresse.

  • Passende Hostnamen vergeben: Bearbeite die Datei hostname im Verzeichnis etc, um jeder physischen Maschine einen sprechenden Namen zu geben, zum Beispiel «master node», «worker1» und «worker2». Bearbeite ausserdem die Datei hosts, um jeden Hostnamen mit seiner IP-Adresse zu verbinden.

Ports

Für die verschiedenen Rollen müssen unterschiedliche Ports offen sein:

Control Plane:

Protokoll Richtung Port Bereich Zweck Genutzt von
TCP Eingehend 6443 Kubernetes API Server Alle
TCP Eingehend 2379-2380 etcd Server Client API kube-apiserver, etcd
TCP Eingehend 10250 Kubelet API Selbst, Control Plane
TCP Eingehend 10259 kube-scheduler Selbst
TCP Eingehend 10257 kube-controller-manager Selbst

Die etcd-Ports stehen zwar bei der Control Plane, du kannst deinen etcd-Cluster aber auch extern oder auf eigenen Ports betreiben.

Worker Node(s):

Protokoll Richtung Port Bereich Zweck Genutzt von
TCP Eingehend 10250 Kubelet API Selbst
Control Plane
TCP Eingehend 30000-32767 NodePort Services Alle

Nach diesen Schritten ist auf jeder Maschine das nötige Betriebssystem installiert, und alle haben eindeutige Namen, die die Verwaltung erleichtern.

2. Eine Container Runtime installieren

Damit die Pods auf jedem Node im Cluster laufen können, braucht jeder Node eine Container Runtime.

Seit Kubernetes 1.29 ist eine Runtime nötig, die mit dem Container Runtime Interface (CRI) kompatibel ist. Details zu den unterstützten CRI-Versionen findest du in der entsprechenden Dokumentation.

Mit Kubernetes 1.29 lassen sich mehrere Runtimes verwenden:

  • containerd
  • CRI-O
  • Docker Engine
  • Mirantis Container Runtime

Da Kubernetes containerd gegenüber Docker bevorzugt, nehmen wir ebenfalls containerd.

containerd installieren

# das System aktualisieren
sudo apt-get update
sudo apt-get upgrade

# die Abhängigkeiten installieren
sudo apt-get install apt-transport-https ca-certificates curl gpg

# den GPG-Schlüssel von Docker hinzufügen
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# das Repository einrichten
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Hinweis: Wenn du eine von Ubuntu abgeleitete Distribution wie Linux Mint verwendest, musst du eventuell UBUNTU_CODENAME statt VERSION_CODENAME nehmen.

# den Paketindex aktualisieren
sudo apt-get update
sudo apt-get install -y containerd.io

containerd konfigurieren

# sicherstellen, dass containerd mit systemd startet
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/systemd_cgroup \= false/systemd_cgroup \= true/g' /etc/containerd/config.toml

# den containerd-Dienst neu starten und aktivieren
sudo systemctl restart containerd
sudo systemctl enable containerd

# prüfen, ob der Dienst erfolgreich gestartet ist
sudo systemctl status containerd

Eins erledigt. Die Runtime ist installiert. Weiter geht’s.

3. Swap deaktivieren

Swap ist ein Bereich auf der Festplatte, in dem das Betriebssystem Daten zwischenspeichert, wenn der physische Arbeitsspeicher voll ist. Er dient als Erweiterung des RAM und erlaubt dem Betriebssystem, inaktive Daten aus dem RAM auszulagern.

Kubernetes und containerisierte Anwendungen sind aber auf schnellen Zugriff auf physischen RAM ausgelegt. Deshalb musst du Swap deaktivieren, damit Kubernetes sich nicht auf den langsameren Swap verlässt.

Swap deaktivierst du mit diesem Befehl im Terminal:

sudo swapoff -a

Bearbeite die Datei fstab in /etc, damit die Swap-Datei nach einem Neustart nicht wieder angelegt wird. Kommentier die Zeile aus, die mit /swap... beginnt.

4. Kernel-Module laden und eine IPv4-Bridge einrichten

# benötigte Kernel-Module laden
sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# Kernel-Parameter für Kubernetes konfigurieren
sudo tee /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# die Änderungen anwenden
sudo sysctl --system

5. Kubernetes installieren

Jetzt installierst du die Kubernetes-Werkzeuge auf allen physischen Maschinen im Cluster. Die wichtigsten Werkzeuge:

  • kubeadm: zum Aufsetzen von Cluster und Nodes
  • kubelet: die Komponente, die auf allen Nodes läuft und sich um Dinge wie das Starten von Pods und Containern und das Melden des Node-Status kümmert
  • kubectl: das Kommandozeilenwerkzeug, mit dem du mit dem Cluster sprichst
# den GPG-Schlüssel von Kubernetes hinzufügen
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

ACHTUNG: Der nächste Schritt überschreibt eine bestehende Konfiguration in /etc/apt/sources.list.d/kubernetes.list

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# den Paketindex aktualisieren
sudo apt-get update

# kubelet, kubeadm und kubectl installieren und ihre Version fixieren
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Das kubelet startet jetzt alle paar Sekunden neu, weil es in einer Crash-Schleife darauf wartet, dass kubeadm ihm sagt, was es tun soll.

6. Den Master Node initialisieren

Um den Master Node zu initialisieren, verwenden wir kubeadm init. Gib mit dem Flag --pod-network-cidr den CIDR-Bereich an, der zum gewählten Pod-Netzwerk passt. Da wir Flannel verwenden, ist der CIDR 10.244.0.0/16.

Initialisier den Master Node mit diesem Befehl:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --upload-certs

Nach dem Befehl erscheint eine Ausgabe in der Form kubeadm join <master-node-ip>:<master-node-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>. Speichere sie, du brauchst sie später.

7. kubectl auf dem Master Node einrichten

Als Nächstes speichern wir die Konfiguration, damit wir mit kubectl auf den Cluster zugreifen können.

Dazu diese Befehle im Terminal eingeben:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Um zu prüfen, ob alles funktioniert, holen wir die Liste der Nodes:

kubectl get nodes

8. Ein Pod-Netzwerk-Add-on installieren

Damit die Nodes im Kubernetes-Cluster miteinander kommunizieren können, brauchst du ein Pod-Netzwerk-Add-on. Eine Liste der Optionen findest du auf der Kubernetes-Website.

Wenn du ein Add-on gewählt hast, installierst du es mit diesem Befehl:

kubectl apply -f <pod-network-addon>.yaml

Ersetze <pod-network-addon> durch die URL des gewählten Add-ons. Für Flannel zum Beispiel:

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

9. Worker Nodes zum Cluster hinzufügen

Nachdem der Master Node initialisiert und das Pod-Netzwerk konfiguriert ist, kannst du die Worker Nodes hinzufügen.

Dazu führst du auf jedem Node diesen Befehl aus:

sudo kubeadm join <master-node-ip>:<master-node-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

Ersetze dabei <master-node-ip>, <master-node-port>, <token> und <hash> durch die Werte, die du am Ende von Schritt 6 gespeichert hast.

10. Den Status des Clusters prüfen

Wenn alle Worker Nodes beim Master Node angemeldet sind, prüfst du den Status des Clusters.

Dazu gibst du auf dem Master Node diesen Befehl ein:

kubectl get nodes

Die Ausgabe sollte alle Worker Nodes mit dem Status «Ready» zeigen.

11. Anwendungen deployen

Wenn der Kubernetes-Cluster läuft, kannst du Anwendungen darauf deployen. Wenn du es zum Beispiel mit NGINX testen willst, gibst du diesen Befehl ein:

kubectl create deployment nginxtest1 --image=nginx

Mehr in Feldnotizen

Teilen