Kubernetes mit kubeadm auf Rocky Linux

Vorbereitung des Systems

Bevor du mit der Installation von Kubeadm beginnst, musst du dein Rocky Linux 9 System vorbereiten. Du musst sicherstellen, dass bestimmte Pakete und Abhängigkeiten installiert und die Systemeinstellungen korrekt sind.

Setzen des korrekten Hostnamens

Der folgenden Befehl setzt den Hostnamen des Systems auf seine eigene IP Adresse über den Dienst ip.dynlinux.io

sudo hostnamectl set-hostname $(hostname -I | cut -f 1 -d " " | tr . -).ip.dynlinux.io
sudo hostnamectl

Vollständige Aktualisierung des Systems

sudo dnf update -y

Dieser Befehl stellt sicher, dass alle Systempakete auf dem neuesten Stand sind.

Deaktivieren von SELinux

Kubernetes erfordert die Deaktivierung von SELinux, um ordnungsgemäß zu funktionieren. Du kannst dies tun, indem du die Konfigurationsdatei bearbeitest.

sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config

Nach der Deaktivierung über die Konfigurationsdatei muss das System neu gestartet werden.

Alternativ kannst du es auch temporär deaktivieren

sudo setenforce 0

Deaktivieren der Firewall

Die Firewall kann den Netzwerkverkehr zwischen den Kubernetes-Komponenten blockieren. Deaktiviere sie, um mögliche Probleme zu vermeiden:

sudo systemctl stop firewalld
sudo systemctl disable firewalld

Konfigurieren von IP-Weiterleitung und Bridge-Einstellungen

Für die Netzwerkinfrastruktur von Kubernetes ist die IP-Weiterleitung erforderlich. Erstelle die Konfigurationsdatei 99-kubernetes.conf

sudo tee /etc/sysctl.d/99-kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

Lade die Einstellungen neu

sudo sysctl --system

Lade das Kernelmodul br_netfilter

sudo tee /etc/modules-load.d/k8s.conf <<EOF
br_netfilter
EOF
sudo modprobe br_netfilter

Installation von Containerd

Containerd ist die Container-Laufzeitumgebung (Container Runtime), die von Kubernetes benötigt wird, um Container zu starten und zu verwalten. Kubernetes verwendet die Container Runtime Interface (CRI), um mit der Container-Laufzeitumgebung zu interagieren.

Installation der erforderlichen Pakete

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y containerd.io

Konfiguration von Containerd

Zuerst erstellst du eine Standardkonfiguration für Containerd:

sudo containerd config default | sudo tee /etc/containerd/config.toml

Anschließend bearbeitest du die Konfigurationsdatei, um das cgroupfs-System für das Systemd-Cgroup-Treiber-System zu verwenden:

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

Aktivierung und Starten von Containerd

sudo systemctl enable containerd
sudo systemctl restart containerd

Installation von Kubeadm, Kubelet und Kubectl

Nachdem Containerd eingerichtet ist, installierst du die Kubernetes-Tools.

Hinzufügen des Kubernetes-YUM-Repositorys

sudo tee /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/repodata/repomd.xml.key
EOF

⚠️ Hinweis: Die Versionsnummer v1.32 sollte an deine gewünschte Kubernetes-Version angepasst werden.

Installation der Kubernetes-Pakete

sudo dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

Dieser Befehl installiert die drei Hauptkomponenten:

  • kubelet: Der Agent, der auf jedem Knoten läuft und die Kommunikation mit dem Control Plane übernimmt.
  • kubeadm: Das Tool zum Bootstrapping des Clusters.
  • kubectl: Das Befehlszeilentool zur Interaktion mit dem Cluster.

Initialisierung des Control-Plane-Knotens

Jetzt kannst du den Control-Plane-Knoten (Master-Knoten) initialisieren. Dies ist der wichtigste Schritt, da er das Herzstück deines Kubernetes-Clusters bildet.

Initialisiere das Kubernetes Control Plane

sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint $IP:6443

Der Parameter –pod-network-cidr ist wichtig, da er das Netzwerk-Subnetz für die Pods festlegt. Der Wert 10.244.0.0/16 ist der Standard, der von vielen CNI-Plugins wie Flannel verwendet wird.

Starten und Aktivieren des Kubelet-Dienstes

sudo systemctl enable --now kubelet

Konfigurieren des Benutzers für kubectl

Nach der erfolgreichen Initialisierung musst du kubectl für den aktuellen Benutzer konfigurieren, um Befehle ausführen zu können:

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

