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
hostnameim Verzeichnisetc, um jeder physischen Maschine einen sprechenden Namen zu geben, zum Beispiel «master node», «worker1» und «worker2». Bearbeite ausserdem die Dateihosts, 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
fstabin/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