<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://xinux.net/index.php?action=history&amp;feed=atom&amp;title=Kubernetes_Grundlagen_und_Cluster_Aufbau</id>
	<title>Kubernetes Grundlagen und Cluster Aufbau - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://xinux.net/index.php?action=history&amp;feed=atom&amp;title=Kubernetes_Grundlagen_und_Cluster_Aufbau"/>
	<link rel="alternate" type="text/html" href="https://xinux.net/index.php?title=Kubernetes_Grundlagen_und_Cluster_Aufbau&amp;action=history"/>
	<updated>2026-08-23T18:08:10Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Xinux Wiki</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://xinux.net/index.php?title=Kubernetes_Grundlagen_und_Cluster_Aufbau&amp;diff=72553&amp;oldid=prev</id>
		<title>Thomas.will: Die Seite wurde neu angelegt: „Dieser Artikel erklärt, warum der Schritt von Docker Compose zu Kubernetes notwendig wird, wie ein Kubernetes-Cluster aufgebaut ist, und baut anschließend ei…“</title>
		<link rel="alternate" type="text/html" href="https://xinux.net/index.php?title=Kubernetes_Grundlagen_und_Cluster_Aufbau&amp;diff=72553&amp;oldid=prev"/>
		<updated>2026-08-09T08:10:36Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „Dieser Artikel erklärt, warum der Schritt von Docker Compose zu Kubernetes notwendig wird, wie ein Kubernetes-Cluster aufgebaut ist, und baut anschließend ei…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Dieser Artikel erklärt, warum der Schritt von Docker Compose zu Kubernetes notwendig wird, wie ein Kubernetes-Cluster aufgebaut ist, und baut anschließend einen eigenen Cluster mit '''k3s''' auf vier virtuellen Maschinen auf: einem Server-Node, zwei Agent-Nodes und einem separaten Client.&lt;br /&gt;