Installieren eines Pod-Netzwerk-Addons

Ohne ein Pod-Netzwerk-Addon können die Pods nicht miteinander kommunizieren. Flannel ist eine beliebte Wahl.

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

Nach der Installation kannst du den Status der Pods überprüfen

kubectl get pods --all-namespaces

Erlaube pods auf der Control Plane

Auf der Control Plane solltest du keine Pods, die nicht zur Control Plane gehören - laufen lassen. Dies kann zu einer Instabilität der Control Plane führen.

Für Test-Setups ist es möglich auch auf der Control Plane Pods laufen zu lassen

kubectl taint nodes <node-name> node-role.kubernetes.io/control-plane:NoSchedule-

Hinzufügen von weiteren Control Plane-Knoten

Um weitere Control Plane-Knoten zu erstellen musst du zunächst die Zertifikatsdaten des Clusters ein Kubernetes Secret speichern. Dazu führst du auf einem existierenden Conntrol Plane-Knoten den folgenden Befehl aus.

sudo kubeadm init phase upload-certs --upload-certs

⚠️ Dieser Schritt ist für das Hinzufügen eines Workers nicht notwendig.

Der Certificate Key Name aus der Ausgabe des vorherigen Befehls wird für den kubeadm join benötigt. Der restliche Aufruf wird mit dem folgenden Befehl ausgegeben auf dem bestehenden Control Plane-Knoten.

sudo kubeadm token create --print-join-command

Den Ausgegebenen Befehl musst du nun um die Parameter --control-plane und --certificate-key <certificate-key-string> erweitern und auf dem neuen Control Plane-Knoten ausführen.

sudo kubeadm join <control-plane-IP>:<control-plane-port> \
     --token <token-string> --discovery-token-ca-cert-hash sha256:<hash-string> \
     --control-plane --certificate-key <certificate-key-string>

Sobald die zusätzliche Node bei kubectl get nodes auftaucht können die korrekten Label gesetzt werden.

kubectl label node <node-name> node-role.kubernetes.io/etcd=
kubectl label node <node-name> node-role.kubernetes.io/control-plane=

Hinzufügen von Worker-Knoten

Kubeadm gibt dir nach der Initialisierung einen kubeadm join-Befehl aus. Du musst diesen Befehl auf den Worker-Knoten ausführen, um sie dem Cluster hinzuzufügen.

sudo kubeadm join <control-plane-ip>:<control-plane-port> --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>

Dieser Befehl verbindet den Worker-Knoten mit dem Control Plane.

💡 Die Daten für diesen Befehl kannst du auf der Control Plane auslesen

kubeadm token create --print-join-command

Starten und Aktivieren des Kubelet-Dienstes auf dem Worker

sudo systemctl enable --now kubelet

Sobald die zusätzliche Node bei kubectl get nodes auftaucht können die korrekten Label gesetzt werden.

kubectl label node <node-name> node-role.kubernetes.io/worker=

Überprüfung des Clusters

Um sicherzustellen, dass dein Cluster ordnungsgemäß funktioniert, kannst du den Status der Knoten überprüfen:

kubectl get nodes

Die Ausgabe sollte alle Knoten (den Control-Plane-Knoten und alle hinzugefügten Worker-Knoten) als Ready anzeigen.

Testanwendung installieren

Wenn du eine Anwendung bereitstellen möchtest, kannst du dies mit einem Deployment-Befehl tun:

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --type=NodePort --port=80

Diese Befehle erstellen ein Deployment für eine Nginx-Webserver-Anwendung und legen einen Service vom Typ NodePort an, um die Anwendung über eine externe IP-Adresse zugänglich zu machen.

Deinstallieren der kompletten Installation

Uninstall k8s

## on control-plane
kubectl drain mynodename --force --ignore-daemonsets
kubectl delete node mynodename
## on node
sudo kubeadm reset --force
sudo systemctl stop kubelet
sudo dnf -f remove kubeadm kubectl kubelet kubernetes-cni kube*
sudo dnf -f autoremove
rm -rf ~/.kube
sudo rm -rf /var/lib/kubelet/*

Uninstall containerd

sudo systemctl disable --now containerd
sudo dnf -y remove yum-utils
sudo dnf -y remove containerd.io
sudo rm -rf /var/lib/containerd
sudo rm -rf /etc/containerd

Uninstall flannel

sudo rm -rf /var/lib/cni/
sudo rm -rf /run/flannel
sudo rm -rf /etc/cni/