&lt;br /&gt;
==Warum reicht Docker Compose nicht mehr==&lt;br /&gt;
&lt;br /&gt;
Mit Docker Compose lässt sich eine Anwendung aus mehreren Containern zuverlässig auf '''einem''' Host beschreiben und starten. Für Entwicklung und kleine Tests ist das ausreichend. Sobald eine Anwendung produktiv läuft, tauchen aber Fragen auf, die Compose grundsätzlich nicht beantworten kann.&lt;br /&gt;
&lt;br /&gt;
; Was passiert bei einem Host-Ausfall&lt;br /&gt;
* Fällt der Host aus, auf dem Compose läuft, ist die gesamte Anwendung nicht mehr erreichbar. Es gibt keinen zweiten Host, auf den automatisch ausgewichen wird.&lt;br /&gt;
&lt;br /&gt;
; Wie wird über mehrere Maschinen skaliert&lt;br /&gt;
* &amp;lt;code&amp;gt;docker compose up --scale web=3&amp;lt;/code&amp;gt; startet drei Instanzen – aber immer auf demselben Host. Reicht dessen CPU oder RAM nicht mehr aus, gibt es keinen Mechanismus, der auf eine zweite Maschine ausweicht.&lt;br /&gt;
&lt;br /&gt;
; Was passiert, wenn ein Container abstürzt&lt;br /&gt;
* Compose kann einen abgestürzten Container auf demselben Host neu starten (&amp;lt;code&amp;gt;restart: always&amp;lt;/code&amp;gt;). Es gibt aber keine Instanz, die aktiv überwacht, ob genügend Kapazität für einen Neustart überhaupt noch vorhanden ist.&lt;br /&gt;
&lt;br /&gt;
; Wie läuft ein Update ohne Downtime&lt;br /&gt;
* Ein &amp;lt;code&amp;gt;docker compose up -d&amp;lt;/code&amp;gt; nach einem Image-Wechsel ersetzt Container in der Regel abrupt. Ein kontrolliertes, schrittweises Update über mehrere Instanzen hinweg, bei dem immer genügend laufende Instanzen übrig bleiben, ist mit Compose nicht vorgesehen.&lt;br /&gt;
&lt;br /&gt;
Der eigentliche Sprung ist konzeptioneller Natur: Bei Compose '''startet''' man Container. Bei Kubernetes '''beschreibt''' man einen gewünschten Zielzustand (&amp;quot;es sollen drei Instanzen dieser Anwendung laufen&amp;quot;) – und ein fortlaufend aktiver Kontrollmechanismus sorgt dafür, dass dieser Zustand über beliebig viele Maschinen hinweg eingehalten wird, auch wenn einzelne Maschinen ausfallen.&lt;br /&gt;
&lt;br /&gt;
Dieses Prinzip nennt sich '''Self-Healing''': Stirbt eine Instanz, wird sie automatisch neu gestartet – bei Bedarf auf einer anderen Maschine. Genau dieses Verhalten wird am Ende dieses Artikels in einer Übung selbst provoziert und beobachtet.&lt;br /&gt;
&lt;br /&gt;
==Ziel dieses Kurses==&lt;br /&gt;
&lt;br /&gt;
Am Ende versteht ihr, warum eine Compose-Anwendung bei Skalierung und Ausfallsicherheit an ihre Grenzen stößt, und könnt dieselbe Anwendung so beschreiben, dass ein Cluster sie selbstständig am Laufen hält – auch wenn Nodes ausfallen, Images wechseln oder die Last steigt. Es geht nicht darum, jeden Kubernetes-Befehl auswendig zu können, sondern zu verstehen, was im Cluster passiert, wenn ein Pod stirbt, ein neues Image ausgerollt wird oder Traffic hereinkommt.&lt;br /&gt;
&lt;br /&gt;
==Architektur eines Kubernetes-Clusters==&lt;br /&gt;
&lt;br /&gt;
Ein Kubernetes-Cluster besteht aus zwei Arten von Maschinen (Nodes) mit unterschiedlichen Aufgaben.&lt;br /&gt;
&lt;br /&gt;
; Control Plane (Server-Node)&lt;br /&gt;
* Trifft alle Entscheidungen: Wo soll ein Container laufen, ist der gewünschte Zustand noch erfüllt, was passiert bei einem Ausfall. Der Server-Node führt selbst normalerweise keine Anwendungs-Container aus.&lt;br /&gt;
&lt;br /&gt;
; Worker-Nodes (Agent-Nodes)&lt;br /&gt;
* Hier laufen die eigentlichen Container. Ein Agent meldet sich beim Server-Node an, bekommt Arbeit zugewiesen und führt sie aus.&lt;br /&gt;
&lt;br /&gt;
; Der Client&lt;br /&gt;
* &amp;lt;code&amp;gt;kubectl&amp;lt;/code&amp;gt; ist das Kommandozeilenwerkzeug, mit dem der Cluster gesteuert wird. Es läuft bewusst '''nicht''' auf einem der Cluster-Nodes, sondern auf einem separaten Rechner (oder dem eigenen Laptop), der über das Netzwerk mit dem Server-Node spricht. Das ist ein wichtiger Unterschied zu einer Gewohnheit aus der Docker-Welt: Bei Docker meldet man sich häufig direkt auf dem Host an, um &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt;-Befehle auszuführen. Bei Kubernetes steuert man den Cluster von außen.&lt;br /&gt;
&lt;br /&gt;
In diesem Kurs werden vier Maschinen aufgesetzt:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Maschine !! Rolle !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| k8s-server || Control Plane || Server-Node, hier läuft k3s im Server-Modus&lt;br /&gt;
|-&lt;br /&gt;
| k8s-agent-1 || Worker || Erster Agent-Node&lt;br /&gt;
|-&lt;br /&gt;
| k8s-agent-2 || Worker || Zweiter Agent-Node&lt;br /&gt;
|-&lt;br /&gt;
| k8s-client || Client || Kein Cluster-Node, nur &amp;lt;code&amp;gt;kubectl&amp;lt;/code&amp;gt; und die Kubeconfig&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==k3s als Kubernetes-Distribution==&lt;br /&gt;
&lt;br /&gt;
Für den Cluster wird '''k3s''' verwendet, eine schlanke, aber vollständig zu Kubernetes kompatible Distribution.&lt;br /&gt;
&lt;br /&gt;
; Ein einziges Binary&lt;br /&gt;
* Statt vieler einzelner Komponenten (&amp;lt;code&amp;gt;kube-apiserver&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kube-scheduler&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;kube-controller-manager&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;etcd&amp;lt;/code&amp;gt; …) steckt bei k3s alles in einem Go-Binary.&lt;br /&gt;
&lt;br /&gt;
; SQLite statt etcd&lt;br /&gt;
* Als Standard-Datenspeicher nutzt k3s SQLite statt des ressourcenhungrigen etcd. Für ein Lab-Setup völlig ausreichend.&lt;br /&gt;
&lt;br /&gt;
; Geringer Ressourcenbedarf&lt;br /&gt;
* k3s läuft mit deutlich weniger RAM pro Node als ein klassischer Kubeadm-Aufbau – ideal für VirtualBox-VMs mit begrenzten Ressourcen.&lt;br /&gt;
&lt;br /&gt;
; Vollständig kompatible API&lt;br /&gt;
* Alle &amp;lt;code&amp;gt;kubectl&amp;lt;/code&amp;gt;-Befehle, Manifeste und Konzepte funktionieren bei k3s exakt so wie bei jedem anderen Kubernetes-Cluster. Was in diesem Kurs gelernt wird, gilt uneingeschränkt auch für größere Cluster.&lt;br /&gt;
&lt;br /&gt;
==Vorbereitung der virtuellen Maschinen==&lt;br /&gt;
&lt;br /&gt;
; Empfohlene VM-Ausstattung&lt;br /&gt;
* 1 vCPU, 2 GB RAM, 10 GB Festplatte je Node reichen für dieses Lab aus.&lt;br /&gt;
&lt;br /&gt;
; Basis-Image&lt;br /&gt;
* Ein minimales Debian oder Rocky Linux als Grundlage. Empfehlenswert: eine VM einmal vorbereiten (Betriebssystem installieren, &amp;lt;code&amp;gt;curl&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;open-vm-tools&amp;lt;/code&amp;gt;/Gastadditionen einrichten) und anschließend dreimal klonen.&lt;br /&gt;
&lt;br /&gt;
; Netzwerk-Konfiguration in VirtualBox&lt;br /&gt;
* Für die Kommunikation der Nodes untereinander wird ein '''Internal Network''' oder '''Host-only Adapter''' verwendet. Zusätzlich braucht jede VM einen zweiten Adapter im '''NAT'''-Modus, damit Pakete und Container-Images aus dem Internet geladen werden können.&lt;br /&gt;
&lt;br /&gt;
; Feste IP-Adressen vergeben&lt;br /&gt;
* Damit sich die Nodes zuverlässig finden, sollten feste IP-Adressen im internen Netz vergeben werden, zum Beispiel &amp;lt;code&amp;gt;192.168.56.10&amp;lt;/code&amp;gt; (Server), &amp;lt;code&amp;gt;192.168.56.11&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;192.168.56.12&amp;lt;/code&amp;gt; (Agents), &amp;lt;code&amp;gt;192.168.56.20&amp;lt;/code&amp;gt; (Client).&lt;br /&gt;
&lt;br /&gt;
==Installation des Server-Node==&lt;br /&gt;
&lt;br /&gt;
Auf der Maschine &amp;lt;code&amp;gt;k8s-server&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
; k3s im Server-Modus installieren&lt;br /&gt;
* &amp;lt;code&amp;gt;curl -sfL https://get.k3s.io | sh -&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Installation prüfen&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo k3s kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Join-Token auslesen&lt;br /&gt;
* Das Token wird für den Beitritt der Agent-Nodes benötigt.&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo cat /var/lib/rancher/k3s/server/node-token&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Installation der Agent-Nodes==&lt;br /&gt;
&lt;br /&gt;
Auf '''jeder''' der beiden Maschinen &amp;lt;code&amp;gt;k8s-agent-1&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;k8s-agent-2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
; k3s im Agent-Modus installieren und dem Cluster beitreten&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;amp;lt;SERVER_IP&amp;amp;gt;&amp;lt;/code&amp;gt; durch die IP-Adresse von &amp;lt;code&amp;gt;k8s-server&amp;lt;/code&amp;gt; ersetzen, &amp;lt;code&amp;gt;&amp;amp;lt;NODE_TOKEN&amp;amp;gt;&amp;lt;/code&amp;gt; durch das zuvor ausgelesene Token.&lt;br /&gt;
* &amp;lt;code&amp;gt;curl -sfL https://get.k3s.io | K3S_URL=https://&amp;amp;lt;SERVER_IP&amp;amp;gt;:6443 K3S_TOKEN=&amp;amp;lt;NODE_TOKEN&amp;amp;gt; sh -&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Beitritt vom Server aus prüfen&lt;br /&gt;
* Nach kurzer Zeit sollten auf &amp;lt;code&amp;gt;k8s-server&amp;lt;/code&amp;gt; beide Agents als &amp;lt;code&amp;gt;Ready&amp;lt;/code&amp;gt; erscheinen.&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo k3s kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==kubectl auf dem Client einrichten==&lt;br /&gt;
&lt;br /&gt;
Auf der Maschine &amp;lt;code&amp;gt;k8s-client&amp;lt;/code&amp;gt;, die '''nicht''' Teil des Clusters ist:&lt;br /&gt;
&lt;br /&gt;
; kubectl installieren&lt;br /&gt;
* &amp;lt;code&amp;gt;curl -LO &amp;quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Kubeconfig vom Server-Node holen&lt;br /&gt;
* Die Datei enthält die Zugangsdaten für den Cluster. Sie wird vom Server-Node kopiert und angepasst.&lt;br /&gt;
* &amp;lt;code&amp;gt;scp k8s-server:/etc/rancher/k3s/k3s.yaml ~/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Server-Adresse in der Kubeconfig anpassen&lt;br /&gt;
* Die kopierte Datei verweist standardmäßig auf &amp;lt;code&amp;gt;127.0.0.1&amp;lt;/code&amp;gt;. Das muss auf die tatsächliche IP-Adresse von &amp;lt;code&amp;gt;k8s-server&amp;lt;/code&amp;gt; geändert werden.&lt;br /&gt;
* In &amp;lt;code&amp;gt;~/.kube/config&amp;lt;/code&amp;gt; die Zeile &amp;lt;code&amp;gt;server: https://127.0.0.1:6443&amp;lt;/code&amp;gt; auf &amp;lt;code&amp;gt;server: https://&amp;amp;lt;SERVER_IP&amp;amp;gt;:6443&amp;lt;/code&amp;gt; ändern.&lt;br /&gt;
&lt;br /&gt;
; Verbindung testen&lt;br /&gt;
* &amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
* Es sollten alle drei Nodes (Server und beide Agents) mit Status &amp;lt;code&amp;gt;Ready&amp;lt;/code&amp;gt; erscheinen.&lt;br /&gt;
&lt;br /&gt;
==Übung: Cluster verifizieren==&lt;br /&gt;
&lt;br /&gt;
# Meldet euch auf &amp;lt;code&amp;gt;k8s-client&amp;lt;/code&amp;gt; an und prüft mit &amp;lt;code&amp;gt;kubectl get nodes -o wide&amp;lt;/code&amp;gt;, welche interne IP-Adresse jeder Node hat.&lt;br /&gt;
# Ermittelt mit &amp;lt;code&amp;gt;kubectl cluster-info&amp;lt;/code&amp;gt;, unter welcher Adresse die Control Plane erreichbar ist.&lt;br /&gt;
# Prüft mit &amp;lt;code&amp;gt;kubectl get pods -A&amp;lt;/code&amp;gt;, welche System-Pods bereits ohne euer Zutun im Cluster laufen (unter anderem CoreDNS und Traefik). Notiert euch, in welcher Namespace diese laufen.&lt;br /&gt;
# Führt &amp;lt;code&amp;gt;kubectl describe node k8s-agent-1&amp;lt;/code&amp;gt; aus und sucht im Abschnitt &amp;lt;code&amp;gt;Allocatable&amp;lt;/code&amp;gt; nach der verfügbaren CPU- und Speicherkapazität dieses Nodes.&lt;br /&gt;
&lt;br /&gt;
==Übung: Self-Healing beobachten==&lt;br /&gt;
&lt;br /&gt;
Diese Übung provoziert bewusst den zentralen Unterschied zu Docker Compose: Ein Pod stirbt, und der Cluster reagiert von selbst.&lt;br /&gt;
&lt;br /&gt;
# Startet eine einfache Test-Anwendung: &amp;lt;code&amp;gt;kubectl create deployment webtest --image=nginx:1.25 --replicas=1&amp;lt;/code&amp;gt;&lt;br /&gt;
# Prüft mit &amp;lt;code&amp;gt;kubectl get pods -o wide&amp;lt;/code&amp;gt;, auf welchem Agent-Node der Pod gelandet ist.&lt;br /&gt;
# Löscht den Pod gezielt (nicht das Deployment): &amp;lt;code&amp;gt;kubectl delete pod &amp;amp;lt;pod-name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# Prüft sofort danach erneut mit &amp;lt;code&amp;gt;kubectl get pods -o wide&amp;lt;/code&amp;gt; und beobachtet: Ein neuer Pod ist automatisch entstanden – möglicherweise sogar auf dem anderen Agent-Node.&lt;br /&gt;
# Überlegt gemeinsam: Was genau hat gemerkt, dass ein Pod fehlt, und wer hat entschieden, ihn neu zu starten? (Antwort wird im weiteren Kursverlauf beim Thema Deployments und Controller vertieft.)&lt;br /&gt;
# Räumt zum Abschluss auf: &amp;lt;code&amp;gt;kubectl delete deployment webtest&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Übung: Grenzen von Compose selbst erleben==&lt;br /&gt;
&lt;br /&gt;
# Simuliert einen Node-Ausfall, indem ihr &amp;lt;code&amp;gt;k8s-agent-1&amp;lt;/code&amp;gt; in VirtualBox herunterfahrt, während dort Pods laufen.&lt;br /&gt;
# Beobachtet mit &amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;, wie lange es dauert, bis der Node als &amp;lt;code&amp;gt;NotReady&amp;lt;/code&amp;gt; markiert wird.&lt;br /&gt;
# Beobachtet mit &amp;lt;code&amp;gt;kubectl get pods -o wide&amp;lt;/code&amp;gt;, was mit den Pods passiert, die vorher auf &amp;lt;code&amp;gt;k8s-agent-1&amp;lt;/code&amp;gt; liefen.&lt;br /&gt;
# Startet &amp;lt;code&amp;gt;k8s-agent-1&amp;lt;/code&amp;gt; wieder und prüft, ob der Node wieder automatisch dem Cluster beitritt.&lt;/div&gt;</summary>
		<author><name>Thomas.will</name></author>
	</entry>
</feed>