Geführter Lehrgang
Docker & Containerisierung
Von der ersten Container-Idee bis zu Netzwerk, Storage, Security und Kubernetes-Grundlagen.
Arbeite diese Seite von oben nach unten durch. Jeder Schritt enthält die einfache Erklärung, Praxis, technische Tiefe und den Quick-Check aus dem Glossar.
Von der ersten Container-Idee bis zu Netzwerk, Storage, Security und Kubernetes-Grundlagen.
2 bis 6 Wochen, grob 26+ Stunden aktive Lernzeit
Keine besonderen Voraussetzungen außer sauberem Lesen und eigenem Ausprobieren.
Du kannst die Begriffe erklären, typische Fälle einordnen, Grenzen benennen und mit Quick-Checks prüfen, ob das Wissen sitzt.
- Lokaler Lerner0 XP
- Backend-Ranking folgtGlobal
Abschlussprüfung
24 Fragen aus den Quick-Checks dieses Lernpfads. Erst antworten, dann Musterlösung öffnen und selbst bewerten.
Schritt 1 / 35
Docker
Was Container sind und warum sie Software reproduzierbar machen.
S1
Schritt 1 / 35
Docker
Was Container sind und warum sie Software reproduzierbar machen.
1. Verstehen
Stell dir vor, du willst einen Kuchen backen (eine App laufen lassen). Normalerweise brauchst du eine Küche (Server) mit dem richtigen Ofen, den richtigen Schüsseln und Zutaten. Wenn die Küche anders ist (anderes Betriebssystem), gelingt der Kuchen nicht. Docker ist wie eine Tupperware-Box (Container), in der die komplette Küche inkl. Ofen und Zutaten schon drin ist. Du nimmst die Box, stellst sie irgendwo hin, machst sie auf, und der Kuchen ist fertig. Egal, ob die Box auf einem Windows-PC, einem Mac oder einem Linux-Server steht – drinnen ist es immer gleich.
Merksatz: Eine Technologie, um Software in isolierte Pakete (Container) zu verpacken, die überall gleich laufen.
2. Anwenden
Ohne Docker: "Bei mir läuft es, aber auf dem Server nicht!" (Der Klassiker: "It works on my machine"). Weil du Python 3.9 hast und der Server Python 3.8.
Mit Docker:
Du schreibst eine Bauanleitung (Dockerfile): "Nimm Python 3.9, kopiere meinen Code rein, starte es."
Docker baut daraus ein Image (die Blaupause).
Aus dem Image startest du einen Container (die laufende App).
Du gibst dem Kollegen das Image, und er hat garantiert 1:1 die gleiche Umgebung wie du.
:level1
Praxisbruecke: Der typische Anfängerfluss lautet: Image suchen, Container starten, Logs lesen, Port prüfen, Container stoppen. Wer diese fuenf Schritte sicher kann, versteht Docker im Alltag deutlich besser.
3. Technisch einordnen
1. Container vs. VM (Virtuelle Maschine)
- VM: Ein ganzes Haus im Haus. Jede VM hat ein eigenes, komplettes Betriebssystem (Kernel). Schwer und langsam (Startzeit Minuten).
- Container: Ein Zelt im Haus. Alle Container teilen sich den Kernel des Wirts-Systems (Host). Leicht und schnell (Startzeit Millisekunden).
2. Docker Compose
Eine App besteht selten nur aus einem Teil. Du brauchst Webserver + Datenbank + Cache.
Mit docker-compose.yml beschreibst du das ganze Orchester:
"Starte Wordpress (Container A) und MySQL (Container B) und verbinde sie."
Ein Befehl: docker-compose up – und die ganze Landschaft steht.
Technisch ist Docker eine Werkzeugkette aus Client, Daemon, Images, Containern, Netzwerken, Volumes und Registries. Probleme entstehen oft, wenn man diese Bausteine vermischt.
4. Vertiefen
1. Architektur: Client-Server Trennung (REST API)
Viele Entwickler denken, docker auf der Command Line wäre das System selbst.
Falsch. Der docker CLI Command auf deinem Mac ist nur ein "dummer" HTTP-Client.
Er feuert ein JSON via cURL-artigem Stream an den UNIX-Socket /var/run/docker.sock.
Dahinter sitzt erst der mächtige Docker Daemon (dockerd). Der Daemon ist das Hirn: Er baut Architektur auf, kommandiert den Kernel, pullt Images und erstellt Netzwerke. Weil es eine strikte Client/Server-REST-Trennung ist, kannst du von deinem Windows Laptop aus völlig nativ über SSH den dockerd eines AWS Amazon-Linux-Servers im Hintergrund fernsteuern.
2. Containerd und RunC (Die Evolution)
Früher war "Docker" ein einziger monolithischer Go-Block.
Heute hat die Industrie Docker in Bausteine gesprengt (um Standards wie OCI zu schaffen).
Der dockerd (Daemon) macht fast nichts Großes mehr. Wenn du Container startest, reicht dockerd das Kommando an containerd weiter (High-Level Runtime, gemanaged von Kubernetes/CNCF). containerd reicht das an runc weiter (Low-Level C-Runtime). runc spricht mit dem Linux-Kernel per C-Primitiven und vollzieht die Kernel-Isolation (Namespaces, cgroups), übergibt den Exec-Code und stirbt sofort wieder. Der Container "hängt" fortan lose im containerd-Sheduler. Diese massive Schichten-Architektur minimiert Crash-Flächen massiv.
3. Docker on Mac/Windows: Die Virtualisierungs-Lüge
Ein Linux-Container erfordert einen nativen Linux-Kernel zur Ausführung (da er nicht wie im VMware modell simulieren kann, was nicht da ist). Auf Linux Servern klappt Docker deswegen unfassbar gut. Wie funktionieren Docker-Container dann auf Windows und MacOS, obwohl diese keine Unix/Linux Kernel (cgroups) besitzen? Es ist ein Hack: Docker Desktop installiert heimlich eine "echte" Linux-Virtuelle-Maschine (Hyper-V / WSL2 auf Windows, oder QEMU/HyperKit auf macOS) unsichtbar in den Hintergrund deines Rechners. In dieser unsichtbaren kleinen Linux-VM rennt der Docker Daemon. Dein lokales macOS Terminal schickt nur API-Befehle durch den Hypervisor-Tunnel dorthin. Resultat: Exzellent für Entwicklung, aber grottenschlechte Performance beim I/O-Dateimount zwischen Mac-SSD und Linux-VM.
5. Prüfen
Was ist der Unterschied zwischen Image und Container?
Das Image ist das Rezept (tote Datei). Der Container ist der Kuchen (lebender Prozess). Du kannst aus einem Image beliebig viele Container starten.Brauche ich Docker als Anfänger?
Ja! Es ist der einfachste Weg, Datenbanken oder Tools auszuprobieren ("docker run postgres"), ohne deinen PC zuzumüllen.Sind Daten im Container sicher?
Jein. Wenn du einen Container löschst, sind alle Daten darin weg (ephemeral). Deshalb speichert man wichtige Daten immer außerhalb des Containers (in "Volumes").
Zusammenfassung
- Stell dir vor, du willst einen Kuchen backen (eine App laufen lassen). Normalerweise brauchst du eine Küche (Server) mit dem richtigen Ofen, den richtigen Schüsseln und Zutaten. Wenn die Küche anders ist (anderes Betriebssystem), gelingt der Kuchen nicht....
- Ohne Docker: "Bei mir läuft es, aber auf dem Server nicht!" (Der Klassiker: "It works on my machine"). Weil du Python 3.9 hast und der Server Python 3.8.
- Technisch ist Docker eine Werkzeugkette aus Client, Daemon, Images, Containern, Netzwerken, Volumes und Registries. Probleme entstehen oft, wenn man diese Bausteine vermischt.
Optionale Praxisaufgabe
- Erkläre Docker in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Betriebssystem (OS) S1
Überblick: Das Betriebssystem (OS) ist der Manager deines Computers. Hardware (Maus, Bildschirm, Prozessor) ist dumm. Software (Word, Spiele) ist anspruchsvoll. Das OS vermittelt zwischen den beiden. Es sagt: "Word darf jetzt drucken." "Chrome bekommt 2 GB Speicher." "Das WLAN-Passwort ist 1234."
Einfach erklärt: Für den normalen Nutzer ist das OS der Computer. Du interagierst fast nur über die GUI (Grafische Oberfläche) des OS: Dateimanager (Explorer/Finder) zum Ordnen von Dateien. Taskleiste/Dock zum Starten von Apps. Einstellungen für Helligkeit, Netzwerk und Updates.
Warum laufen iPhone-Apps nicht auf Android?
Weil beide Betriebssysteme (iOS vs. Android) eine völlig unterschiedliche "Sprache" und Struktur haben. Die App findet nicht die Bausteine, die sie erwartet.Was ist der Unterschied zwischen Kernel und GUI?
Der Kernel ist der unsichtbare Motor, der die Technik steuert. Die GUI ist das hübsche Lenkrad, das der Benutzer bedient.Warum braucht man Treiber?
Damit das Betriebssystem auch Hardware verstehen kann, die es beim Bau des OS noch gar nicht gab (z. B. ein ganz neuer Drucker).
Server S1
Überblick: Ein Server ist ein Diener (engl. "to serve" = dienen). Es ist ein Computer, der darauf wartet, dass andere (Clients) etwas von ihm wollen. Webserver: "Zeig mir diese Webseite!" Mailserver: "Nimm meine E-Mail an!" Fileserver: "Speichere diese Datei!"
Einfach erklärt: Im Büro steht oft ein "Serverraum". Da steht der Firmenserver. Darauf liegen alle Word-Dateien, damit alle Kollegen gleichzeitig darauf zugreifen können. Wenn der Server abstürzt, kann keiner arbeiten ("Das Netz ist weg").
Tiefer verstanden: Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Braucht ein Server einen Bildschirm?
Nein. Man verwaltet ihn "headless" (kopflos) über das Netzwerk (Fernwartung mit SSH oder Remote Desktop). Ein Monitor steht nur für Notfälle im Serverraum.Was ist "Server Down"?
Der Server reagiert nicht. Gründe: Stromausfall, Internet weg, abgestürzt oder überlastet (DDoS).Warum sind Server so laut?
Wegen den Lüftern. Sie erzeugen enorme Hitze und müssen extrem gekühlt werden. Die kleinen Lüfter drehen mit 15.000 Umdrehungen pro Minute und klingen wie ein Triebwerk.
Virtualisierung S1
Überblick: Virtualisierung ist Inception für Computer. Du hast einen echten Computer (Hardware). Darauf installierst du eine Software, die so tut, als wäre sie noch ein Computer. Du kannst Windows in einem Fenster auf deinem Mac laufen lassen. Der echte Computer heißt Host (Wirt). Der virtuelle Computer heißt Guest (Gast).
Einfach erklärt: Warum macht man das? 1. Effizienz: Ein Server langweilt sich oft (5% Auslastung). Mit 10 VMs darauf ist er zu 50% ausgelastet - Strom gespart. 2. Sicherheit: Wenn du Viren testen willst, machst du das in einer VM. Wenn der Virus alles zerstört, löschst du einfach die VM-Datei und startest neu. Dein echter PC bleibt heil (Sandbox). 3. Legacy: Deine uralte Buchhaltungs-Software läuft nur auf Windows 98? Installiere Windows 98 in einer VM.
Kann ich Fortnite in einer VM spielen?
Schwierig. Grafikkarten-Virtualisierung ist komplex. Meistens ruckelt es, weil die VM keinen direkten Zugriff auf die GPU-Power hat. Cloud-Gaming (GeForce Now) löst das anders.Was ist der Unterschied zu Containern (Docker)?
Eine VM virtualisiert die Hardware (eigener Kernel). Ein Container virtualisiert das Betriebssystem (geteilter Kernel). Container sind viel leichter, aber VMs sind stärker isoliert.Kann eine VM ausbrechen?
Sehr selten ("VM Escape"). Wenn der Hypervisor einen Bug hat, könnte der Gast auf den Wirt zugreifen. Das ist der Super-GA für Cloud-Anbieter.
Schritt 2 / 35
Container
Die laufende Instanz eines Images verstehen.
S1
Schritt 2 / 35
Container
Die laufende Instanz eines Images verstehen.
1. Verstehen
Ein Container ist wie eine Lunchbox für Software. Wenn du dein Mittagessen (Nudeln) einfach so in den Rucksack wirfst, vermischt es sich mit deinen Büchern (Chaos). Wenn du es in eine Lunchbox tust, ist es sicher und du kannst es überall hin mitnehmen (Schule, Arbeit, Picknick). Software hat das gleiche Problem: Sie vermischt sich oft mit dem Betriebssystem und geht kaputt. In einem Container ist alles drin, was die Software braucht (Code, Bibliotheken). Sie läuft dadurch auf jedem Computer gleich.
Merksatz: Eine isolierte Umgebung, die Software und alle ihre Abhängigkeiten verpackt, damit sie überall läuft.
2. Anwenden
Das wichtigste Tool für Container ist Docker. Prozess:
- Entwickler schreibt Code.
- Entwickler packt Code in Container ("Build").
- Entwickler gibt Container an Server.
- Server führt Container aus ("Run").
Vorteil: "Bei mir läuft es, aber auf dem Server nicht" gibt es nicht mehr. Wenn der Container auf dem Laptop läuft, läuft er auch in der Cloud.
:level1
Praxisbruecke: Ein Container ist kein kompletter Computer. Er nutzt den Kernel des Hosts, bringt aber eigene Dateien, Prozesse und Umgebungsvariablen mit. Ports und Volumes verbinden ihn gezielt mit der Aussenwelt.
3. Technisch einordnen
1. Isolation (Namespaces & Cgroups)
Wie funktioniert die Magie? Linux-Features!
- Namespaces: Lügen dem Prozess vor, er wäre allein auf der Welt. "Du bist Prozess Nr. 1 und hast dein eigenes Netzwerk."
- Cgroups (Control Groups): Begrenzen die Ressourcen. "Du darfst nur 512 MB RAM und 1 CPU-Kern nutzen."
2. Microservices
Container sind der Baustein für moderne Architektur. Statt einem Riesen-Programm (Monolith) baut man 50 kleine Container (Microservices), die miteinander reden. Wenn einer abstürzt, laufen die anderen 49 weiter.
:level2Technisch endet ein Container, wenn sein Hauptprozess endet. Darum ist wichtig, welcher Prozess im Vordergrund läuft, welche Dateien persistent sind und welche Daten beim Loeschen verschwinden.
4. Vertiefen
1. Linux Kernel Namespaces
Die größte Illusion der Informatik. Ein Container "existiert" eigentlich gar nicht als echtes Objekt, er ist nur ein normaler Linux-Prozess, dem der Kernel Scheuklappen anlegt. Das passiert mit Namespaces.
- PID Namespace: Der Browser im Container denkt, er ist der einzige Prozess (
PID 1). Tatsächlich ist er auf dem Host-System in Wahrheit Prozess Nummer34091. - Net Namespace: Der Container erhält eine isolierte Netzwerkkarte (veth-Interface) und eine eigene IP-Adresse. Er "sieht" die Netzwerkkarten des Host-Systems nicht.
- Mount Namespace: Der Container bekommt einen fingierten Datei-Baum (
/). Er kann physikalisch die Festplatte des Hosts/home/usernicht "sehen" oder mounten, es sei denn, man perforiert diesen Namespace explizit via Bind-Mounts.
2. Cgroups (Control Groups)
Wenn Namespaces sagen "Was darf der Container sehen?", dann sagen Cgroups, "Wie viel darf er verbrauchen?". Cgroups sind ein Kernel-Feature (ursprünglich von Google entwickelt). Sie rationieren Hardware. Man kann einen Container in eine Cgroup packen und definieren: Maximal 500 MB RAM, nur Zugriff auf CPU Core 2, und maximal 10 Megabyte pro Sekunde Schreibgeschwindigkeit auf der SSD (Solid State Drive). Versucht der Code mehr RAM anzufordern, greift der Kernel hart ein und killt den Prozess (OOM-Kill, Out of Memory).
3. Layered File Systems (UnionFS / OverlayFS)
Wenn 10 Container auf einem Server laufen und jeder ein Ubuntu-Base-Image (70 MB) hat, verbraucht das nicht 700 MB Speicherplatz. Container nutzen OverlayFS. Ein Container-Image besteht aus schreibgeschützten (Read-Only) Schichten (Layers). Haben zehn Container denselben Base-Layer, liegt diese 70 MB Schicht nur ein einziges Mal physikalisch auf der SSD. Darüber legt Docker beim Start eine extrem dünne "Read/Write"-Schicht für den jeweiligen Container (oft nur wenige KB groß). Wenn der Container stirbt, wirft Docker nur diese oberste R/W-Folie weg, die Read-Only Schichten darunter bleiben unberührt. Das macht das Starten von Containern blitzschnell (Millisekunden) und speichereffizient.
5. Prüfen
Ist ein Container eine Virtuelle Maschine?
Nein. Eine VM simuliert einen ganzen PC (inkl. Hardware und Kernel). Ein Container nutzt den Kernel des Wirts (Host) mit. Container sind viel leichter und schneller.Was ist Kubernetes?
Ein "Container-Kapitän". Wenn du 1.000 Container hast, kannst du sie nicht von Hand starten. Kubernetes managt sie ("Start Container A neu, wenn er abstürzt").Sind Container sicher?
Ja, aber weniger isoliert als VMs. Wenn der Kernel einen Fehler hat, könnten alle Container betroffen sein ("Container Breakout"). Aber für normale Apps reicht es völlig.
Zusammenfassung
- Ein Container ist wie eine Lunchbox für Software. Wenn du dein Mittagessen (Nudeln) einfach so in den Rucksack wirfst, vermischt es sich mit deinen Büchern (Chaos). Wenn du es in eine Lunchbox tust, ist es sicher und du kannst es überall hin mitnehmen...
- Das wichtigste Tool für Container ist Docker. Prozess: 1. Entwickler schreibt Code. 2. Entwickler packt Code in Container ("Build"). 3. Entwickler gibt Container an Server. 4. Server führt Container aus ("Run").
- Technisch endet ein Container, wenn sein Hauptprozess endet. Darum ist wichtig, welcher Prozess im Vordergrund läuft, welche Dateien persistent sind und welche Daten beim Loeschen verschwinden.
Optionale Praxisaufgabe
- Erkläre Container in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Container relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Betriebssystem (OS) S1
Überblick: Das Betriebssystem (OS) ist der Manager deines Computers. Hardware (Maus, Bildschirm, Prozessor) ist dumm. Software (Word, Spiele) ist anspruchsvoll. Das OS vermittelt zwischen den beiden. Es sagt: "Word darf jetzt drucken." "Chrome bekommt 2 GB Speicher." "Das WLAN-Passwort ist 1234."
Einfach erklärt: Für den normalen Nutzer ist das OS der Computer. Du interagierst fast nur über die GUI (Grafische Oberfläche) des OS: Dateimanager (Explorer/Finder) zum Ordnen von Dateien. Taskleiste/Dock zum Starten von Apps. Einstellungen für Helligkeit, Netzwerk und Updates.
Warum laufen iPhone-Apps nicht auf Android?
Weil beide Betriebssysteme (iOS vs. Android) eine völlig unterschiedliche "Sprache" und Struktur haben. Die App findet nicht die Bausteine, die sie erwartet.Was ist der Unterschied zwischen Kernel und GUI?
Der Kernel ist der unsichtbare Motor, der die Technik steuert. Die GUI ist das hübsche Lenkrad, das der Benutzer bedient.Warum braucht man Treiber?
Damit das Betriebssystem auch Hardware verstehen kann, die es beim Bau des OS noch gar nicht gab (z. B. ein ganz neuer Drucker).
Software S1
Überblick: Software ist der Teil eines Computers, den man nicht anfassen kann: Programme, Apps, Betriebssysteme, Treiber und Skripte. Hardware ist das Gerät, Software sagt dem Gerät, was es tun soll. Ohne Software wäre ein Computer nur Elektronik ohne Aufgabe.
Einfach erklärt: Ein Browser, ein Textprogramm, ein Spiel, eine App und ein Serverdienst sind Software. Nutzer installieren oder öffnen sie, Entwickler schreiben und pflegen sie. Unternehmen achten auf Updates, Lizenzen, Sicherheit, Kompatibilitaet und Support.
Tiefer verstanden: Software kann aus Quellcode, Bibliotheken, Konfigurationsdateien, Assets und Build-Artefakten bestehen. Moderne Systeme trennen oft Frontend, Backend, Datenbank, Infrastrukturcode und Automatisierungen. Qualität entsteht durch Tests, Reviews, Versionierung, Monitoring und klare Architektur.
Praxisgrenze: Software altert, auch wenn sie nicht angefasst wird: Abhaengigkeiten bekommen Sicherheitslücken, Plattformen ändern sich, Daten wachsen und Nutzeranforderungen verschieben sich. Deshalb ist Wartbarkeit wichtiger als nur "es läuft gerade". Schlechte Update- und Backup-Prozesse machen harmlose Änderungen riskant.
Was unterscheidet Software von Hardware?
Hardware ist das physische Gerät. Software sind Programme, Regeln und Daten, die auf dieser Hardware laufen.Warum braucht Software Updates?
Updates beheben Fehler, Sicherheitslücken, Kompatibilitaetsprobleme und erweitern Funktionen.Was ist eine typische Praxisfalle?
Nur auf sichtbare Features zu achten und Wartung, Tests, Lizenzen und Sicherheit zu ignorieren.
Virtualisierung S1
Überblick: Virtualisierung ist Inception für Computer. Du hast einen echten Computer (Hardware). Darauf installierst du eine Software, die so tut, als wäre sie noch ein Computer. Du kannst Windows in einem Fenster auf deinem Mac laufen lassen. Der echte Computer heißt Host (Wirt). Der virtuelle Computer heißt Guest (Gast).
Einfach erklärt: Warum macht man das? 1. Effizienz: Ein Server langweilt sich oft (5% Auslastung). Mit 10 VMs darauf ist er zu 50% ausgelastet - Strom gespart. 2. Sicherheit: Wenn du Viren testen willst, machst du das in einer VM. Wenn der Virus alles zerstört, löschst du einfach die VM-Datei und startest neu. Dein echter PC bleibt heil (Sandbox). 3. Legacy: Deine uralte Buchhaltungs-Software läuft nur auf Windows 98? Installiere Windows 98 in einer VM.
Kann ich Fortnite in einer VM spielen?
Schwierig. Grafikkarten-Virtualisierung ist komplex. Meistens ruckelt es, weil die VM keinen direkten Zugriff auf die GPU-Power hat. Cloud-Gaming (GeForce Now) löst das anders.Was ist der Unterschied zu Containern (Docker)?
Eine VM virtualisiert die Hardware (eigener Kernel). Ein Container virtualisiert das Betriebssystem (geteilter Kernel). Container sind viel leichter, aber VMs sind stärker isoliert.Kann eine VM ausbrechen?
Sehr selten ("VM Escape"). Wenn der Hypervisor einen Bug hat, könnte der Gast auf den Wirt zugreifen. Das ist der Super-GA für Cloud-Anbieter.
RAM S1
Überblick: RAM ist das Kurzzeitgedächtnis deines Computers. Alles, was du gerade jetzt machst (diese Webseite lesen, Musik hören), liegt im RAM. Es ist extrem schnell, aber vergesslich. Sobald du den Strom ausschaltest, ist der RAM leer. Deshalb musst du deine Hausarbeit speichern (auf die Festplatte schreiben), bevor du den PC herunterfährst.
Einfach erklärt: Wie viel RAM brauchst du? 8 GB: Standard für Surfen und Office. 16 GB: Gut für Gaming und Fotobearbeitung. 32 GB+: Für Videoschnitt und Profi-Anwendungen.
Warum speichert man nicht einfach alles im RAM?
1. Weil alles weg wäre, wenn der Strom ausfällt. 2. Weil RAM viel teurer ist als SSD-Speicher (pro Gigabyte).Was bedeutet "Chrome frisst RAM"?
Jeder offene Tab in Chrome ist ein eigener Prozess. Das ist sicher (wenn einer abstürzt, lebt der Rest weiter), kostet aber viel Arbeitsspeicher.Was ist der Unterschied zu VRAM?
VRAM (Video RAM) sitzt auf der Grafikkarte. Er ist speziell dafür optimiert, riesige Texturen und 3D-Modelle für Spiele zu speichern.
CPU S1
Überblick: Die CPU (Central Processing Unit) ist das Gehirn deines Computers. Sie erledigt alle Denkaufgaben. Jedes Mal, wenn du die Maus bewegst, eine Webseite öffnest oder 1+1 rechnest, ist es die CPU, die das macht. Sie ist ein winziger Chip (kleiner als ein Keks), der aber Milliarden von Befehlen pro Sekunde ausführen kann.
Einfach erklärt: Beim Kauf eines PCs achtet man auf zwei Dinge: 1. Kerne (Cores): Wie viele Aufgaben kann er gleichzeitig machen? 2 Kerne = Du kannst surfen und Musik hören. 8 Kerne = Du kannst spielen, streamen und Videos schneiden gleichzeitig. 2. Taktfrequenz (GHz): Wie schnell denkt er? 3 GHz = 3 Milliarden Takte pro Sekunde. (Schneller = Besser für Spiele).
Was ist wichtiger: Viele Kerne oder viel GHz?
Kommt drauf an. Für Gaming oft GHz (Single-Core Speed). Für Videoschnitt und Multitasking eher Kerne (Multi-Core Speed).Warum wird die CPU heiß?
Weil Milliarden von Elektronen mit hoher Geschwindigkeit durch winzige Leiterbahnen flitzen. Der elektrische Widerstand erzeugt Wärme, die der Lüfter wegblasen muss.Was ist der Unterschied zur GPU (Grafikkarte)?
Die CPU ist ein Alleskönner (wenige, starke Kerne). Die GPU ist ein Spezialist für Bilder (tausende, dumme Kerne), perfekt für parallele Aufgaben wie 3D-Grafik oder KI.
SSD (Solid State Drive) S1
Überblick: Früher hatten Computer HDDs (Hard Disk Drives). Da drehte sich drinnen eine Magnetscheibe wie bei einem Plattenspieler. Das war laut, empfindlich und langsam. Eine SSD hat keine beweglichen Teile. Sie besteht aus Speicherchips (wie ein riesiger USB-Stick). Sie ist lautlos. Sie ist robust (kann runterfallen). Sie ist extrem schnell (Windows startet in 10 Sekunden statt 2 Minuten).
Einfach erklärt: Es gibt zwei Bauformen: 1. SATA-SSD: Sieht aus wie eine kleine Zigarrenschachtel (2,5 Zoll). Wird mit Kabel angeschlossen. (ca. 500 MB/s). 2. NVMe (M.2): Sieht aus wie ein Riegel Kaugummi. Wird direkt aufs Mainboard gesteckt. Extrem schnell (bis zu 7.000 MB/s).
Sollte ich meine Festplatte defragmentieren?
SSD auf keinen Fall! Defragmentieren sortiert Daten um (viele Schreibvorgänge). Das nutzt die SSD unnötig ab und bringt keinen Geschwindigkeitsvorteil (weil sie eh überall sofort zugreifen kann).Sind SSDs teurer als HDDs?
Ja, pro Gigabyte. Für Datengräber (Fotosammlung, Backups) lohnen sich noch alte HDDs (4 TB HDD = 80 €, 4 TB SSD = 250 €).Gehen Daten auf der SSD verloren ohne Strom?
Nein, es ist "nicht-volatiler" Speicher. Theoretisch können SSDs nach Jahren ohne Strom Daten verlieren (Bit Rot), aber für den Alltag ist das irrelevant.
Server S1
Überblick: Ein Server ist ein Diener (engl. "to serve" = dienen). Es ist ein Computer, der darauf wartet, dass andere (Clients) etwas von ihm wollen. Webserver: "Zeig mir diese Webseite!" Mailserver: "Nimm meine E-Mail an!" Fileserver: "Speichere diese Datei!"
Einfach erklärt: Im Büro steht oft ein "Serverraum". Da steht der Firmenserver. Darauf liegen alle Word-Dateien, damit alle Kollegen gleichzeitig darauf zugreifen können. Wenn der Server abstürzt, kann keiner arbeiten ("Das Netz ist weg").
Tiefer verstanden: Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Braucht ein Server einen Bildschirm?
Nein. Man verwaltet ihn "headless" (kopflos) über das Netzwerk (Fernwartung mit SSH oder Remote Desktop). Ein Monitor steht nur für Notfälle im Serverraum.Was ist "Server Down"?
Der Server reagiert nicht. Gründe: Stromausfall, Internet weg, abgestürzt oder überlastet (DDoS).Warum sind Server so laut?
Wegen den Lüftern. Sie erzeugen enorme Hitze und müssen extrem gekühlt werden. Die kleinen Lüfter drehen mit 15.000 Umdrehungen pro Minute und klingen wie ein Triebwerk.
Schritt 3 / 35
Docker Image
Images als Bauplan für Container lesen.
S1
Schritt 3 / 35
Docker Image
Images als Bauplan für Container lesen.
1. Verstehen
Wenn du einen Container starten willst, brauchst du eine Vorlage. Diese Vorlage ist das Docker Image. Es ist wie ein Schnappschuss (Snapshot) von einem kompletten Computer. Darin ist:
- Das Betriebssystem (Linux Alpine, Ubuntu).
- Die Tools (Python, Node.js).
- Dein Code (
app.py). Der Clou: Ein Image ist unveränderlich (Immutable). Wenn du es einmal gebaut hast, ändert es sich nie wieder (außer du baust eine neue Version v2). Wenn du 10 Container aus einem Image startest, sind alle 10 beim Start exakt gleich.
Merksatz: Ein schreibgeschütztes Template, das alle notwendigen Dateien (Code, Libraries, Dependencies, OS) enthält, um einen Container auszuführen. Es besteht aus übereinanderliegenden Layern.
2. Anwenden
Du bekommst Images aus dem Internet (Docker Hub):
docker pull nginx:latest (Lädt das Image herunter).
docker images (Zeigt alle Images auf deiner Festplatte).
docker run nginx (Macht aus dem toten Image einen lebenden Container).
docker rmi nginx (Löscht das Image, um Platz zu sparen).
Praxisroutine
In der Praxis lernst du Docker Image, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Layers & UnionFS
Ein Image ist keine einzelne Datei (wie .iso).
Es ist ein Stapel von Layern (Schichten).
- Layer 1: Ubuntu Base (100 MB).
- Layer 2: Python installiert (50 MB).
- Layer 3: Dein Code (1 MB).
Docker nutzt ein Union Filesystem (Overlay2).
Wenn du Layer 3 liest, schaut Docker durch alle Schichten hindurch.
Wenn du eine Datei in Layer 1 löschst?
Docker markiert sie im oberen Layer als "gelöscht" (Whiteout File
.wh.file), aber im unteren Layer ist sie physikalisch noch da. Das bläht Images auf, wenn man nicht aufpasst!
2. Manifest & Digest (SHA256)
Tags (:latest) sind gefährlich (Mutable).
Heute zeigt es auf v1, morgen auf v2.
Produktions-Systeme nutzen den Digest (Hash).
nginx@sha256:854c32....
Dieser Hash ist kryptografisch eindeutig.
Er wird aus dem Manifest berechnet (einer JSON-Datei, die die Liste aller Layer-Hashes enthält).
Wenn sich ein Bit in einem Layer ändert, ändert sich der Digest.
3. Scratch Images & Distroless
Profis nutzen keine vollen OS-Images (Ubuntu/Debian). Sie nutzen:
- Alpine: Winzig (5 MB), aber nutzt
muslstattglibc(Kompatibilitätsprobleme). - Distroless (Google): Enthält nur deine App und Laufzeitumgebung. Keine Shell (
/bin/sh), keinls, keinapt. Mega sicher, weil Angreifer nichts tun können, selbst wenn sie reinkommen. - Scratch: Leeres Image. Perfekt für Go/Rust Binaries (
FROM scratch). 0 Overhead.
4. Vertiefen
1. UnionFS (OverlayFS2) Architektur
Ein Docker Image ist keine monolithische 2-Gigabyte .iso Datei. Es ist eine abstrakte Illusion des Dateisystems.
Auf der SSD (Solid State Drive) deines Hosts (in /var/lib/docker/overlay2/) existiert ein gigantischer Ordner mit Hash-Namen. Jedes Kommando (RUN apt-get install curl) im Dockerfile erzeugt einen neuen Hash-Ordner (Layer), in dem nur die Differenz (das kleine Binary von curl) liegt.
Startest du den Container, nimmt das OverlayFS alle Dutzend RO-Layer (Read-Only) und stülpt sie (wie durchsichtige Folien auf einem Overheadprojektor) optisch übereinander in einen Mountpoint. Dem Container wird vorgegaukelt, ein einzelnes, flaches C:\ Laufwerk vor sich zu haben.
2. Copy-on-Write (CoW) und UpperDir
Wenn das Image zu 100% Read-Only ist, wie kann deine App beim Laufen dann eine Logdatei in /var/log schreiben?
Der laufende Container bekommt von Docker einen hauchdünnen, unsichtbaren R/W-Layer (UpperDir) ganz oben auf den Folienstapel gelegt.
Hier greift Copy-on-Write (CoW): Möchtest du im Container eine fette 100 MB Datei aus dem Basis-Image leicht verändern, blockiert Docker das. Docker kopiert die 100 MB Datei blitzschnell unsichtbar vom RO-Layer buchstäblich hoch in den UpperDir-Layer, und dort modifizierst du sie. Die Basisdatei bleibt für immer unberührt. Das Kopieren kostet kurz extrem viel I/O Performance, schützt aber das Original-Image.
3. OCI (Open Container Initiative) Format
Früher war ein Image das propritär verschlossene Eigentum von "Docker Inc.".
Heute unterliegen Images dem offenen Standard OCI.
Dort ist exakt definiert (JSON-Schema), wie das Image-Manifest aufgebaut ist.
Das ist der entscheidende Punkt, warum moderne Runtimes in Kubernetes wie containerd oder CRI-O (als Docker-Konkurrenz) ein normales "Docker Image" starten können, ohne dass du auch nur noch eine einzige Zeile Docker-Source-Code auf deinem Server installiert hast. Das Image ist universell portabel zwischen den IT-Konzernwelten geworden.
5. Prüfen
Was ist "Squashing"?
Das Zusammenfügen vieler kleiner Layer zu einem großen. Vorteil: Kleinere Gesamtgröße (gelöschte Dateien fliegen wirklich raus). Nachteil: Docker kann Layer nicht mehr wiederverwenden (schlechtes Caching beim Pull/Push).Warum keine Passwörter im Image?
Weil jeder, derdocker historytippt oder das Image entpackt (docker save), die Datei im Klartext sehen kann. Auch wenn du sie im nächsten Layer löschst! (Siehe Whiteout Files).Was ist OCI?
Open Container Initiative. Ein Standard, damit Docker-Images auch in anderen Runtimes (Podman, Kubernetes CRI-O) laufen. Ein "Docker Image" ist heute eigentlich ein "OCI Image".
Zusammenfassung
- Wenn du einen Container starten willst, brauchst du eine Vorlage. Diese Vorlage ist das Docker Image. Es ist wie ein Schnappschuss (Snapshot) von einem kompletten Computer. Darin ist: Das Betriebssystem (Linux Alpine, Ubuntu). Die Tools (Python, Node.js)....
- Du bekommst Images aus dem Internet (Docker Hub): docker pull nginx:latest (Lädt das Image herunter). docker images (Zeigt alle Images auf deiner Festplatte). docker run nginx (Macht aus dem toten Image einen lebenden Container). docker rmi nginx (Löscht das...
Optionale Praxisaufgabe
- Erkläre Docker Image in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Image relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Dateisystem S1
Überblick: Ein Dateisystem organisiert Dateien und Ordner auf einem Speichergerät. Es merkt sich Namen, Pfade, Größen, Rechte und wo die Daten physisch liegen. Ohne Dateisystem wäre eine Festplatte nur ein großer ungeordneter Datenbereich.
Einfach erklärt: Wenn du eine Datei speicherst, kopierst, loeschst oder suchst, arbeitest du mit dem Dateisystem. Betriebssysteme nutzen Rechte, Pfade und Metadaten, um Zugriff zu steuern. In Servern und Containern sind Volumes, Mounts und Backups besonders wichtig.
Tiefer verstanden: Dateisysteme verwalten Blöcke, Inodes oder vergleichbare Metadatenstrukturen. Sie können Journaling, Snapshots, Quotas, Verschluesselung und Rechte unterstützen. Beispiele sind ext4, NTFS, APFS, XFS und ZFS.
Praxisgrenze: Dateien lokal im Webprozess zu speichern ist in skalierenden Systemen oft riskant. Der nächste Request kann auf einem anderen Server landen. Auch geloeschte Dateien, defekte Rechte, volle Partitionen und fehlende Backups sind typische Betriebsprobleme.
Was speichert ein Dateisystem ausser dem Inhalt?
Metadaten wie Name, Pfad, Größe, Zeitstempel und Rechte.Warum sind Backups wichtig?
Weil Dateisysteme gegen Bedienfehler, Defekte oder Angriffe nicht automatisch schützen.Was ist eine typische Serverfalle?
Uploads nur lokal abzulegen, obwohl mehrere Server oder Container beteiligt sind.
SSD (Solid State Drive) S1
Überblick: Früher hatten Computer HDDs (Hard Disk Drives). Da drehte sich drinnen eine Magnetscheibe wie bei einem Plattenspieler. Das war laut, empfindlich und langsam. Eine SSD hat keine beweglichen Teile. Sie besteht aus Speicherchips (wie ein riesiger USB-Stick). Sie ist lautlos. Sie ist robust (kann runterfallen). Sie ist extrem schnell (Windows startet in 10 Sekunden statt 2 Minuten).
Einfach erklärt: Es gibt zwei Bauformen: 1. SATA-SSD: Sieht aus wie eine kleine Zigarrenschachtel (2,5 Zoll). Wird mit Kabel angeschlossen. (ca. 500 MB/s). 2. NVMe (M.2): Sieht aus wie ein Riegel Kaugummi. Wird direkt aufs Mainboard gesteckt. Extrem schnell (bis zu 7.000 MB/s).
Sollte ich meine Festplatte defragmentieren?
SSD auf keinen Fall! Defragmentieren sortiert Daten um (viele Schreibvorgänge). Das nutzt die SSD unnötig ab und bringt keinen Geschwindigkeitsvorteil (weil sie eh überall sofort zugreifen kann).Sind SSDs teurer als HDDs?
Ja, pro Gigabyte. Für Datengräber (Fotosammlung, Backups) lohnen sich noch alte HDDs (4 TB HDD = 80 €, 4 TB SSD = 250 €).Gehen Daten auf der SSD verloren ohne Strom?
Nein, es ist "nicht-volatiler" Speicher. Theoretisch können SSDs nach Jahren ohne Strom Daten verlieren (Bit Rot), aber für den Alltag ist das irrelevant.
Schritt 4 / 35
Image Layer
Warum Images aus Schichten bestehen.
S2
Schritt 4 / 35
Image Layer
Warum Images aus Schichten bestehen.
1. Verstehen
Stell dir ein Docker Image wie einen Stapel Pfannkuchen vor. Ganz unten ist der Teller (Kernel). Darauf kommt der erste Pfannkuchen (Ubuntu). Darauf der zweite (Python). Darauf der dritte (Deine App). Jeder Pfannkuchen ist ein Layer. Wenn du die App änderst, musst du nicht den ganzen Stapel wegwerfen. Du bäckst nur den obersten Pfannkuchen neu. Die anderen bleiben. Das macht Docker schnell. Der Stapel ist Read-Only (festgebacken). Wenn der Container läuft, kommt oben noch ein dünner "Schreib-Layer" (fettiges Papier) drauf, auf den du schreiben kannst.
Merksatz: Eine einzelne, unveränderliche Dateisystem-Schicht innerhalb eines Docker-Images, die Änderungen gegenüber der vorherigen Schicht speichert. Layer werden durch Union-Filesystems gestapelt.
2. Anwenden
Du siehst Layer beim docker pull:
Pulling ubuntu:
abc1234: Pulling fs layer (50 MB)
def5678: Pulling fs layer (10 MB)
Jeder Befehl im Dockerfile (RUN, COPY, ADD) erzeugt einen neuen Layer.
Wenn du apt-get update ausführst, entsteht ein Layer mit den neuen Index-Dateien.
Praxisroutine
In der Praxis lernst du Image Layer, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Copy-on-Write (CoW) Strategie
Wenn du eine Datei /etc/hosts in Layer 3 änderst, die in Layer 1 schon da war:
Docker kopiert die Datei von Layer 1 nach Layer 3 (Copy-Up) und speichert dort die Änderung.
Layer 1 bleibt unberührt (Immutable).
Der Container sieht nur die Version aus Layer 3.
Das Bläht Images auf: Wenn du eine 1GB Datei in Layer 2 hinzufügst und in Layer 3 löschst, ist das Image immer noch 1GB groß (weil Layer 2 noch da ist).
Die Datei ist nur "whiteout" (unsichtbar) im Layer 3.
2. Storage Drivers (Overlay2)
Wie funktioniert die Magie technisch?
Der Storage Driver (heute fast immer overlay2) regelt das.
Er nutzt Kernel-Features, um Verzeichnisse "übereinander" zu mounten (lowerdir, upperdir, merged).
Ältere Treiber (aufs, devicemapper) hatten Performance-Probleme oder inode-Limits.
Overlay2 ist extrem schnell (Page Cache Sharing), nutzt aber Inodes auf dem Host-Filesystem.
3. Layer Sharing & Deduplication
Wenn 100 Images auf ubuntu:20.04 basieren.
Der Ubuntu-Layer wird nur einmal auf der Festplatte gespeichert (/var/lib/docker/overlay2).
Alle 100 Container nutzen denselben Read-Only Layer.
Das spart Gigabytes an Platz.
Deshalb ist es schlau, in der Firma ein "Golden Base Image" zu standardisieren.
4. Vertiefen
Whiteouts und Opaque Dirs im UnionFS
Wie "löscht" man eine Datei in einem Read-Only-System? Wenn du im Layer 3 ein RUN rm -rf /app/secrets ausführst, obwohl /app/secrets im Layer 1 lag, löscht Docker physisch nichts.
Stattdessen erstellt Overlay2 eine spezielle Character-Device-Datei mit der Major/Minor-Nummer 0/0 namens .wh.secrets (Ein Whiteout). Das Dateisystem treibt bei jedem Read-Request eine Täuschung: Es ignoriert den alten Ordner, sobald es den .wh-Merkzettel über ihn findet.
Das perfide: Extrahiert ein Hacker dein fertiges Image lokal per docker save image > tar.tar und entpackt dessen Layer einzeln, sieht er die Ursprungsdatei in der Tiefe ungefiltert. Dies macht rm zum Verbergen von Credentials fatal.
Buildkit und Inline-Cache
Früher (Legacy Docker Builder) basierte das Layer-Caching rein auf der Linearen SHA-Historie.
Änderte man in Zeile 5 was, flogen alle Layer ab Zeile 6 in den Müll (Cache Invalidation).
Modernes Buildkit (der Standard seit Docker 20) bricht die lineare Kette auf. Es analysiert einen Directed Acyclic Graph (DAG) aller Befehle aus Multi-Stage-Builds und baut Layer parallel.
Mit dem Flag --cache-from kannst du einen existierenden Container aus der Registry als "Remote Cache" beim Bauen einbinden (oft in CI/CD). Eine unsaubere Layer-Struktur (kopieren von oft mutierenden package.json und src/ Code in einem Layer) bricht jedoch jeden Caching-Mechanismus, weshalb man Dependency-Schichten (installieren der Pip-Pakete) zwingend vor das eigentliche Code-Copying packen muss.
Squash und Flattening
Viele Devs wollten Layer-Overhead reduzieren und nutzten docker export gefolgt von docker import (oder das --squash arg beim Bauen).
Ein "Squash" drückt alle 20 Layer deines Images in einen einzigen gigantischen Layer zusammen.
Der gravierende Nachteil: Das Zerstört das Kern-Feature "Shared Layers".
Zehn gesquashte Images, die sich zuvor 500MB Ubuntu-Base geteilt hätten, blockieren auf der SSD dann brutal 5 GB (10x das Ubuntu Base-Image), weil der Layer-Hash sich als isolierter Blob grundlegend geändert hat. Squashen ist nur noch für winzige Distroless/Scratch-Binaries in hochgradigen Edge-Szenarien nützlich.
5. Prüfen
Wie viele Layer darf ich haben?
Früher max. 127 (Aufs Limit). Heute (Overlay2) fast unbegrenzt. Aber viele Layer machen den Start langsam (Overhead beim Mergen). Versuche unter 50 zu bleiben.Was ist
docker history?Zeigt alle Layer eines Images an, inklusive Größe und Befehl, der sie erstellt hat. Unverzichtbar zum Debuggen ("Warum ist mein Image 2GB groß? Ah, Layer 5 hattmpkopiert!").Kann ich Layer verschlüsseln?
Standardmäßig nein. Ein Layer ist ein Tar-Archiv. Wer Root hat, kann reinschauen. Für vertrauliche Daten (Secrets) nutze Docker Secrets oder Vault, niemals Layer!
Zusammenfassung
- Stell dir ein Docker Image wie einen Stapel Pfannkuchen vor. Ganz unten ist der Teller (Kernel). Darauf kommt der erste Pfannkuchen (Ubuntu). Darauf der zweite (Python). Darauf der dritte (Deine App). Jeder Pfannkuchen ist ein Layer. Wenn du die App änderst,...
- Du siehst Layer beim docker pull: Pulling ubuntu: abc1234: Pulling fs layer (50 MB) def5678: Pulling fs layer (10 MB) Jeder Befehl im Dockerfile (RUN, COPY, ADD) erzeugt einen neuen Layer. Wenn du apt-get update ausführst, entsteht ein Layer mit den neuen...
Optionale Praxisaufgabe
- Erkläre Image Layer in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Image Layer relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Dateisystem S1
Überblick: Ein Dateisystem organisiert Dateien und Ordner auf einem Speichergerät. Es merkt sich Namen, Pfade, Größen, Rechte und wo die Daten physisch liegen. Ohne Dateisystem wäre eine Festplatte nur ein großer ungeordneter Datenbereich.
Einfach erklärt: Wenn du eine Datei speicherst, kopierst, loeschst oder suchst, arbeitest du mit dem Dateisystem. Betriebssysteme nutzen Rechte, Pfade und Metadaten, um Zugriff zu steuern. In Servern und Containern sind Volumes, Mounts und Backups besonders wichtig.
Tiefer verstanden: Dateisysteme verwalten Blöcke, Inodes oder vergleichbare Metadatenstrukturen. Sie können Journaling, Snapshots, Quotas, Verschluesselung und Rechte unterstützen. Beispiele sind ext4, NTFS, APFS, XFS und ZFS.
Praxisgrenze: Dateien lokal im Webprozess zu speichern ist in skalierenden Systemen oft riskant. Der nächste Request kann auf einem anderen Server landen. Auch geloeschte Dateien, defekte Rechte, volle Partitionen und fehlende Backups sind typische Betriebsprobleme.
Was speichert ein Dateisystem ausser dem Inhalt?
Metadaten wie Name, Pfad, Größe, Zeitstempel und Rechte.Warum sind Backups wichtig?
Weil Dateisysteme gegen Bedienfehler, Defekte oder Angriffe nicht automatisch schützen.Was ist eine typische Serverfalle?
Uploads nur lokal abzulegen, obwohl mehrere Server oder Container beteiligt sind.
Schritt 5 / 35
Dockerfile
Eigene Images systematisch bauen.
S1
Schritt 5 / 35
Dockerfile
Eigene Images systematisch bauen.
1. Verstehen
Das Dockerfile (ohne Dateiendung!) ist das Kochrezept für dein Image. Docker liest es von oben nach unten. Jede Zeile im Rezept fügt eine Zutat hinzu. Typische Befehle:
FROM: Nimm einen Basis-Kuchenboden (Ubuntu).COPY: Wirf meine Erdbeeren (Code) drauf.RUN: Backe es bei 200 Grad (Kompilieren / Installieren).CMD: Serviere es mit Sahne (Startbefehl).
Merksatz: Eine Textdatei mit Instruktionen zur automatisierten Erstellung eines Docker-Images. Jeder Befehl erzeugt einen neuen Layer im Image.
:level0
Lernbruecke: Ein Dockerfile ist eine Bauanleitung. FROM sagt, womit du startest. COPY legt Dateien hinein. RUN bereitet etwas vor. CMD sagt, was beim Start laufen soll.
2. Anwenden
Ein klassisches Node.js Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Bauen mit docker build -t my-app ..
:level1
Praxisbeispiel: Du baust ein kleines Node.js-Image. Erst Basisimage, dann package-Dateien kopieren, Abhaengigkeiten installieren, App kopieren, Startbefehl setzen. Danach testest du das Image lokal.
Praxisroutine
In der Praxis lernst du Dockerfile, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Instruktions-Details
COPYvsADD:ADDkann URLs herunterladen und.tar.gzautomatisch entpacken. Das ist oft "magisch" und ungewollt. Best Practice: Nutze immerCOPY, außer du brauchst das Entpacken zwingend.ENVvsARG:ARG: Variable existiert nur beim Build. (docker build --build-arg VERSION=1.0).ENV: Variable existiert im laufenden Container.SHELL: Du kannst die Shell ändern (SHELL ["/bin/bash", "-c"]), praktisch für Windows Container (PowerShell) oder wenn du "Pipefail" aktivieren willst (set -o pipefail).
2. Layer-Optimierung
Schlecht:
RUN apt-get update
RUN apt-get install -y vim
RUN rm -rf /var/lib/apt/lists/*
Das sind 3 Layer. Im 2. Layer sind die apt-Listen da. Im 3. gelöscht. Das Image bleibt groß, weil Layer 2 noch existiert! Gut (Chaining):
RUN apt-get update && \
apt-get install -y vim && \
rm -rf /var/lib/apt/lists/*
Das ist ein Layer. Müll wird im selben Schritt gelöscht -> Image bleibt klein.
3. .dockerignore
Unterschätzt!
Alles, was nicht in .dockerignore steht, wird an den Daemon übertragen (Build Context).
Wenn du .git (500MB History) nicht ignorierst, dauert jeder Build 10 Sekunden länger ("Sending build context...").
Und: .env Dateien mit Passwörtern landen aus Versehen im Image!
Technisch entscheidet die Reihenfolge der Befehle über Cache und Build-Zeit. Haefig geänderte Dateien sollten später kopiert werden, damit Dependency-Layer wiederverwendet werden können.
4. Vertiefen
1. Build-Zeit vs. Laufzeit Executables
Oft findet man im Dockerfile Befehle, die konzeptionell falsch platziert sind.
Ein typischer Fehler: RUN npm start anstelle von CMD ["npm", "start"].
RUNwird exakt einmal zum Zeitpunkt des Image-Builds (z.B. in der GitHub Action) im isolierten temporären Container ausgeführt. Wenn die App 30 Sekunden läuft und crasht, crasht der Build.CMDundENTRYPOINTsind Befehle, die erst feuern, wenn ein User später auf dem Produktivserverdocker runtippt. Sie werden einfach als Metadaten-String in die JSON-Struktur des Images gehängt.
2. Exec-Form vs. Shell-Form
Befehle existieren historisch in zwei Syntax-Arten.
- Shell-Form:
CMD node app.js. Docker schaltet heimlich/bin/sh -cdazwischen. Problem: Die Shell krallt sich PID 1. Dasnode-Programm startet als Kind-Prozess. Drückst dudocker stop, kriegt die Shell das SIGTERM-Signal, gibt es aber nicht an Node weiter. Node stirbt grausam nach 10s Timeout-Kill. - Exec-Form:
CMD ["node", "app.js"]. Hier wird Node direkt als PID 1 im Container gespawned (ohne/bin/sh). Signale kommen sauber durch, Graceful Shutdown funktioniert, Datenbank-Connections werden sanft beendet.
3. Geheimnisse im Build (Secret Mounts)
Braucht dein Build-Prozess ein OAuth-Token (um ein privates NPM Package von GitHub Packages zu laden), tippen Anfänger oft: ENV TOKEN=xyz.
Das ist extrem falsch, da das API-Token dann für immer als Klartext im Environment des finalen Images brennt (jeder kann es mit docker inspect stehlen).
BuildKit hat dafür Secret Mounts eingeführt:
RUN --mount=type=secret,id=npm_token npm ci
Der Mount hängt eine kleine Read-Only Datei temporär an den RUN Befehl und blendet sie nach Ausführung mikroskopisch schnell wieder aus. Nichts landet in den Persistenzlayern des Abbildes.
5. Prüfen
Was macht
onbuild?Ein Trigger für Kind-Images. Wenn ichFROM my-onbuild-imagemache, werden Befehle ausgeführt, die im Eltern-Image definiert wurden. Nützlich für Boilerplates, aber intransparent ("Magic code execution"). Wird heute selten genutzt.Warum
EXPOSE?Es ist nur Dokumentation für den Menschen. Es öffnet keinen Port! (Das machtdocker run -p). Aber Tools (wie Traefik) lesen es, um zu wissen, wo der Service läuft.Heredocs?
Seit BuildKit kannst du mehrzeilige Skripte sauber schreiben:RUN <<EOF ... EOF. Das machtRUN-Layer viel lesbarer als&& \-Ketten.
Zusammenfassung
- Das Dockerfile (ohne Dateiendung!) ist das Kochrezept für dein Image. Docker liest es von oben nach unten. Jede Zeile im Rezept fügt eine Zutat hinzu. Typische Befehle: FROM: Nimm einen Basis-Kuchenboden (Ubuntu). COPY: Wirf meine Erdbeeren (Code) drauf. RUN:...
- Ein klassisches Node.js Dockerfile: dockerfile FROM node:18-alpine
- Technisch entscheidet die Reihenfolge der Befehle über Cache und Build-Zeit. Haefig geänderte Dateien sollten später kopiert werden, damit Dependency-Layer wiederverwendet werden können.
Optionale Praxisaufgabe
- Erkläre Dockerfile in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Dockerfile relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 6 / 35
Docker Build
Builds nachvollziehbar und cachebar ausführen.
S1
Schritt 6 / 35
Docker Build
Builds nachvollziehbar und cachebar ausführen.
1. Verstehen
Ein Docker Container kommt aus einem Image.
Aber woher kommt das Image?
Es wird gebaut ("gebacken").
Der Befehl docker build nimmt ein Rezept (Dockerfile) und Zutaten (deinen Code) und erstellt daraus ein Image.
Er geht das Rezept Zeile für Zeile durch:
- Nimm Linux.
- Installiere Python.
- Kopiere meinen Code rein. Am Ende hast du ein fertiges Paket, das überall läuft.
Merksatz: Der Befehl (docker build), der den Docker Daemon anweist, ein Image basierend auf den Instruktionen in einem Dockerfile und einem Build-Context (Dateien) zu erstellen.
2. Anwenden
Im Terminal, dort wo dein Dockerfile liegt:
docker build -t meine-app:v1 .
-t meine-app:v1: Tag (Name) des Images..: Der "Context" (der aktuelle Ordner). Docker schickt ALLE Dateien in diesem Ordner an den Daemon. (Achtung bei großen Dateien!).
Nutze eine .dockerignore Datei (wie .gitignore), um Ordner wie node_modules oder .git auszuschließen. Das macht den Build viel schneller.
Praxisroutine
In der Praxis lernst du Docker Build, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Build Cache & Layering
Jede Zeile im Dockerfile (RUN, COPY) erzeugt einen neuen Layer.
Docker cached diese Layer.
Wenn du Zeile 3 änderst, muss Docker Zeile 1 und 2 nicht neu bauen (Cache Hit).
Aber: Sobald eine Zeile sich ändert (Cache Miss), müssen alle folgenden Zeilen neu gebaut werden.
Optimierung: Kopiere package.json und mache npm install bevor du den Rest des Codes (COPY . .) kopierst.
So bleiben die Dependencies gecached, auch wenn du Code änderst.
2. BuildKit
Der neue Builder (Standard seit Docker 23).
Viel schneller, parallele Ausführung von Stages, besseres Caching.
Erlaubt Secrets Mounting: RUN --mount=type=secret,id=mykey ....
Damit landet dein API-Key sicher im Build, aber nicht im finalen Image-Layer.
3. Multi-Architecture Builds (Buildx)
Du arbeitest auf Mac (ARM64), der Server ist Linux (AMD64).
Ein normales docker build baut für deine CPU. Es läuft nicht auf dem Server ("Exec format error").
Mit docker buildx kannst du Cross-Platform bauen (QEMU Emulation).
docker buildx build --platform linux/amd64,linux/arm64 ....
Erstellt ein "Manifest List" Image, das auf beiden Architekturen läuft.
4. Vertiefen
1. Multi-Stage Builds für Sicherheit und Größe
Anfänger bauen Go-Apps so: FROM golang:1.20, kopieren den Source, RUN go build, fertig.
Resultat: Das Image ist 900 Megabyte groß. Es enthält den gesamten Go-Compiler, Debugger, GCC für CGO und all deine Source-Code .go Dateien im Prod-Image. Ein absolutes Desaster.
Profis nutzen Multi-Stage-Builds:
FROM golang:1.20 as builder
COPY . /app
RUN go build -o /server /app
FROM scratch
COPY --from=builder /server /server
ENTRYPOINT ["/server"]
Das finale Image ist nun gigantische 6 MB groß (nur das Binary). Keine Linux-Tools (kein bash, kein ls), kein Root-Zugriff, keine Angriffsfläche (CVEs).
2. Der Build Context und .dockerignore
Wenn du docker build . tippst, schiebt der Docker-CLI-Client zunächst den gesamten Inhalt des Orderns (Context) als .tar-Archiv zum Docker Daemon (Backend), bevor Zeile 1 der Dockerfile überhaupt starten darf.
Liegt dort der node_modules Ordner (500 MB) oder ein Backup .sql File rum, blockiert das Build zig Sekunden lang (I/O und CPU), nur um Daten zum Daemon zu pumpen, die danach nie vom Image gebraucht werden.
Die .dockerignore ist zwingende Pflicht. Sie verhindert hart, dass Passwörter, Git-Historys (.git) oder lokale Müll-Ordner überhaupt die Reise zum Daemon über das Socket antreten.
3. LLB (Low-Level Builder) im BuildKit
Historisch bearbeitete der Legacy-Docker-Builder Zeile für Zeile imperativ (streng nacheinander).
Der moderne BuildKit Engine kompiliert das Dockerfile im ersten Schritt zunächst in einen sogenannten LLB (Low-Level Builder) AST-Graphen.
Das ist ein optimierter Directed Acyclic Graph (Abhängigkeitsbaum, wie Make).
Hat ein Dockerfile zwei Multi-Stages (Frontend baut Node, Backend baut Python), erkennt der LLB-Graph: "Stage 1 und 2 brauchen einander nicht." und instruiert den Concurrency-Scheduler, beide Instanzen extrem aggressiv und in der exakt gleichen Millisekunde parallel auf mehreren CPU-Kernen zu rendern, was die Build-Zeiten signifikant drückt.
5. Prüfen
Warum ist der Build Context (".") wichtig?
Docker ist Client-Server. Der CLI-Client zipped den ganzen Ordner und schickt ihn an den Daemon. Wenn du eine 5GB ISO im Ordner hast, dauert der Start des Builds ewig, auch wenn du die ISO im Dockerfile gar nicht nutzt. ->.dockerignore!Was sind "Dangling Images" (
<none>)?Wenn du ein Image neu baust (v1), verliert die alte Version den Namen. Sie bleibt als Datenmüll auf der Platte. Aufräumen mitdocker image prune.Kann/Sollte man im Build Tests laufen lassen?
Ja! In einem Multi-Stage Build kann eine StageRUN npm testausführen. Wenn der Test failt, bricht der Build ab. So entsteht gar kein kaputtes Image.
Zusammenfassung
- Ein Docker Container kommt aus einem Image. Aber woher kommt das Image? Es wird gebaut ("gebacken"). Der Befehl docker build nimmt ein Rezept (Dockerfile) und Zutaten (deinen Code) und erstellt daraus ein Image. Er geht das Rezept Zeile für Zeile durch: 1....
- Im Terminal, dort wo dein Dockerfile liegt: docker build -t meine-app:v1 . -t meine-app:v1: Tag (Name) des Images. .: Der "Context" (der aktuelle Ordner). Docker schickt ALLE Dateien in diesem Ordner an den Daemon. (Achtung bei großen Dateien!).
Optionale Praxisaufgabe
- Erkläre Docker Build in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Build relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 7 / 35
Docker Run
Container starten, Ports setzen und Umgebungen übergeben.
S1
Schritt 7 / 35
Docker Run
Container starten, Ports setzen und Umgebungen übergeben.
1. Verstehen
Der wichtigste Befehl in Docker.
Er ist der Urknall. Er erschafft Universen.
docker run nimmt ein totes Image (Bauplan) und erweckt es zum Leben -> ein Container (Prozess).
Er macht im Hintergrund viel:
- Prüfen: "Hab ich das Image?" (Nein ->
pull). - Erstellen: Container-Filesystem anlegen (
create). - Starten: Prozess ausführen (
start). - Verbinden: Logs anzeigen (
attach). Das alles in einem Befehl.
Merksatz: Der CLI-Befehl zum Erstellen und Starten eines neuen Containers aus einem Image. Er kombiniert pull, create und start.
2. Anwenden
docker run -d -p 80:80 --name mein-web nginx
-d(Detached): Lauf im Hintergrund (sonst blockiert dein Terminal).-p 80:80(Port): Öffne Port 80 am Laptop und leite zu Port 80 im Container.--name: Gib ihm einen Namen (sonst heißt ermodest_einstein).nginx: Das Image.
Wegwerf-Modus für Tests:
docker run --rm -it ubuntu bash
--rm: Lösche den Container sofort, wenn er fertig ist (kein Müll).-it: Interaktiv (ich will tippen).bash: Der Befehl, den ich starten will.
3. Technisch einordnen
1. Entrypoint vs. CMD
Der ewige Klassiker.
- ENTRYPOINT: Die Haupt-Anwendung ("Das Binary"). Wird nicht überschrieben.
- CMD: Die Argumente ("Die Params"). Wird leicht überschrieben.
Image:
ENTRYPOINT ["echo"],CMD ["Hello"].docker run img->echo Hello.docker run img World->echo World. Wenn durunbenutzt, überschreibst du immer nurCMD, es sei denn du nutzt--entrypoint.
2. Runtime Constraints (--ulimit)
Manchmal crasht Java oder Elasticsearch im Container: "Too many open files".
Das liegt daran, dass der Container die Limits vom Host erbt (oft 1024).
Mit docker run --ulimit nofile=65535:65535 ... kannst du Kernel-Limits pro Container hochsetzen, ohne den Host global zu ändern.
3. PID 1 & Signal Forwarding
docker run startet deinen Prozess als PID 1.
PID 1 ist speziell (in Linux ignorieren sie Standard-Kill-Signale).
Wenn du docker run ... /bin/sh -c 'java app.jar' machst, ist die Shell PID 1.
Wenn du docker stop machst, kriegt die Shell das Signal. Sie leitet es aber nicht an Java weiter. Java wird nach 10s gnadenlos gekillt.
Nutze exec Form im Dockerfile oder --init im Run-Befehl.
4. Vertiefen
1. Cgroups und Namespaces Initiierung
Was macht docker run tief im Linux-Kernel wirklich?
Es ruft insgeheim Tools wie runc (Container Runtime) auf.
Kommando: "Kernel! Erstelle mir einen isolierten Namespace (PID)". Das gaukelt dem laufenden Container-Prozess vor, er wäre PID 1, obwohl er auf dem echten Server in Wahrheit Prozess 54890 ist.
Weiter: "Kernel! Sperre ihn in eine Cgroup". Docker run (-m 512m --cpus=1) konfiguriert den Linux-Sheduler rigoros so, dass dieser Container hart abstürzt (OOM Killed), bevor er jemals 513 MB Server-RAM berühren darf. docker run ist in Wahrheit nur ein glorifizierter Wrapper um sehr tiefgreifende Linux-Kernel-Kapselungen.
2. Das Seccomp Profile
Warum kann ein Hacker, der eine Lücke in deiner Node.js App ausnutzt und "in den Container" eindringt, den darunterliegenden Server nicht übernehmen?
Weil docker run standardmäßig ein Seccomp (Secure Computing Mode) Profil mitlädt.
Von über 300 verfügbaren Linux-Systemaufrufen (Syscalls), die ein C-Programm am Kernel machen kann (z.B. Hardware Mounten, Datum ändern, Kernel-Module nachladen), blockiert Docker hart die gefährlichsten 44 Syscalls. Selbst wenn der Container-Angreifer Code schreibt, der die System-Uhrzeit deines nackten Servers manipulieren will, verwirft der Linux Kernel den Command mit "Permission Denied", weil die Container-Laufzeitumgebung in einer syscall-verkrüppelten Sandbox festhängt.
3. TTY Allocation (-it Parameter)
Hängst du in Linux ein Binary an das Terminal, will es PTY (Pseudo Terminal) Features haben (bunte Farben, Strg+C Escape-Sequenzen verstehen).
Betreibst du docker run ubuntu bash (ohne -it), startet Bash im Container, "merkt", dass gar keine Tastatur oder Monitor angeschlossen ist (Background), schaltet im Bruchteil einer Sekunde wieder ab und "exits".
Der -t (Allocate pseudo-TTY) Flag zwingt Docker, einen unsichtbaren Rohrpost-Treiber (TTY) in den Container zu injizieren, und -i (Interactive) zwingt den Docker-Client auf dem Host, deinen Tastatur-Input fortlaufend ungepuffert als Stream durch dieses Rohr in den Container zu pumpen.
5. Prüfen
Was ist
-v?Volumes.-v /host/pfad:/container/pfad. Damit können Daten überleben oder Config-Dateien injiziert werden.Unterschied
runvsexec?runerstellt einen neuen Container.execgeht in einen bestehenden, laufenden Container rein. Nutzerunzum Starten der App,execzum Debuggen (/bin/bash).Warum
-it?-i(Interactive): Halte STDIN offen (Tastatur).-t(TTY): Simuliere ein Terminal (bunte Farben, Strg+C funktioniert). Ohne-tdenken viele Programme, sie laufen in einem Skript und schalten Output-Buffering an (keine Live-Logs).
Zusammenfassung
- Der wichtigste Befehl in Docker. Er ist der Urknall. Er erschafft Universen. docker run nimmt ein totes Image (Bauplan) und erweckt es zum Leben - ein Container (Prozess). Er macht im Hintergrund viel: 1. Prüfen: "Hab ich das Image?" (Nein - pull). 2....
- docker run -d -p 80:80 --name mein-web nginx -d (Detached): Lauf im Hintergrund (sonst blockiert dein Terminal). -p 80:80 (Port): Öffne Port 80 am Laptop und leite zu Port 80 im Container. --name: Gib ihm einen Namen (sonst heißt er modesteinstein). nginx:...
Optionale Praxisaufgabe
- Erkläre Docker Run in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Run relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 8 / 35
Docker Client
Wie CLI und Docker Engine zusammenarbeiten.
S1
Schritt 8 / 35
Docker Client
Wie CLI und Docker Engine zusammenarbeiten.
1. Verstehen
Docker ist zweiteilig.
Wenn du im Terminal tippst: docker run hello-world, dann sprichst du mit dem Docker Client.
Aber der Client tut nichts. Er baut keine Images, er startet keine Container.
Er ist nur die Fernbedienung.
Er schickt deinen Befehl an den Docker Daemon (dockerd), der (meistens) auf dem gleichen Computer im Hintergrund läuft.
Der Daemon macht die Arbeit und schickt das Ergebnis an den Client zurück.
Du kannst den Client auch auf deinem Laptop haben und damit den Daemon auf einem riesigen Cloud-Server steuern.
Merksatz: Die Befehlszeilenschnittstelle (CLI), die API-Anfragen an den Docker Daemon sendet, um Container zu steuern. Die primäre Interaktionsmethode für Benutzer (docker Kommando).
2. Anwenden
Das wichtigste Prinzip: Context.
Standardmäßig spricht der Client mit unix:///var/run/docker.sock (lokaler Daemon).
Du kannst das ändern:
docker context create remote-server --docker "host=ssh://user@remote-ip"
docker context use remote-server
Jetzt passiert jedes docker ps auf dem entfernten Server!
Extreme Vorsicht: Ein docker system prune löscht nicht deinen Laptop, sondern den Production-Server.
Praxisroutine
In der Praxis lernst du Docker Client, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. The Docker Socket
Der Client kommuniziert über eine REST API.
Lokal läuft das über einen Unix Socket /var/run/docker.sock.
Wer Schreibrechte auf diesen Socket hat, ist faktisch Root.
Warum?
docker run -v /:/host alpine rm -rf /host
Das löscht das Host-System.
Deshalb darf der User docker (Gruppe) alles.
In Kubernetes wird oft der Socket in den Container gemountet ("Docker-in-Docker" light).
Gefährlich! Ein Container kann dann den Host übernehmen.
2. API Version Negotiation
Client und Server haben Versionen.
Client v24 redet mit Server v20.
Der Client sendet im Header Warning: API version mismatch.
Er versucht, sich "dumm zu stellen" (Downgrade), damit er mit dem alten Server reden kann.
Manchmal fehlen dann Features (docker buildx geht nicht mit altem Daemon).
3. Alternativen (Podman)
Podman hat keinen Daemon.
Der podman Befehl ist Client und Server in einem (fork/exec).
Das Sicherheitsmodell ist anders (Rootless by default).
Aber für den User fühlt es sich gleich an (alias docker=podman).
4. Vertiefen
1. Die Architektur der Control-Plane
Der docker CLI Binarity ist faktisch ein reines REST/gRPC-Frontend (mittlerweile oft in Go geschrieben, das externe Plugins wie buildx in ~/.docker/cli-plugins/ nachlädt). Er enthält absolut null Containerisierung-Logik (cgroups, namespaces). Er parst nur User-Flags (wie --rm) und transliert sie in ein HTTP POST JSON auf den Endpoint /containers/create.
Es gibt in Architekturen Fälle, wo der Client auf dem CI-Runner (GitHub Actions) sitzt und der Daemon auf EC2 in AWS (oder minikube) rennt. Sie trennen die Ausführungsschicht von der Bedienschicht.
2. Socket-Mounts: Das Rooting-Dilemma
Oft muss ein CI/CD Tool wie Jenkins. Dessen Container muss neue Images für das Hauptprojekt bauen.
Der Admin reicht den Unix Socket per Volume an Jenkins durch: -v /var/run/docker.sock:/var/run/docker.sock. (Docker-Out-of-Docker Ansatz).
Das ist extrem gefährlich.
Der Jenkins Container redet als Docker-Client mit dem Docker-Daemon des nackten physischen Host-Systems.
Jenkins kann nun tippen: docker run -v /:/host_root alpine rm -rf /host_root. Er löscht das gesamte Betriebssystem aus, oder startet privilegierte (Root) Container auf dem Host, die SSH-Keys auslesen. Jeder Socket-Mount ist ein absoluter Privilege Escalation Vektor (Instant-System-Root-Zugriff).
3. Alternative Clients & CRI API
Seit Docker den Engine modifiziert hat, können sogar unzählige Dritte-Clients denselben Socket füttern.
In Kubernetes ist Docker (dockershim) mittlerweile als Laufzeit tot. Kubernetes nutzt nicht den Docker Client und nicht dockerd. Kubernetes nutzt das CRI (Container Runtime Interface) und spricht direkt mit containerd (dem Unterbau von Docker).
Ein anderer Client als Alternative zu Docker CLI ist nerdctl. Er verhält sich vom Kommando exakt wie Docker (nerdctl run), baut aber ohne den riesigen Daemon Overhead nativ in containerd, was Ressourceneffizienter im Cluster (für ContainerD-basierte Nodes) arbeitet und Funktionen liefert, die das "fette" Docker-Ökosystem nie umsetzen wollte (z.b. natives eStargz Lazy Image Pulling).
5. Prüfen
Was ist
DOCKER_HOST?Eine Umgebungsvariable. Wenn duexport DOCKER_HOST=tcp://192.168.1.5:2375setzt, redet dein Client sofort mit diesem Server. (Achtung: Port 2375 ist unverschlüsselt! Nutze 2376 mit TLS).Warum cli-plugins?
Der moderne Docker Client lädt Plugins wiecomposeundbuildxdynamisch. Früher wardocker-composeein Python-Skript. Jetzt ist esdocker compose(Go-Plugin).Kann ich Docker ohne Client nutzen?
Ja, direkt percurlan die API. Oder mit Libraries (Python Docker SDK). Aber für Menschen ist CLI bequemer.
Zusammenfassung
- Docker ist zweiteilig. Wenn du im Terminal tippst: docker run hello-world, dann sprichst du mit dem Docker Client. Aber der Client tut nichts. Er baut keine Images, er startet keine Container. Er ist nur die Fernbedienung. Er schickt deinen Befehl an den...
- Das wichtigste Prinzip: Context. Standardmäßig spricht der Client mit unix:///var/run/docker.sock (lokaler Daemon). Du kannst das ändern: docker context create remote-server --docker "host=ssh://user@remote-ip" docker context use remote-server Jetzt passiert...
Optionale Praxisaufgabe
- Erkläre Docker Client in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Client relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
API S1
Überblick: Eine API (Application Programming Interface) ist der universelle Vermittler zwischen verschiedenen Software-Systemen. Man kann es sich – ganz klassisch – wie einen Kellner in einem Restaurant vorstellen, aber schauen wir uns das Detail genauer an:
Einfach erklärt: Wenn du Tools wie n8n, Zapier oder Make nutzt, bist du im Grunde ein "API-Manager". Du verknüpfst verschiedene Dienste miteinander.
Tiefer verstanden: Hier gehen wir tief in die Mechanik. Eine moderne Web-API (meist RESTful) folgt strengen Regeln des HTTP-Protokolls. Wenn du als Developer oder Automation Engineer arbeitest, musst du verstehen, was "unter der Haube" passiert.
Warum kann ich nicht einfach direkt auf die Datenbank von z. B. Google zugreifen, sondern muss die API nutzen?
Sicherheit & Kontrolle. Die API (Kellner) prüft, ob du das darfst. Niemand lässt Fremde direkt in die Küche (Datenbank). Zudem abstrahiert die API die technische Komplexität der Datenbank.Was ist der Unterschied zwischen einem Request und einer Response?
Request = Die Anfrage vom Client an den Server (inkl. Methode, Header, Body). Response = Die Antwort vom Server (inkl. Status Code und Daten).Was passiert, wenn du das Rate Limit einer API überschreitest?
Der Server blockiert die Anfrage mit dem Status Code429 Too Many Requests. Du musst warten, bis dein "Budget" wieder aufgefüllt ist.
Schritt 9 / 35
Docker Daemon (dockerd)
Der Hintergrunddienst, der Container verwaltet.
S2
Schritt 9 / 35
Docker Daemon (dockerd)
Der Hintergrunddienst, der Container verwaltet.
1. Verstehen
Wenn du Docker installierst, installierst du eigentlich einen Server-Dienst.
Dieser Dienst heißt Docker Daemon (dockerd).
Er läuft im Hintergrund (Systemd Service) und schläft nie.
Er ist der Boss.
Er verwaltet alle Container, Images, Netzwerke und Volumes.
Wenn du docker run tippst, sendest du nur einen Wunsch an den Daemon.
Der Daemon redet dann mit dem Linux-Kernel, um den Wunsch zu erfüllen.
Wenn der Daemon abstürzt, sterben (oft) alle Container.
Merksatz: Der persistente Hintergrundprozess, der Docker-Objekte verwaltet und Container-Runtimes anweist, Container zu erstellen und auszuführen.
2. Anwenden
Du siehst ihn selten, aber konfigurierst ihn in /etc/docker/daemon.json.
Wichtige Settings:
"log-driver": "json-file": Wie Logs gespeichert werden (und Log-Rotation!)."insecure-registries": [...]: Erlaube HTTP (statt HTTPS) für private Regstries."data-root": "/mnt/große-platte/docker": Verschiebe Images von/var/lib/dockerauf eine größere Partition. Nach Änderung:systemctl reload docker.
Praxisroutine
In der Praxis lernst du Docker Daemon (dockerd), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Monolith vs. Modular (Refactoring)
Früher war dockerd ein riesiger Monolith.
Heute ist er modular zerlegt (das Moby Projekt):
- dockerd: Die API-Schicht.
- containerd: Standardisierte Runtime (CNCF). Verwaltet den Lifecycle -> überlebt
dockerdRestart! - runc: Das Low-Level Tool, das wirklich mit dem Kernel (cgroups, namespaces) spricht.
- shim: Ein winziger Prozess, der am Container klebt, damit
dockerdnicht der Parent ist. Ziel: Live Restore. Der Daemon kann geupdated werden, ohne dass die Container stoppen (Feature:live-restore: true).
2. Root Privilegien
Der Daemon läuft als Root. Das ist das größte Sicherheitsrisiko von Docker. Ein Bug im Daemon = Root-Zugriff auf dem Server. Gegenmaßnahmen:
- Rootless Mode: Docker im User-Space laufen lassen (viele Einschränkungen bei Networking).
- User Namespaces (
userns-remap): Mappe Root im Container auf User 1000 am Host.
3. OOM Score Adjust
Der Daemon ist kritisch.
Linux hat einen Mechanismus (OOM Score), um Prozesse zu töten, wenn RAM voll ist.
Dockerd setzt seinen eigenen Score automatisch auf -500 (sehr sicher).
Er sagt dem Kernel: "Töte lieber Chrome oder die Datenbank, aber töte nicht MICH (den Manager)."
4. Vertiefen
Die Docker API und /var/run/docker.sock
Der Daemon hört standardmäßig auf einen lokalen "UNIX Domain Socket" (/var/run/docker.sock), nicht auf einen TCP-Port.
Wenn du docker ps tippst, macht das CLI nur einen HTTP GET-Request an http://unix:/var/run/docker.sock/v1.41/containers/json.
Das Geniale, aber Gefährliche: Du kannst diesen Socket per Bind-Mount in Container hineinreichen (-v /var/run/docker.sock:/var/run/docker.sock).
Dann kann ein Container den Daemon auf dem Host steuern, also weitere Container starten (Prinzip von CI-Runnern oder Portainer). Wenn der Container jedoch gehackt wird, hat der Angreifer Vollzugriff auf den Host. Wer den Socket hat, ist effektiv root.
TCP Bindings & TLS Mutual Auth
Willst du den Daemon remote per TCP (Port 2375 // 2376) steuern (z. B. aus einer fernen CI/CD Pipeline), darfst du niemals den Socket nackt ins Internet hängen. Crawler wie Shodan finden offene Docker-Daemons innerhalb von Minuten, und Krypto-Miner fliegen auf deinen Maschinen ein.
Die Lösung ist mTLS (Mutual TLS Authentication).
Du generierst private Keys für den Daemon (Server) und für dich (Client). Der Daemon signiert Zertifikate, und nur Requests, die von einem kryptografisch zertifizierten Docker-Client kommen, dürfen eine Verbindung aufbauen. Selbst eine korrekte Authentifizierungsmethode verhindert allerdings keinen Root-Ausbruch, wenn der Angreifer den korrekten Key stiehlt.
Storage Drivers & OverlayFS-2
Dockerd verwaltet den Festplattenplatz nicht plump per Dateikopien.
Für das Image-Layering nutzt der Daemon Storage Drivers, heute quasi universell overlay2.
OverlayFS nutzt Features des Linux-Kernels, wodurch Dateien nicht dubliziert werden. 10 Container, die alle ubuntu als Basis haben, verbrauchen zusammen nur 70MB (für das Base-Image), da Layers Copy-On-Write sind. Der Daemon orchestriert die Layer-Idempotenz.
Vorsicht bei ext4 vs. xfs: Ohne d_type (Directory Entry Type)-Support im Dateisystem verschluckt sich der Daemon extrem beim Kopieren und baut kaputte Layer.
5. Prüfen
Was ist
containerd?Eine High-Level Runtime, die von Docker ausgekoppelt wurde. Kubernetes nutzt heute oftcontainerddirekt (ohne Docker Daemon dazwischen), um Ressourcen zu sparen. Docker ist "nur noch" UI für containerd.Kann ich den Daemon überwachen?
Ja. In derdaemon.jsonkannst du"metrics-addr": "0.0.0.0:9323"setzen. Das öffnet einen Prometheus-Endpunkt mit internen Metriken (Anzahl Container, Go-Routines, Failures).Warum stirbt alles bei
kill -9 dockerd?Weil SIGKILL dem Daemon keine Chance gibt, die Child-Prozesse ansystemdzu übergeben. Die Pipe bricht,shimsverlieren die Verbindung -> Chaos. Nutze immersystemctl stop docker.
Zusammenfassung
- Wenn du Docker installierst, installierst du eigentlich einen Server-Dienst. Dieser Dienst heißt Docker Daemon (dockerd). Er läuft im Hintergrund (Systemd Service) und schläft nie. Er ist der Boss. Er verwaltet alle Container, Images, Netzwerke und Volumes....
- Du siehst ihn selten, aber konfigurierst ihn in /etc/docker/daemon.json. Wichtige Settings: "log-driver": "json-file": Wie Logs gespeichert werden (und Log-Rotation!). "insecure-registries": [...]: Erlaube HTTP (statt HTTPS) für private Regstries....
Optionale Praxisaufgabe
- Erkläre Docker Daemon (dockerd) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Daemon (dockerd) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Server S1
Überblick: Ein Server ist ein Diener (engl. "to serve" = dienen). Es ist ein Computer, der darauf wartet, dass andere (Clients) etwas von ihm wollen. Webserver: "Zeig mir diese Webseite!" Mailserver: "Nimm meine E-Mail an!" Fileserver: "Speichere diese Datei!"
Einfach erklärt: Im Büro steht oft ein "Serverraum". Da steht der Firmenserver. Darauf liegen alle Word-Dateien, damit alle Kollegen gleichzeitig darauf zugreifen können. Wenn der Server abstürzt, kann keiner arbeiten ("Das Netz ist weg").
Tiefer verstanden: Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Braucht ein Server einen Bildschirm?
Nein. Man verwaltet ihn "headless" (kopflos) über das Netzwerk (Fernwartung mit SSH oder Remote Desktop). Ein Monitor steht nur für Notfälle im Serverraum.Was ist "Server Down"?
Der Server reagiert nicht. Gründe: Stromausfall, Internet weg, abgestürzt oder überlastet (DDoS).Warum sind Server so laut?
Wegen den Lüftern. Sie erzeugen enorme Hitze und müssen extrem gekühlt werden. Die kleinen Lüfter drehen mit 15.000 Umdrehungen pro Minute und klingen wie ein Triebwerk.
Linux-Kernel S3
Überblick: Der Linux-Kernel ist der Kern eines Linux-Systems. Er verwaltet Hardware, Prozesse, Speicher, Dateisysteme und Netzwerkzugriffe. Anwendungen sprechen nicht direkt mit der Hardware, sondern über Kernel-Schnittstellen.
Einfach erklärt: Admins sehen den Kernel indirekt bei Treibern, Netzwerkproblemen, Container-Isolation, Dateisystemen und Performance. Container nutzen Kernel-Funktionen wie Namespaces und Cgroups. Moderne Netzwerk- und Security-Tools verwenden eBPF oder XDP.
Tiefer verstanden: Der Kernel stellt System Calls bereit, plant Prozesse, verwaltet virtuellen Speicher, kontrolliert Rechte und implementiert Netzwerk-Stacks. Module können Funktionen nachladen. Kernel-Version, Distribution-Patches und Konfiguration beeinflussen Stabilitaet und Feature-Support.
Praxisgrenze: Kernel-nahe Fehler können das ganze System betreffen. Unsichere Module, falsche Treiber oder riskante eBPF-Programme sind nicht wie normale App-Fehler isoliert. Kernel-Updates brauchen deshalb Rollback-Plan, Tests und Wartungsfenster.
Warum brauchen Container den Linux-Kernel?
Container teilen sich den Kernel des Hosts und nutzen Kernel-Funktionen wie Namespaces und Cgroups für Isolation.Was ist ein System Call?
Eine kontrollierte Schnittstelle, über die Programme Kernel-Funktionen anfordern.Was ist eine typische Falle?
Kernel-nahe Änderungen wie normale App-Updates zu behandeln, obwohl ein Fehler den ganzen Host betreffen kann.
Schritt 10 / 35
Docker Registry
Images speichern, versionieren und verteilen.
S1
Schritt 10 / 35
Docker Registry
Images speichern, versionieren und verteilen.
1. Verstehen
Du hast ein Image gebaut (docker build). Es liegt auf deinem Laptop.
Dein Kollege will es auch haben.
Schickst du ihm einen USB-Stick? Nein.
Du lädst es in eine Registry hoch (docker push).
Er lädt es herunter (docker pull).
Die Registry ist wie ein App Store oder Google Drive für Docker Images.
Die bekannteste ist Docker Hub (öffentlich).
Firmen nutzen private Registries (Google Artifact Registry, AWS ECR, Harbor), damit der Quellcode geheim bleibt.
Merksatz: Ein zentraler Serverdienst zum Speichern und Verteilen von Docker Images. Es verwaltet Repositories und Tags und regelt den Zugriff (Authentifizierung).
2. Anwenden
- Login:
docker login registry.example.com(Benutzer/Passwort). - Taggen: Du musst dem Image sagen, wohin es soll.
docker tag mein-app registry.example.com/team/mein-app:v1Der Servername ist Teil des Imagenamens! - Push:
docker push registry.example.com/team/mein-app:v1. - Pull: Auf dem server:
docker pull ....
Praxisroutine
In der Praxis lernst du Docker Registry, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Registry API V2 & Content Addressable Storage
Die Registry speichert Blobs (Layer).
Jeder Blob hat einen Hash (SHA256).
Wenn du Image A (Ubuntu + App) und Image B (Ubuntu + DB) pushst.
Die Registry merkt: "Hey, der Ubuntu-Layer abc123 ist schon da."
Sie speichert ihn nur einmal (Deduplication).
Das spart Petabytes an Speicher bei großen Firmen.
Der Client fragt beim Push erst "Hast du Hash X schon?". Registry: "Ja". Client: "Okay, überspringe Upload."
2. Garbage Collection (GC)
Wenn du ein Tag (:latest) überschreibst (Updates), verweist das alte Manifest auf nichts mehr.
Aber die Layer (Blobs) bleiben auf der Festplatte.
Registry-Admins müssen regelmäßig GC laufen lassen.
Der Prozess stoppt oft die Registry (Read-Only Mode), scannt alle Manifeste und löscht verwaiste Blobs ("Dangling Layers").
3. Proxy & Mirroring
In großen Firmen (10.000 Entwickler) ist der Traffic zum Docker Hub teuer/langsam. Man stellt eine Pull-Through Cache Registry ins lokale LAN. Client -> "Gib mir Nginx". lokale Registry -> "Hab ich nicht. Lade von Docker Hub... Speichere... Hier hast du es." Nächster Client -> "Gib mir Nginx". lokale Registry -> "Hier (aus Cache)." Spart Bandbreite und schützt vor Docker Hub Outages.
4. Vertiefen
1. HTTP API V2 und Push-Mechanismus (Content Addressable)
Wenn docker push feuert, lädt es nicht stumm ein 2GB Blob hoch. Der Docker-Client redet mit der REST API (/v2/<name>/blobs/uploads/).
Der Client iteriert durch alle 10 Layer deines Images. Er berechnet lokal den SHA256 Hash des Layers. Er funkt zur Registry: "Hast du Hash a3f5... schon?". Hat die Registry den Layer von einem ganz anderen Entwickler-Image (z.B. Node.js Alpine base) bereits in ihrer globalen Datenbank, antwortet sie: "Ja, hab ich! Skip das!".
Dieses Content Addressable Storage Design ist der Grund, warum ein Push von 500 MB manchmal nur Millisekunden dauert, weil physisch kein Byte über Netz ging. Alles ist dedupliziert.
2. Manifest Lists (Fat Manifests) für Multi-Arch
Die Welt ist gespalten in AMD64 (Intel Server) und ARM64 (Apple M2, AWS Graviton).
Wenn du docker pull nginx:latest machst, wie lädt das System das richtige Binary für deine CPU?
Das Geheimnis ist die Manifest-List (Fat Manifest).
Hinter dem Tag :latest liegt auf der Registry kein direktes Image. Dort liegt ein intelligenter Router (JSON).
"manifests": [
{ "digest": "sha256:123...", "platform": { "architecture": "amd64" } },
{ "digest": "sha256:456...", "platform": { "architecture": "arm64" } }
]
Dein lokaler Docker Daemon liest das JSON, checkt deine Hardware, und lädt stumm den passenden Digest herunter. Es ist eine architektonische Meisterleistung für unsichtbare Cross-Platform Kompatibilität.
3. Garbage Collection (Registry Bloat)
In CI/CD Pipelines pushen Firmen am Tag 100 neue Versionen.
Du überschreibst ständig den Tag :latest. Die Registry trennt den Tag vom alten Image v1 und heftet :latest an v2.
Das Image v1 ist nun ein Dangling Image (es hat keinen Tag-Namen mehr), verbraucht aber weiter 500 MB Festplatte auf der Registry.
Die Registry-Festplatten (S3 Buckets) laufen voll. Um den Mülleimer zu leeren, muss der Registry-Admin einen "Read-Only Lock" setzen, externe Schreib-Pushes blockieren und den hoch-aggressiven Garbage-Collection Prozess ausführen, der verwaiste Blobs (die kein Manifest mehr referenzieren) schreddert.
5. Prüfen
Unterschied Repository vs. Registry?
Registry = Der Server (z. B. Docker Hub). Repository = Ein Ordner darin (z. B.nginxodermyuser/myapp). Ein Repository enthält viele Versionen (Tags) eines Images.Was ist
library/?Wenn dudocker pull ubuntutippst, macht Docker darausdocker.io/library/ubuntu.libraryist das offizielle Repository für "zertifizierte" Images auf dem Hub.Kann ich eine Registry selbst hosten?
Ja,docker run -p 5000:5000 registry:2. Es ist selbst nur ein Container! Aber Achtung: Du musst dich selbst um SSL, Auth und Backups kümmern.
Zusammenfassung
- Du hast ein Image gebaut (docker build). Es liegt auf deinem Laptop. Dein Kollege will es auch haben. Schickst du ihm einen USB-Stick? Nein. Du lädst es in eine Registry hoch (docker push). Er lädt es herunter (docker pull). Die Registry ist wie ein App Store...
- Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
Optionale Praxisaufgabe
- Erkläre Docker Registry in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Registry relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
HTTP S1
Überblick: HTTP ist die universelle Sprache des Internets. Jedes Mal, wenn du eine Webseite öffnest, eine App nutzt oder ein Video streamst, sprechen dein Gerät (Client) und der Server diese Sprache.
Welche HTTP-Methode nutzt dein Browser standardmäßig, wenn du eine Adresse in die Zeile tippst?
GET. Du forderst eine Ressource an, um sie anzuzeigen.Warum ist es technisch "schwierig", einen Warenkorb zu bauen, wenn HTTP stateless ist?
Weil der Server nach dem Hinzufügen des ersten Artikels sofort vergisst, wer du warst. Man muss den Zustand künstlich über Cookies/Sessions mitschleppen.Was bedeutet der Status Code 404 genau?
Der Server wurde erreicht (er lebt!), aber die Ressource (Datei/Seite), die du angefordert hast, liegt nicht an diesem Ort.
Artifact Registry S2
Überblick: Wenn Programmierer Code schreiben, entstehen am Ende Dateien, die man "ausliefern" kann. Eine .exe Datei (Windows Programm). Ein .jar File (Java). Ein Docker Image. Diese fertigen Pakete nennt man Artefakte. Wo speichert man die? Nicht auf dem Laptop, nicht in Git (Git ist für Text/Code, nicht für riesige Binärdateien). Man speichert sie in einer Artifact Registry. Das ist das "Lagerhaus" für Software. Server laden sich von dort die fertige Software, um sie zu installieren.
Einfach erklärt: Bekannte Beispiele: Docker Hub: Öffentliche Registry für Container. JFrog Artifactory / Sonatype Nexus: Der Industriestandard (On-Premise). AWS ECR / Google Artifact Registry: Cloud-Lösungen.
Warum nicht Git?
Git wird extrem langsam bei großen Binärdateien (Repo bläht sich auf). Git kann zudem keine Versionierung von Paketen (Maven, Nuget) im Sinne von Dependency Management abbilden.Was ist "Docker Hub Rate Limiting"?
Docker Hub erlaubt anonymen Nutzern nur 100 Pulls in 6 Stunden. In großen Firmen mit einer IP (NAT) ist das Limit in Sekunden erreicht. Deshalb: Eigene Registry nutzen!Polyglot?
Ja. Artifactory kann Docker, NPM, Maven, PyPi, Go, Helm, NuGet und mehr gleichzeitig verwalten. Alles unter einem Dach.
Datenbank S1
Überblick: Eine Datenbank ist ein digitaler Aktenschrank, in dem Informationen extrem ordentlich sortiert sind. Stell dir eine Excel-Tabelle vor, aber viel mächtiger. Dort speichert Facebook alle deine Freunde. Amazon alle deine Bestellungen. Deine Bank alle Kontobewegungen. Ohne Datenbanken müsste man alles in Textdateien schreiben – und das Suchen würde ewig dauern.
Einfach erklärt: Die meisten Datenbanken nutzen eine Sprache namens SQL (Structured Query Language), um mit ihnen zu reden. Ein Befehl sieht so aus: SELECT FROM users WHERE age 18; ("Gib mir alle Benutzer, die älter als 18 sind").
Was ist der Unterschied zwischen einer Datenbank und einer Excel-Tabelle?
Excel ist für Menschen (visuell). Datenbanken sind für Computer (massiv skalierbar, multiuser-fähig, sicher). Excel stürzt bei 1 Mio. Zeilen ab, Datenbanken lachen darüber.Warum nutzt man nicht für alles NoSQL?
Weil SQL-Datenbanken (Tabellen) extrem gut darin sind, Beziehungen darzustellen ("Kunde hat Bestellung hat Artikel"). NoSQL ist flexibler, aber oft schlechter bei komplexen Verknüpfungen (Joins).Was passiert, wenn zwei Leute gleichzeitig denselben Datensatz ändern?
Die Datenbank sperrt ihn kurzzeitig ("Locking"). Einer muss warten, bis der andere fertig ist, damit keine Daten überschrieben werden (Concurrency Control).
CPU S1
Überblick: Die CPU (Central Processing Unit) ist das Gehirn deines Computers. Sie erledigt alle Denkaufgaben. Jedes Mal, wenn du die Maus bewegst, eine Webseite öffnest oder 1+1 rechnest, ist es die CPU, die das macht. Sie ist ein winziger Chip (kleiner als ein Keks), der aber Milliarden von Befehlen pro Sekunde ausführen kann.
Einfach erklärt: Beim Kauf eines PCs achtet man auf zwei Dinge: 1. Kerne (Cores): Wie viele Aufgaben kann er gleichzeitig machen? 2 Kerne = Du kannst surfen und Musik hören. 8 Kerne = Du kannst spielen, streamen und Videos schneiden gleichzeitig. 2. Taktfrequenz (GHz): Wie schnell denkt er? 3 GHz = 3 Milliarden Takte pro Sekunde. (Schneller = Besser für Spiele).
Was ist wichtiger: Viele Kerne oder viel GHz?
Kommt drauf an. Für Gaming oft GHz (Single-Core Speed). Für Videoschnitt und Multitasking eher Kerne (Multi-Core Speed).Warum wird die CPU heiß?
Weil Milliarden von Elektronen mit hoher Geschwindigkeit durch winzige Leiterbahnen flitzen. Der elektrische Widerstand erzeugt Wärme, die der Lüfter wegblasen muss.Was ist der Unterschied zur GPU (Grafikkarte)?
Die CPU ist ein Alleskönner (wenige, starke Kerne). Die GPU ist ein Spezialist für Bilder (tausende, dumme Kerne), perfekt für parallele Aufgaben wie 3D-Grafik oder KI.
Schritt 11 / 35
Docker Compose
Mehrere Services gemeinsam betreiben.
S1
Schritt 11 / 35
Docker Compose
Mehrere Services gemeinsam betreiben.
1. Verstehen
Ein einzelner Container (docker run) ist wie eine einzelne Geige. Schön, aber kein Orchester.
Eine echte App braucht Datenbank, Webserver, Cache und API.
Wenn du dafür 4 Terminal-Fenster öffnest und 4 Befehle tippst, wirst du wahnsinnig.
Docker Compose ist der Dirigent.
Du schreibst einen Plan (docker-compose.yml), in dem alle Instrumente (Services) stehen.
Ein Befehl: docker compose up.
Docker startet alles, vernetzt es und zeigt dir alle Logs an einer Stelle.
Es ist der Standard für lokale Entwicklung.
Merksatz: Ein Werkzeug zur Definition und Ausführung von Multi-Container-Docker-Anwendungen, konfiguriert über eine YAML-Datei.
Für lokale Projekte ist ein Compose Override besonders nützlich: Die Basisdatei bleibt stabil, während lokale Ports, Volumes oder Debug-Settings getrennt überschrieben werden.
2. Anwenden
docker-compose.yml:
version: "3.8" # (Optional in V2)
services:
web:
build: .
ports: ["5000:5000"]
redis:
image: "redis:alpine"
docker compose up: Startet alles (im Vordergrund).docker compose up -d: Startet im Hintergrund (Detached).docker compose ps: Zeigt Status.docker compose logs -f: Zeigt Logs live ("Follow").docker compose down: Stoppt und löscht Container + Netzwerke.
:level1
Praxisbruecke: Compose beschreibt mehrere Container als ein kleines System. Eine App, eine Datenbank und ein Cache können gemeinsam gestartet werden. Services, Ports, Volumes und .env-Werte gehoeren zusammen.
3. Technisch einordnen
1. V1 (Python) vs V2 (Go)
- V1 (
docker-compose): War ein separates Python-Tool. Langsam, Installationsprobleme. Ist Deprecated. - V2 (
docker compose): Ist ein Plugin direkt in der Docker CLI (geschrieben in Go). Viel schneller, bessere Parallelität. Nutze nur noch V2 (ohne Bindestrich).
2. Extensions & Inclucdes
Neuere Features erlauben Modularisierung.
include: Importiere eine anderecompose.yml(z. B.include: infra/db.yaml).x-logging: &default-logging: YAML Anchors, um Configs zu teilen (DRY). Damit kann man riesige Monolithen-Setups (50 Container) beherrschbar machen.
3. Production Use?
Soll man Compose in Produktion nutzen? Antwort: Jein.
- Single Server: Ja, total okay. "Compose on Server" ist einfach und stabil.
- Cluster: Nein. Compose kann kein Failover zwischen Servern (Node A stirbt -> App zieht nach Node B um). Das kann nur Docker Swarm oder Kubernetes.
Es gibt Tools wie
kompose, die Compose-Files zu Kubernetes-Manifesten konvertieren.
4. Vertiefen
1. Networking und DNS Discovery
Startest du normale Docker-Container parallel, haben sie IPs (wie 172.17.0.2), aber sie "kennen" sich nicht.
Docker Compose baut magisch ein Custom Bridge Network im Hintergrund (z.B. projekt_default).
Der geniale Architektur-Kniff: In diesem Netz läuft ein winziger, eingebetteter DNS-Server von Docker.
Dadurch kann dein Django-Code im Container A DATABASES_HOST = "db" schreiben. Der Compose-DNS fängt die Anfrage ab, löst das Wort db zur dynamischen IP des Containers B auf (Service Discovery). Das abstrahiert IP-Adressen für Entwickler völlig weg.
2. Startup Orders (Depends_on Conditions)
Ein riesiges Problem: Dein Node.js Backend bootet in 1 Sekunde, aber die PostgreSQL Datenbank braucht 5 Sekunden zum Initialisieren. Das Backend feuert seine queries und crasht ("Connection refused"), weil Compose alle Container stupide zeitgleich startet.
Profis nutzen tiefes depends_on:
backend:
depends_on:
db:
condition: service_healthy
Hier wartet Docker Compose stur und hält den Backend-Start zurück, bis der db Container den in seiner Sektion definierten healthcheck erfolgreich zurückmeldet.
3. Overrides (Die docker-compose.override.yml)
Wie teilt man sich eine komplexe YAML im Team, wenn der Local-Entwickler "Hot-Reloading" Mappen will, aber der Staging-Server das Image kompilieren soll? Docker Compose liest automatisch immer zwei Dateien, wenn sie existieren:
docker-compose.yml(Das absolute Basis-Set, für alle gültig).docker-compose.override.yml(Entwickler-Spezifisch). Im Override überschreibt der Programmierer lokal Ports oder mountet seinen Code (./app:/app), während die Datei via.gitignoregar nicht in Git eingecheckt wird. Im Staging läuft nur die Basis-Datei ohne Volumes. Das löst das fatale "It works on my machine" Problem tief in der Infrastruktur.
5. Prüfen
Was bedeutet
version: "3"?Früher wichtig für Swarm-Kompatibilität. In der neuen Compose Spec (V2) ist das Version-Feld optional und wird oft ignoriert. Docker empfiehlt, es wegzulassen.Healthchecks?
Du kannst im Compose File definieren:healthcheck: test: ["CMD", "curl", "-f", "localhost"]. Compose startet abhängige Services erst, wenn der Healthcheck "healthy" ist (service_healthy), nicht nur "running"..envFiles?Compose lädt automatisch.envim gleichen Ordner. Du kannst Variablen in der YAML nutzen:image: myapp:${TAG}. Perfekt für Versionierung.
Zusammenfassung
- Ein einzelner Container (docker run) ist wie eine einzelne Geige. Schön, aber kein Orchester. Eine echte App braucht Datenbank, Webserver, Cache und API. Wenn du dafür 4 Terminal-Fenster öffnest und 4 Befehle tippst, wirst du wahnsinnig. Docker Compose ist...
- docker-compose.yml: yaml version: "3.8" (Optional in V2) services: web: build: . ports: ["5000:5000"] redis: image: "redis:alpine" docker compose up: Startet alles (im Vordergrund). docker compose up -d: Startet im Hintergrund (Detached). docker compose ps:...
Optionale Praxisaufgabe
- Erkläre Docker Compose in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Compose relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
YAML (YAML Ain't Markup Language) S1
Überblick: Computer mögen JSON (viele Klammern, schwer zu lesen). Menschen mögen Listen und Einrückungen. YAML ist ein Datenformat, das für Menschen gemacht ist. Keine geschweiften Klammern {}. Keine Anführungszeichen (meistens). Stattdessen: Einrückung (Indentation). Es wird fast überall in der modernen IT für Konfigurationen genutzt (Kubernetes, Docker Compose, Ansible, GitHub Actions).
Einfach erklärt: JSON: json { "server": { "port": 80, "admin": ["max", "moritz"] } }
Tiefer verstanden: production: <<: basesettings Erbt alles von defaults host: prod.com Sehr nützlich in CI/CD Pipelines (GitLab CI), um riesige Dateien klein zu halten.
Superset von JSON?
Ja! Jedes gültige JSON ist auch gültiges YAML. Du kannst{ "foo": "bar" }einfach in eine YAML-Datei schreiben. (Umgekehrt nicht).Kommentare?
Ja, mit#. JSON kann offiziell keine Kommentare. Das ist einer der Hauptgründe, warum Configs YAML nutzen (man kann erklären, warum eine Einstellung so ist).Sicherheitsrisiko?
Ja, in manchen Sprachen (Python/Ruby) war der Standard-YAML-Parser unsicher (yaml.load()), weil er Code ausführen konnte (Objekt-Deserialisierung). Nutze immersafe_load().
Service Mesh S3
Überblick: Ein Service Mesh ist eine Infrastrukturschicht für Kommunikation zwischen Diensten. Es kuemmert sich um Dinge wie Verschluesselung, Routing, Retry, Telemetrie und Policies, ohne dass jeder Dienst alles selbst implementieren muss.
Einfach erklärt: In Microservice-Umgebungen sprechen viele Dienste miteinander. Ein Service Mesh kann mTLS erzwingen, Traffic auf neue Versionen routen, Fehler sichtbar machen und Verbindungen beobachten. Bekannte Werkzeuge sind Istio und Linkerd.
Tiefer verstanden: Viele Service Meshes nutzen Sidecar-Proxies oder nodebasierte Proxies. Control Plane und Data Plane werden getrennt. Die Control Plane verteilt Regeln, die Data Plane verarbeitet Traffic. Typische Features sind Traffic Splitting, Circuit Breaking, mTLS und Metriken.
Praxisgrenze: Ein Service Mesh löst keine schlechte Service-Architektur. Es fuegt Komplexitaet, Latenz, Zertifikatsbetrieb und Debug-Aufwand hinzu. Für kleine Systeme kann es zu schwer sein. Sinnvoll wird es, wenn Governance, Sicherheit und Observability den Aufwand rechtfertigen.
Warum nutzt man ein Service Mesh?
Um Kommunikation zwischen Diensten sicherer, beobachtbarer und steuerbarer zu machen.Was ist mTLS?
Beidseitig authentifizierte TLS-Verbindungen, bei denen Client und Server Zertifikate nutzen.Was ist eine typische Falle?
Ein Mesh einzufuehren, obwohl Team, Monitoring und Betriebsreife dafür noch nicht bereit sind.
Compose Override S2
Überblick: Du hast eine docker-compose.yml für dein Team. Darin steht: "Starte Webserver auf Port 80." Aber auf deinem lokalen Laptop ist Port 80 schon belegt. Du willst Port 8080 nutzen. Du willst die Datei nicht ändern (weil Git dann meckert). Lösung: Compose Override. Du erstellst eine zweite Datei: docker-compose.override.yml. Darin schreibst du nur die Änderung: "Für Webserver: Nutze Port 8080". Docker liest automatisch beide Dateien und verschmilzt sie (Merge). Die Override-Datei wird oft in .gitignore gepackt, damit jeder Entwickler seine eigenen lokalen Anpassungen haben kann.
Einfach erklärt: Basis docker-compose.yml: yaml services: web: image: my-app:production ports: - "80:80"
Praxisgrenze: services: web: image: nginx logging: default-logging Dies erlaubt es, Base-Konfigurationen (wie Logging, Netzwerke, Restart-Policies) einmal zu definieren und im selben File in dutzenden Containern per anchor zu injecten. Compose Overrides verschwinden dadurch oft, da das Base-File schlank genug wird, um Umgebungsvariablen (.env) für Dev/Prod Switches zu nutzen.
Muss ich die Override-Datei angeben?
Nein. Wenn siedocker-compose.override.ymlheißt, lädt Docker sie automatisch. Das ist Standard-Verhalten. Wenn sie anders heißt, musst du-fnutzen.Kann ich Services löschen?
Nein. Overrides sind additiv. Du kannst keine Services "weg-konfigurieren". Du kannst sie nur stoppen (replicas: 0oder Profiles nutzen).Warum .gitignore?
Weil in der Override oft lokale Pfade (/Users/rixx/projekt), Secrets oder Debug-Ports stehen, die auf dem Produktionsserver nichts zu suchen haben.
Schritt 12 / 35
Compose Service
Services, Images, Ports und Abhaengigkeiten modellieren.
S1
Schritt 12 / 35
Compose Service
Services, Images, Ports und Abhaengigkeiten modellieren.
1. Verstehen
In einer docker-compose.yml Datei beschreibst du deine komplette Applikation.
Eine App besteht oft aus mehreren Teilen: Webserver, Datenbank, Cache.
Jeder dieser Teile ist ein Service.
Ein Service definiert: "Welches Image soll laufen? Welche Ports? Welches Netzwerk?"
Docker Compose sorgt dafür, dass aus der Definition (Text) ein laufender Container (Prozess) wird.
Wichtig: Ein Service kann mehrere Container starten (Scaling). "Service: Web" -> 3 Container "Web-1, Web-2, Web-3".
Merksatz: Ein konfigurierbarer Block in einer Docker-Compose-Datei, der definiert, wie ein spezifischer Container (Image, Ports, Volumes, Netzwerk) innerhalb eines Multi-Container-Setups ausgeführt werden soll.
2. Anwenden
services:
# Service 1: Die Datenbank
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
# Service 2: Die App
web:
build: .
depends_on:
- db
Hier gibt es zwei Services: db und web.
Du kannst sie einzeln steuern: docker compose restart web.
Oder zusammen: docker compose up.
Praxisroutine
In der Praxis lernst du Compose Service, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Scaling & Replicas
Ein Service ist nicht gleich ein Container.
docker compose up --scale web=3.
Jetzt starten 3 Instanzen des Web-Containers.
Docker Load Balancer (internes DNS) verteilt Anfragen an web automatisch auf die 3 IPs (Round Robin).
In der YAML: deploy: replicas: 3 (Version 3 Syntax).
2. Service-to-Service Networking
Services finden sich per DNS.
Der Service web kann einfach postgres://db:5432 aufrufen.
Docker löst den Hostnamen db automatisch zur internen IP des Datenbank-Containers auf.
Du musst niemals IPs hardcoden.
Voraussetzung: Beide sind im gleichen Netzwerk (Standardmäßig erstellt Compose ein default Netzwerk).
3. Restart Policies & Dependencies
Mit depends_on legst du die Startreihenfolge fest.
depends_on: condition: service_healthy.
Das ist extrem mächtig: "Starte Web erst, wenn die Datenbank wirklich bereit ist (Healthcheck OK), nicht nur wenn der Container läuft."
Verhindert "Connection Refused" Fehler beim Booten.
4. Vertiefen
1. Volume Mounts vs. Bind Mounts
In der Service-Definition bestimmst du, wie Daten den Container-Tod überleben.
- Bind Mount (
./data:/app/data): Mappt einen harten, absoluten Pfad deines Laptops direkt in den Container. Für Entwickler im Web-Backend unersetzlich, da jede Code-Änderung in der IDE sofort, ohne Image-Rebuild, Live im laufenden Service reflektiert wird. - Named Volumes (
db_data:/var/lib/postgresql/data): Docker verwaltet den physischen Ort auf der Host-Festplatte transparent selbst. Das ist der Industrie-Standard für Datenbank-Services, weil Docker sich um Dateirechte (Permission-Hürden in Linux UID/GID) und Isolation kümmert.
2. The Init Process (PID 1) Zombie Problem
Solltest du im Service ein simples Shell-Script via command: ./start.sh booten, wird dieses Konstrukt in Linux oft zur PID 1 (Prozess-ID 1) innerhalb der Isolation.
PID 1 in Linux hat extrem mächtige Spezialeigenschaften: Es ist der Einzige, der SIGTERM Kill-Signale igorieren kann. Und es ist für das Säubern (Reaping) toter Kindprozesse (Zombie Processes) verantwortlich.
Stirbt eine App in deinem Compose-Service fehlerhaft ab, leakt sie RAM mit Zombies, da dein dummes ./start.sh überhaupt nicht weiß, wie man Zombies beerdigt. Abhilfe: Die Flag init: true in der Docker Compose File ergänzen. Sie spannt einen winzigen C-Init-Prozess (Tini) vor deine App, der PID 1 übernimmt und Zombies perfekt wegschaufelt.
3. Compose Watch (Live Synchronization)
Seit neueren Docker Versionen hat Compose mit watch ein revolutionäres Konzept für Frontend/Backend-Iterationen erhalten, ohne den RAM-fressenden Ballast komplexer Webpack-Bindings und Inotify-Loops.
In der .yml unter dem Service definierst du Verzeichnisse, die überwacht werden sollen.
Du kannst definieren: Wenn sich .css ändert, synchronisiere sie hart und sofort hinein (action: sync).
Wenn sich die package.json (Requirements) ändert, nützt Sync nichts. Hier löst du action: rebuild aus, was blitzartig einen Multi-Stage Partial-Buld triggert, um Abhängigkeiten des Services lokal frisch im Image neu zu generieren.
5. Prüfen
Unterschied Service vs. Container?
Service = Die Bauanleitung (Klasse). Container = Die laufende Instanz (Objekt). Ein Service kann N Container haben.Was ist
extends?Wiederverwendung von Code. Du kannst einen "Base-Service" definieren (z. B. mit Logging-Config) und andere Services davon erben lassen. Hilft bei großen Projekten (DRY - Don't Repeat Yourself).Container Name vs. Service Name?
Der Service heißtdb. Der Container heißt automatischprojekt_db_1. Im Netzwerk solltest du immer den Service Namen (db) nutzen, da der Container-Name sich ändern kann (z. B. beim Skalieren_2,_3).
Zusammenfassung
- In einer docker-compose.yml Datei beschreibst du deine komplette Applikation. Eine App besteht oft aus mehreren Teilen: Webserver, Datenbank, Cache. Jeder dieser Teile ist ein Service. Ein Service definiert: "Welches Image soll laufen? Welche Ports? Welches...
- yaml services: Service 1: Die Datenbank db: image: postgres:15 environment: POSTGRESPASSWORD: secret
Optionale Praxisaufgabe
- Erkläre Compose Service in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Compose Service relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Compose Override S2
Überblick: Du hast eine docker-compose.yml für dein Team. Darin steht: "Starte Webserver auf Port 80." Aber auf deinem lokalen Laptop ist Port 80 schon belegt. Du willst Port 8080 nutzen. Du willst die Datei nicht ändern (weil Git dann meckert). Lösung: Compose Override. Du erstellst eine zweite Datei: docker-compose.override.yml. Darin schreibst du nur die Änderung: "Für Webserver: Nutze Port 8080". Docker liest automatisch beide Dateien und verschmilzt sie (Merge). Die Override-Datei wird oft in .gitignore gepackt, damit jeder Entwickler seine eigenen lokalen Anpassungen haben kann.
Einfach erklärt: Basis docker-compose.yml: yaml services: web: image: my-app:production ports: - "80:80"
Praxisgrenze: services: web: image: nginx logging: default-logging Dies erlaubt es, Base-Konfigurationen (wie Logging, Netzwerke, Restart-Policies) einmal zu definieren und im selben File in dutzenden Containern per anchor zu injecten. Compose Overrides verschwinden dadurch oft, da das Base-File schlank genug wird, um Umgebungsvariablen (.env) für Dev/Prod Switches zu nutzen.
Muss ich die Override-Datei angeben?
Nein. Wenn siedocker-compose.override.ymlheißt, lädt Docker sie automatisch. Das ist Standard-Verhalten. Wenn sie anders heißt, musst du-fnutzen.Kann ich Services löschen?
Nein. Overrides sind additiv. Du kannst keine Services "weg-konfigurieren". Du kannst sie nur stoppen (replicas: 0oder Profiles nutzen).Warum .gitignore?
Weil in der Override oft lokale Pfade (/Users/rixx/projekt), Secrets oder Debug-Ports stehen, die auf dem Produktionsserver nichts zu suchen haben.
Backend S1
Überblick: Eine App ist wie ein Restaurant. Frontend: Der prächtige Gastraum, die Speisekarte, der Kellner. (Was du siehst). Backend: Die Küche, das Lager, die Buchhaltung. (Was im Hintergrund passiert). Wenn du in der App auf "Kaufen" drückst, passiert im Frontend wenig (nur eine Lade-Animation). Das Backend prüft: "Ist Geld da? Ist Ware da?" und speichert die Bestellung in der Datenbank. Das Backend läuft auf dem Server, weit weg vom User, wo es sicher ist.
Einfach erklärt: Sprachen: Python (Django/FastAPI), Java (Spring), JavaScript (Node.js), Go, PHP.
BFF (Backend for Frontend)?
Ein Design Pattern. Statt einer Riesen-API gibt es spezielle Mini-Backends: Eines für die iOS-App (liefert kleine Bilder), eines für Desktop (liefert viele Details).ORM?
Object Relational Mapper. Ein Tool im Backend, das Python-Objekte automatisch in SQL-Befehle übersetzt. Spart Zeit, frisst Performance, wenn man nicht aufpasst (N+1 Problem).Headless CMS?
Ein Backend-Only CMS (Content Management System). Es hat kein Frontend (keine Webseite). Es liefert nur JSON per API. Das Frontend baut sich der Entwickler selbst (z. B. mit React).
Datenbank S1
Überblick: Eine Datenbank ist ein digitaler Aktenschrank, in dem Informationen extrem ordentlich sortiert sind. Stell dir eine Excel-Tabelle vor, aber viel mächtiger. Dort speichert Facebook alle deine Freunde. Amazon alle deine Bestellungen. Deine Bank alle Kontobewegungen. Ohne Datenbanken müsste man alles in Textdateien schreiben – und das Suchen würde ewig dauern.
Einfach erklärt: Die meisten Datenbanken nutzen eine Sprache namens SQL (Structured Query Language), um mit ihnen zu reden. Ein Befehl sieht so aus: SELECT FROM users WHERE age 18; ("Gib mir alle Benutzer, die älter als 18 sind").
Was ist der Unterschied zwischen einer Datenbank und einer Excel-Tabelle?
Excel ist für Menschen (visuell). Datenbanken sind für Computer (massiv skalierbar, multiuser-fähig, sicher). Excel stürzt bei 1 Mio. Zeilen ab, Datenbanken lachen darüber.Warum nutzt man nicht für alles NoSQL?
Weil SQL-Datenbanken (Tabellen) extrem gut darin sind, Beziehungen darzustellen ("Kunde hat Bestellung hat Artikel"). NoSQL ist flexibler, aber oft schlechter bei komplexen Verknüpfungen (Joins).Was passiert, wenn zwei Leute gleichzeitig denselben Datensatz ändern?
Die Datenbank sperrt ihn kurzzeitig ("Locking"). Einer muss warten, bis der andere fertig ist, damit keine Daten überschrieben werden (Concurrency Control).
Schritt 13 / 35
Docker Compose Volumes
Persistente Daten richtig anbinden.
S1
Schritt 13 / 35
Docker Compose Volumes
Persistente Daten richtig anbinden.
1. Verstehen
In docker-compose.yml definierst du, wo deine Daten überleben.
Wenn du eine Datenbank (postgres) startest und den Container löschst, sind die Daten weg.
Das ist schlecht.
Mit Volumes sagst du: "Speichere /var/lib/postgresql/data an einem sicheren Ort auf dem Host."
Docker Compose hat zwei Arten:
- Short Syntax:
- ./data:/db. (Einfach, Bind Mount). - Long Syntax / Named Volumes: Sauberer, von Docker verwaltet.
Merksatz: Die Konfiguration von persistentem Speicher innerhalb von Docker Compose, um Daten unabhängig vom Lebenszyklus der Container zu bewahren.
2. Anwenden
Named Volumes (Empfohlen für DBs):
services:
db:
image: mysql
volumes:
- db_data:/var/lib/mysql
volumes:
db_data: # Muss hier definiert werden!
Docker erstellt ein Volume projektname_db_data. Die Daten liegen tief in /var/lib/docker/volumes. Sie überleben docker compose down.
Löschen erzwingen: docker compose down -v.
Bind Mounts (Empfohlen für Configs/Code):
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
Nutze relative Pfade (./). :ro macht es Read-Only (Sicherheit).
Praxisroutine
In der Praxis lernst du Docker Compose Volumes, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Volume Drivers (NFS / Cloud)
Volumes müssen nicht lokal sein. Du kannst Plugins nutzen:
volumes:
cloud_storage:
driver: rexray/s3
driver_opts:
bucket: my-bucket
Der Container schreibt lokal, der Treiber schiebt es nach S3.
Oder local-persist für festes Mounten von NFS-Shares.
Das erlaubt Containern, zwischen Hosts zu wandern (Swarm/K8s Vorstufe).
2. Copy-on-Write Init
Ein geniales Feature von Docker Volumes:
Wenn das Image in /app/data schon Dateien hat (z. B. eine Default-Config) und du ein leeres Volume drüber mountest...
...kopiert Docker den Inhalt vom Image in das Volume.
Bei Bind Mounts passiert das nicht (der Ordner wird überdeckt/leer).
Das macht Named Volumes sehr anfängerfreundlich ("Pre-Seeding Data").
3. Permissions & User Mapping
Klassisches Problem:
Datenbank schreibt als User postgres (UID 999).
Du machst Backup und startest neue DB. Die hat UID 70.
"Permission Denied".
Docker kennt keine UIDs im Volume-Metadaten.
Lösung: Nutzung von initContainers (chown -R 999 /data) beim Start, um Rechte zu fixen.
4. Vertiefen
1. Inode Replacement und die Bind-Mount Falle
Ein Bind Mount (- ./app:/app) verzahnt ein Host-Verzeichnis in den Container.
Problem beim Coding: Du mountest eine Einzeldatei (- ./config.yaml:/app/config.yaml).
Wenn deine lokale IDE die Datei config.yaml überschreibt, tun viele Texteditoren dies per Atomic Save "Safe Write"-Mechanismus: Sie schreiben eine config.tmp, löschen die echte config.yaml und benennen die tmp heimlich um. Dadurch ändert sich die Inode (Nummer auf der Festplatte). Docker jedoch trackt den Bind-Mount starr auf die alte Inode. Plötzlich "updatet" der Container Änderungen nicht mehr, weil der Linux-Kernel den alten Pointer zu einer abgeklemmten Schatten-Inode führt. Deswegen sollte man niemals Einzeldateien mounten, sondern immer ihr übergeordnetes Verzeichnis (Directory), da der Inode des Ordners stabil bleibt.
2. Die Anonyme Volume-Kette
Wenn im offiziellen Dockerfile einer Datenbank ein Kommando wie VOLUME /var/lib/mysql hardcodiert ist, erstellt der Docker Engine bei jedem simplen docker run ein sogenanntes Anonymes Volume (ein Ordner im Host mit einem 64-stelligen UUID-Hash wie 8f2dca...), falls der User kein Named Volume spezifiziert hat.
Zerstörst du den Container (docker rm), bleibt dieser Hash-Order oft unlöschbar und unsichtbar (verwaist) im Laufwerk zurück, bis /var/lib/docker/volumes die gesamte SSD (Solid State Drive) frisst. Deshalb erzwingt man Named Volumes (mysql_data:/var/lib...) im Compose. Die Aufräumung verwaister Kacheln erfolgt per hartem docker volume prune.
3. Chowning beim Mount vs. Init-Scripts
Mountet man ein persistentes Datenbank/Named Volume auf einen Linux-Host, gehört das Volume (da vom Daemon generiert) fast immer root:root.
Läuft dein Express/Node.js Container jedoch sauber als ungehinderter Unprivileged User (z.B. User uid=1000 node), prallt der Container mit einem harten Permission Denied Error 13 vom Mountpunkt ab und crasht.
In Docker Compose fixen das Sysadmins durch Workarounds: Entweder ein Entrypoint-Shellscript im Container ausführen, welches als kurzes root via chown -R 1000:1000 /app/data die Zugriffsrechte ins Volume hämmert und dann mit su-exec node /bin/app das Zepter aufgibt, oder (moderner, ab Compose v2.22) durch das definieren dedizierter --userns-remap Namensumbelegungen durch den Daemon.
5. Prüfen
Was ist
tmpfs?Ein Volume im RAM.- type: tmpfs, target: /tmp. Daten sind weg beim Neustart. Extrem schnell. Gut für Cache oder Security-Keys, die niemals auf die Festplatte geschrieben werden sollen.Unterschied
volumevs.bindin Long Syntax?Die Long Syntax (type: bind) ist expliziter. Sie erstellt den Ordner nicht automatisch, wenn er fehlt (Error), was gut ist, um Tippfehler zu finden. Short Syntax erstellt einfach leere Ordner.Wie migriere ich Volumes?
Schwer. "Docker cp" geht nicht gut bei Volumes. Best Practice: Starte einen temporären Container, der das Volume UND einen lokalen Ordner mountet, und machetar cvf. Oder nutze Backup-Tools.
Zusammenfassung
- In docker-compose.yml definierst du, wo deine Daten überleben. Wenn du eine Datenbank (postgres) startest und den Container löschst, sind die Daten weg. Das ist schlecht. Mit Volumes sagst du: "Speichere /var/lib/postgresql/data an einem sicheren Ort auf dem...
- Named Volumes (Empfohlen für DBs): yaml services: db: image: mysql volumes: - dbdata:/var/lib/mysql
Optionale Praxisaufgabe
- Erkläre Docker Compose Volumes in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Compose Volumes relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Tmpfs Mount (RAM Disk) S2
Überblick: Normalerweise schreiben Programme auf die Festplatte (HDD/SSD). Das ist langsam und überlebt einen Neustart. Manchmal willst du das Gegenteil: 1. Es soll extrem schnell sein (Cache). 2. Es soll sofort weg sein, wenn der Strom ausgeht (Passwörter). Dafür gibt es tmpfs. Du mountest einen Teil des RAMs (Arbeitsspeicher) als "Ordner". /mnt/ramdisk. Alles, was du da reinschreibst, landet nie auf dem Datenträger.
Einfach erklärt: Docker: docker run --tmpfs /app/cache nginx K8s: yaml volumes: - name: secrets emptyDir: medium: Memory Wenn der Container stoppt, sind die Daten sofort weg. Keine "Undelete" Tools können sie retten.
Performance Gewinn?
Dramatisch. RAM ist 100x schneller als SSD. Latenz im Nanosekunden-Bereich. Perfekt für temporäre Compile-Dateien oder Session-Caches.Unterschied zu Ramdisk?
Altmodische Ramdisks reservierten fix 1GB RAM. Wenn leer, war der RAM trotzdem weg.tmpfswächst und schrumpft dynamisch. Es belegt nur so viel RAM, wie Dateien drin sind./dev/shm?Shared Memory. Ein Standard-tmpfs in Linux, das Prozesse nutzen, um Speicherbereiche zu teilen (Inter Process Communication). Docker container haben oft ein zu kleines/dev/shm(64MB), was Chrome/PyTorch crashen lässt. Mount es größer!
StatefulSet (K8s) S2
Überblick: Deployments sind für Webserver (Rinder). Alle Pods (web-x8z, web-9a1) sind gleich. Wenn einer stirbt, startet ein neuer. Egal welcher. Datenbanken (Postgres, Mongo, Kafka) sind wie Haustiere (Pets). Sie haben Namen (mongo-0, mongo-1). Sie haben festen Wohnsitz (Disk). mongo-0 ist der Master. mongo-1 ist der Slave. Du kannst sie nicht beliebig tauschen. Wenn mongo-0 stirbt, muss er als mongo-0 wiederkommen (mit derselben Disk!). Das StatefulSet garantiert diese Ordnung. Es startet sie auch nacheinander: Erst 0, dann 1, dann 2.
Einfach erklärt: Die Pods heißen immer name-0, name-1 usw. (Ordinal Index). Sie haben auch stabile DNS-Namen: web-0.service.ns.svc.cluster.local. Wichtig: Du brauchst einen Headless Service (clusterIP: None), damit DNS funktioniert. Du nutzt volumeClaimTemplates im YAML, damit jeder Pod seinen eigenen PVC (data-web-0, data-web-1) bekommt. (Bei Deployments teilen sich alle den gleichen PVC oder crashen wegen RWO).
Warum "Pet Set"?
Der alte Name in Alpha Versionen. Anspielung auf "Cattle vs Pets". Deployments sind Cattle (austauschbar). StatefulSets sind Pets (einzigartig, müssen gepflegt werden).Update Strategie?
OnDelete: K8s macht gar nichts, wenn du das Image änderst. Du musst die Pods manuell löschen.RollingUpdate: K8s löscht erst Index N, wartet, dann Index N-1. Das ist sicherer für Leader Election.PVC Retain?
Wenn du das StatefulSet löschst, werden die PVCs nicht gelöscht. K8s sagt: "Daten sind heilig". Du musst die 50 PVCs manuell löschen, wenn du aufräumen willst.
Datenbank S1
Überblick: Eine Datenbank ist ein digitaler Aktenschrank, in dem Informationen extrem ordentlich sortiert sind. Stell dir eine Excel-Tabelle vor, aber viel mächtiger. Dort speichert Facebook alle deine Freunde. Amazon alle deine Bestellungen. Deine Bank alle Kontobewegungen. Ohne Datenbanken müsste man alles in Textdateien schreiben – und das Suchen würde ewig dauern.
Einfach erklärt: Die meisten Datenbanken nutzen eine Sprache namens SQL (Structured Query Language), um mit ihnen zu reden. Ein Befehl sieht so aus: SELECT FROM users WHERE age 18; ("Gib mir alle Benutzer, die älter als 18 sind").
Was ist der Unterschied zwischen einer Datenbank und einer Excel-Tabelle?
Excel ist für Menschen (visuell). Datenbanken sind für Computer (massiv skalierbar, multiuser-fähig, sicher). Excel stürzt bei 1 Mio. Zeilen ab, Datenbanken lachen darüber.Warum nutzt man nicht für alles NoSQL?
Weil SQL-Datenbanken (Tabellen) extrem gut darin sind, Beziehungen darzustellen ("Kunde hat Bestellung hat Artikel"). NoSQL ist flexibler, aber oft schlechter bei komplexen Verknüpfungen (Joins).Was passiert, wenn zwei Leute gleichzeitig denselben Datensatz ändern?
Die Datenbank sperrt ihn kurzzeitig ("Locking"). Einer muss warten, bis der andere fertig ist, damit keine Daten überschrieben werden (Concurrency Control).
SSD (Solid State Drive) S1
Überblick: Früher hatten Computer HDDs (Hard Disk Drives). Da drehte sich drinnen eine Magnetscheibe wie bei einem Plattenspieler. Das war laut, empfindlich und langsam. Eine SSD hat keine beweglichen Teile. Sie besteht aus Speicherchips (wie ein riesiger USB-Stick). Sie ist lautlos. Sie ist robust (kann runterfallen). Sie ist extrem schnell (Windows startet in 10 Sekunden statt 2 Minuten).
Einfach erklärt: Es gibt zwei Bauformen: 1. SATA-SSD: Sieht aus wie eine kleine Zigarrenschachtel (2,5 Zoll). Wird mit Kabel angeschlossen. (ca. 500 MB/s). 2. NVMe (M.2): Sieht aus wie ein Riegel Kaugummi. Wird direkt aufs Mainboard gesteckt. Extrem schnell (bis zu 7.000 MB/s).
Sollte ich meine Festplatte defragmentieren?
SSD auf keinen Fall! Defragmentieren sortiert Daten um (viele Schreibvorgänge). Das nutzt die SSD unnötig ab und bringt keinen Geschwindigkeitsvorteil (weil sie eh überall sofort zugreifen kann).Sind SSDs teurer als HDDs?
Ja, pro Gigabyte. Für Datengräber (Fotosammlung, Backups) lohnen sich noch alte HDDs (4 TB HDD = 80 €, 4 TB SSD = 250 €).Gehen Daten auf der SSD verloren ohne Strom?
Nein, es ist "nicht-volatiler" Speicher. Theoretisch können SSDs nach Jahren ohne Strom Daten verlieren (Bit Rot), aber für den Alltag ist das irrelevant.
Schritt 14 / 35
Docker Compose Networks
Service-Kommunikation in Compose verstehen.
S2
Schritt 14 / 35
Docker Compose Networks
Service-Kommunikation in Compose verstehen.
1. Verstehen
Früher (mit docker run) musste man Container manuell verbinden (--link). Das war schrecklich.
Docker Compose macht das automatisch.
Wenn du eine docker-compose.yml startest, erstellt Docker ein neues, isoliertes Netzwerk für dieses Projekt.
Der Projektname ist oft der Ordnername (z. B. myapp_default).
Alle Container in dieser Datei landen in diesem Netzwerk.
Sie können sich gegenseitig beim Namen rufen:
web kann db anpingen.
Aber Container aus einem anderen Projekt (otherapp_default) kommen nicht rein. Das ist gut für Sicherheit und Ordnung.
Merksatz: Die automatische Netzwerkkonfiguration in Docker Compose, die applikations-spezifische Bridge-Netzwerke erstellt und DNS-Namen basierend auf Service-Namen bereitstellt.
2. Anwenden
Standardmäßig musst du gar nichts konfigurieren. Aber manchmal willst du spezielle Netzwerke.
services:
frontend:
networks:
- public # Darf nach außen
- internal # Darf zur DB
backend:
networks:
- internal # Darf NICHT direkt angesprochen werden
networks:
public:
internal:
internal: true # Kein Internetzugriff (Isolation)
Hier baust du eine DMZ (Demilitarized Zone). Das Frontend ist der Gatekeeper. Das Backend ist geschützt.
Praxisroutine
In der Praxis lernst du Docker Compose Networks, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. External Networks
Wenn du Microservices in getrennten Compose-Files hast.
app-a/docker-compose.yml und app-b/docker-compose.yml.
Wie reden sie miteinander?
Du definierst ein shared network.
networks:
global-net:
external: true
Docker meckert nicht "Network not found", sondern sucht ein bereits existierendes Netzwerk namens global-net.
Beide Apps hängen sich rein und können sich pingen.
2. Aliases & Priority
Was, wenn ich db heißen will, aber der Service heißt database_postgres_v14?
services:
db:
networks:
default:
aliases:
- postgres
- database
Jetzt antwortet der DNS auf alle drei Namen. Wichtig bei Migrationen ("Mock-Database" soll so heißen wie die echte).
3. Driver Opts (MTU)
Ein häufiger Fehler in VPNs oder OpenStack Clouds: Die MTU (Maximum Transmission Unit, Paketgröße) ist kleiner als 1500. Docker Bridge standardmäßig 1500. Folge: Große Pakete werden gedroppt -> "SSH geht, aber HTTPS hängt". Lösung:
networks:
default:
driver_opts:
com.docker.network.driver.mtu: 1400
4. Vertiefen
DNS Round Robin & Service Skalierung
Was passiert, wenn du in Compose sagst: deploy: replicas: 3 für den web-Service?
Docker Compose erstellt drei Container (project_web_1, project_web_2, project_web_3).
Aber der interne eingebettete DNS-Server tut nun etwas Brillantes: DNS Round Robin.
Wenn die API ping web aufruft, gibt der DNS beim ersten Mal die IP von Container 1 zurück, dann die von Container 2, etc. (Round Robin Load Balancing).
Achtung: Dies ist Client-Side Load Balancing. Wenn deine Anwendung DNS-Antworten starr im RAM cached (z. B. manche ältere Java oder Node.js Konfigurationen), wird der Traffic hart an einen einzigen Container gebunden, und die Skalierung bringt exakt gar nichts.
IP Overlaps & das VPN-Problem
Docker Compose verteilt IPs aus dem 172.17.x.x oder 172.18.x.x Adressraum (RFC 1918).
Wenn du für eine große Firma im VPN arbeitest, kann es passieren, dass das Firmen-Router-VPN exakt dieses Subnetz routet.
Ergebnis: Du tippst ping firmenserver (172.18.0.5) und pingst versehentlich deinen lokalen Redis-Container in Compose. Die lokale Bridge ("Connected Route") schlägt die VPN-Route im Kernel.
Lösung in Compose: Du musst das Subnetz von Compose hart umbiegen (z. B. auf abstruse IPs wie 10.254.x.x).
networks:
default:
ipam:
config:
- subnet: 10.254.1.0/24
Macvlan in Compose (Raw Layer 2)
Braucht dein Container eine echte DHCP-IP aus dem LAN deines physischen Routers (z. B. FritzBox)? (Oft für Smart Home wie HomeAssistant oder PiHole). Hierbei versagt Bridge, da es NAT nutzt. Compose unterstützt den Macvlan-Treiber.
networks:
lan:
driver: macvlan
driver_opts:
parent: eth0 # Das physische Interface des Hosts
Der Container hängt nun effektiv "physikalisch" am Router. Das Tückische ("Macvlan 802.1q Limitation"): Aus Sicherheitsgründen im Linux-Kernel kann der Host-Server seinen eigenen Macvlan-Container nun nicht mehr anpingen! Die Kommunikation zwischen Host und Container ist abgeschnitten, während das restliche LAN fehlerfrei kommuniziert.
5. Prüfen
Gehen Ports (
80:80) durch das Netzwerk?Nein. Ports (ports) mappen vom Host in den Container. Das Netzwerk verbindet Container untereinander. Für Container-zu-Container Kommunikation brauchst du keine Ports öffnen! Nur für Host-zu-Container.Was ist
host.docker.internal?Ein spezieller DNS-Name (auf Mac/Windows), damit der Container den Host erreichen kann ("Localhost vom Host"). Unter Linux standardmäßig nicht da (muss man mitextra_hostsenabled).Warum "Project Name"?
Compose präfixiert alles mit dem Ordnernamen (myproject_network). Damit kannst du das gleiche Projekt 2x im gleichen Docker Daemon starten (in 2 Ordnern), ohne dass die Netze kollidieren.
Zusammenfassung
- Früher (mit docker run) musste man Container manuell verbinden (--link). Das war schrecklich. Docker Compose macht das automatisch. Wenn du eine docker-compose.yml startest, erstellt Docker ein neues, isoliertes Netzwerk für dieses Projekt. Der Projektname...
- Standardmäßig musst du gar nichts konfigurieren. Aber manchmal willst du spezielle Netzwerke.
Optionale Praxisaufgabe
- Erkläre Docker Compose Networks in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Compose Networks relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 15 / 35
Docker Network
Container-Netzwerke kontrolliert verwenden.
S2
Schritt 15 / 35
Docker Network
Container-Netzwerke kontrolliert verwenden.
1. Verstehen
Container müssen reden. Mit dem Internet (Updates laden). Mit dem Host (Webseite anzeigen). Miteinander (App <-> Datenbank). Docker Network ist das Stecksystem dafür. Du kannst "Kabel ziehen" (virtuell). Standardmäßig steckt jeder Container im "Bridge" Netzwerk. Du kannst aber eigene Netzwerke bauen. Oder Container direkt ans Internet hängen ("Host"). Oder Container verbinden, die auf verschiedenen Servern liegen ("Overlay"). Ohne Netzwerk ist ein Container taubstumm und einsam.
Merksatz: Das Subsystem von Docker, das die Kommunikation zwischen Containern, dem Host und externen Netzwerken über verschiedene Treiber (Bridge, Host, Overlay, Macvlan) steuert.
Ein Host Network entfernt die übliche Container-Netzwerkisolation teilweise und sollte deshalb nur bewusst genutzt werden. Für lokale Preview-Setups ist meist ein benanntes Bridge-Netz mit klar veröffentlichten Ports sicherer.
2. Anwenden
Das Schweizer Taschenmesser: docker network.
- Listen:
docker network ls. - Inspect:
docker network inspect bridge. (Zeigt IPs aller Container). - Create:
docker network create mein-netz. - Connect:
docker network connect mein-netz laufender-container. (Wie ein Kabel im laufenden Betrieb einstecken!). - Disconnect:
docker network disconnect bridge container.
Praxisroutine
In der Praxis lernst du Docker Network, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. CNM vs. CNI
Docker nutzt das CNM (Container Network Model) mit libnetwork.
Kubernetes nutzt CNI (Container Network Interface).
Das ist ein historischer Streit ("Network Wars").
Docker's Modell ist flexibler für Endnutzer (Connect/Disconnect zur Laufzeit möglich).
Kubernetes' Modell ist einfacher für Maschinen (Pod hat 1 IP, fertig).
In Kubernetes werden Docker-Netzwerke oft komplett ignoriert und durch CNI-Plugins (Calico, Flannel) ersetzt.
2. IPAM (IP Address Management)
Wer entscheidet, dass dein Container 172.17.0.2 bekommt?
Der IPAM Driver.
Er verwaltet den Pool (Subnet).
Du kannst ihn zwingen:
docker network create --subnet=192.168.5.0/24 mein-netz.
Wichtig in Firmen-Netzwerken, um Kollisionen mit dem echten LAN zu vermeiden.
3. Overlay Networks (Swarm)
Wenn Container auf zwei verschiedenen Servern laufen, hilft eine Bridge nicht (sie endet am Kabel). Das Overlay Network (VXLAN) spannt einen Tunnel über das echte Netzwerk. Server A verpackt das Container-Paket in ein UDP-Paket, schickt es an Server B. Server B entpackt es. Container A denkt, er wäre im gleichen LAN wie Container B. Erfordert einen Key-Value Store (Consul/Etcd) oder Swarm Mode für die Synchronisation.
4. Vertiefen
Anatomie der Docker Bridge (docker0)
Wenn du Docker auf Linux startest, greift der Docker Daemon tief ins Betriebssystem ein. Er legt das Interface docker0 an. Das ist ein Software-Switch (Virtual Bridge).
Ein gestarteter Container bekommt sein eigenes virtuelles Netzwerk-Interface (eth0). Docker verbindet dieses per veth-pair (Virtual Ethernet Cable) mit der docker0 Bridge.
Tippst du ip link auf deinem Host, siehst du hunderte Interfaces der Sorte veth123abc – das sind die Gegenstücke der freischwebenden Kabel, die in die Container führen.
Die Bridge leitet Pakete zwischen Containern auf Layer 2 (MAC-Adresse) weiter.
Die DOCKER-USER iptables Chain
Die meisten glauben: "Was nicht publiziert (-p 80:80) wird, sieht das Internet nicht." Falsch. Docker hext im Hintergrund extrem mit Linux Netfilter / iptables.
Wenn Docker startet, schreibt es SNAT (Masquerading) Regeln in die iptables, damit Container ins Internet kommen.
Noch tückischer: Docker fügt in der FORWARD Chain Regeln ein, die den normalen ufw (Uncomplicated Firewall) oder firewalld des Hosts umgehen. Das bedeutet: Auch wenn deine Host-Firewall an Port 80 dicht macht, knallt Docker eine Erlaubnis obendrüber, wenn du -p 80:80 benutzt.
Die DOCKER-USER Chain ist der einzige offizielle Ort in iptables, wo Sysadmins eigene Block-Regeln platzieren dürfen, die von Docker respektiert und nicht überschrieben werden.
Overlay Networking & VXLAN-Header
Um Swarm-Knoten zu vernetzen, packt Docker Layer-2 Frames (MAC-Adressiert für den internen Container-Traffic) in normale Layer-4 UDP-Pakete (meist Port 4789). Das nennt sich VXLAN (Virtual eXtensible Local Area Network). Das bedeutet aber Overhead. Jedes Paket bekommt ca. 50 Byte VXLAN-Header angehängt. In High-Bandwidth-Netzwerken (Datenbank-Replikation über Gbit-Links) muss man die MTU der Container-Interfaces reduzieren (z. B. auf 1450), damit die verpackten VXLAN-Pakete nicht die physikalische 1500er Grenze crashen und fragmentieren, was massiven Paketverlust und hohe Latenzen verursachen kann.
5. Prüfen
Was ist
noneNetwork?--network none. Der Container hat nur Loopback (lo). Kein Internet, kein LAN. Maximale Isolation. Perfekt für Batch-Jobs, die sensible Daten verarbeiten und nichts leaken dürfen.Hairpin NAT?
Ein Problem, wenn ein Container versucht, seine eigene öffentliche IP anzusprechen. Viele Router blockieren das ("Loopback"). Docker richtet iptables so ein, dass es funktioniert (Hairpin Mode auf der Bridge).Kann ich feste IPs vergeben?
Ja (--ip 172.18.0.22), aber NUR in User-Defined Networks. Im Default-Bridge-Netzwerk ist DHCP (Zufall) erzwungen.
Zusammenfassung
- Container müssen reden. Mit dem Internet (Updates laden). Mit dem Host (Webseite anzeigen). Miteinander (App Datenbank). Docker Network ist das Stecksystem dafür. Du kannst "Kabel ziehen" (virtuell). Standardmäßig steckt jeder Container im "Bridge" Netzwerk....
- Das Schweizer Taschenmesser: docker network.
Optionale Praxisaufgabe
- Erkläre Docker Network in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Network relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
IP Address S1
Überblick: Eine IP-Adresse ist die eindeutige Wohnadresse eines Geräts in einem Computernetzwerk. Stell dir vor, du möchtest deinem Freund einen Brief schreiben. Wenn du nur "An Tom" draufschreibst, kommt der Brief nie an. Du brauchst Straße, Hausnummer und Postleitzahl.
Einfach erklärt: Im Alltag begegnen dir zwei Arten von IPs, die oft verwechselt werden:
Warum hat dein Laptop zu Hause meist eine IP, die mit
192.168...anfängt?Das ist ein reservierter Bereich für private Netzwerke (RFC1918). Diese IPs werden im Internet nicht geroutet.Was ist der Unterschied zwischen
127.0.0.1und deiner öffentlichen IP?127.0.0.1bist nur du (interner Monolog). Deine öffentliche IP ist deine Adresse für die Außenwelt.Warum brauchen wir IPv6 wirklich dringend?
Weil wir mehr als 4 Milliarden Geräte haben (Handys, IoT, Autos). IPv4 ist mathematisch am Ende.
Overlay Network S3
Überblick: Du hast zwei Server in verschiedenen Rechenzentren (oder Clouds). Sie können sich nur über das öffentliche Internet erreichen. Du willst aber, dass die Container auf Server A und Server B so tun, als wären sie im gleichen Raum (LAN). Du baust ein Overlay Network. Das ist ein virtueller Tunnel. Der Container schickt ein Paket an "10.0.0.5". Der Server verpackt dieses Paket in ein normales Internet-Paket (UDP), schickt es an Server B. Server B packt es aus und gibt es an Container B. Für die Container sieht alles flach und einfach aus. Die komplexe Realität (Router, Internet) wird "überlagert" (Overlay).
Einfach erklärt: In Docker Swarm / Kubernetes ist das Standard. docker network create -d overlay my-net. Wenn du das machst, können Container auf verschiedenen Hosts miteinander sprechen. Der User (Entwickler) merkt nicht, dass da Tunneling passiert. Er pingt einfach den Hostnamen.
Underlay?
Das physische Netzwerk (Kabel, Switches, echte IPs). Das Overlay liegt auf dem Underlay. Wenn das Underlay kaputt ist (Kabel durchgeschnitten), geht das Overlay auch nicht.Warum UDP?
TCP-in-TCP Tunneling ("TCP Meltdown") ist katastrophal. Wenn das innere Paket verloren geht, wiederholt der innere TCP-Stack. Wenn das äußere auch wiederholt, potenziert sich die Latenz. Deshalb nutzt man für Tunnel immer UDP (Fire & Forget).Geneve Protokoll?
Der Nachfolger von VXLAN. Flexibler für Metadaten (Security Policies, Tracing IDs). Wird von OVN (Open Virtual Network) und modernen Clouds genutzt.
Host Network S2
Überblick: Normalerweise leben Container in ihrer eigenen Blase (eigenes Netzwerk, eigene IP). Mit Host Network platzt die Blase. Der Container teilt sich die Netzwerkkarte direkt mit dem Computer (Host), auf dem er läuft. Er bekommt keine eigene IP-Adresse. Wenn der Container Port 80 öffnet, ist Port 80 auf dem Host offen. Es ist so, als würdest du das Programm direkt auf dem Server installieren, ohne Container-Netzwerk dazwischen. Es ist extrem schnell (kein Overhead), aber gefährlich (Port-Konflikte).
Einfach erklärt: Docker: docker run --network host nginx Versuche mal, zwei davon zu starten. Der zweite wird crashen: "Address already in use". Warum? Weil Port 80 auf dem Host nur einmal existiert. Bei Bridge-Netzwerken ginge das (jeder Container hat eigene IP).
Funktioniert DNS?
Ja, aber anders. Der Container nutzt/etc/resolv.confvom Host. Er kann keine Kubernetes-Services (db.default.svc) mehr auflösen (außer man biegt DNS manuell um), weil er nicht mehr im Pod-Netzwerk ist.Unterschied zu Port Mapping (
-p 80:80)?Bei Port Mapping ist der Container isoliert, nur ein Port wird durch die Firewall gebohrt (Loch). Bei Host Network ist die ganze Wand weg. Port Mapping ist für Apps, Host Network für Infrastruktur.Mac/Windows?
Auf Docker Desktop (Mac/Win) funktioniert--network hostNICHT so wie unter Linux. Der Container landet im Netz der Linux VM, nicht auf deinem Windows-Laptop. Port 80 ist dann auf dem Laptop nicht erreichbar. Das verwirrt jeden Anfänger.
Schritt 16 / 35
Bridge Network
Das Standardnetzwerk von Docker einordnen.
S2
Schritt 16 / 35
Bridge Network
Das Standardnetzwerk von Docker einordnen.
1. Verstehen
Wenn du Docker installierst, willst du nicht, dass jeder Container direkt im Internet hängt. Du willst ein privates Netzwerk für deine Container. Das Bridge Network ist der Standard ("Default"). Es ist wie ein virtueller Switch (Verteiler) innerhalb deines PCs. Alle Container, die an dieser Bridge hängen, können miteinander reden (über IP), sind aber von außen (LAN/Internet) erstmal isoliert. Der Docker-Daemon spielt den Router (NAT), damit die Container trotzdem ins Internet kommen (z. B. Updates laden), aber das Internet nicht in den Container.
Merksatz: Der Standard-Netzwerktreiber in Docker, der ein privates, internes Netzwerk auf dem Host erstellt, über das Container untereinander kommunizieren können, während sie per NAT Zugriff nach außen erhalten.
2. Anwenden
Jeder Container landet automatisch im Netzwerk bridge.
Man sieht es mit: docker network ls.
Aber Achtung: Im "Default Bridge" Network funktioniert DNS nicht gut (man kann Container nicht per Namen anpingen).
Best Practice: Erstelle ein User-Defined Bridge Network.
docker network create mein-netz
docker run --network mein-netz --name db mysql
docker run --network mein-netz --name app my-app
Jetzt kann die App einfach ping db machen. Docker löst "db" automatisch in die richtige IP auf.
Keine harten IP-Adressen nötig!
Praxisroutine
In der Praxis lernst du Bridge Network, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. vEth Pairs & Linux Bridge
Auf Kernel-Ebene erstellt Docker für jeden Container ein vEth Pair (Virtual Ethernet).
Ein Ende steckt im Container (eth0), das andere Ende steckt im Host (veth123abc).
Alle Host-Enden werden in einen virtuellen Switch (Linux Bridge docker0) gesteckt.
Wenn Paket A zu B will:
Container A -> eth0 -> vethA -> Bridge (Switching) -> vethB -> eth0 -> Container B.
Das passiert alles im Kernel auf Layer 2 (Data Link). Sehr schnell.
2. NAT & Port Forwarding
Wie kommt der Container ins Internet?
Über Masquerading (NAT).
Die Bridge routet Pakete an das Host-Interface (eth0 vom PC).
iptables ändert die Absender-IP (Source NAT) auf die Host-IP.
Rückweg: Wenn ich docker run -p 8080:80 mache, erstellt Docker eine DNAT Regel (Destination NAT).
"Alles was auf Host Port 8080 ankommt, weiterleiten an Container IP:80".
Achtung: docker-proxy Prozess läuft im User-Space als Fallback, aber iptables macht die Hauptarbeit.
3. Isolation & Security
Container im gleichen Bridge-Netzwerk vertrauen sich oft blind ("Alle Ports offen"). Wenn ein Hacker den Web-Container übernimmt, kann er die Datenbank scannen (Lateral Movement). In Kubernetes nutzt man deshalb Network Policies, um Bridges einzuschränken ("Web darf nur DB Port 5432 sprechen").
4. Vertiefen
Anatomie der iptables Rules
Wenn du Docker startest, übernimmt es Teile deiner Linux Firewall (iptables / nftables).
Ein tiefes Verständnis der DOCKER-USER Chain ist wichtig, um nicht versehentlich Ports freizulegen.
Eine Standard-Bridge verbietet per Default Traffic von außen und nutzt MASQUERADE für den Outbound-Traffic der Container.
Wenn du docker run -p 8080:80 machst, fügt Docker in der PREROUTING-Table eine DNAT-Regel hinzu.
Vorsicht: Docker umgeht oft die Standard UFW (Uncomplicated Firewall) von Ubuntu! Wenn du in UFW Port 8080 verbietest, Docker aber auf 8080 bindet (-p 8080:80), bleibt der Port von außen oftmals trügerischerweise offen, da Dockers iptables-Regeln vor den UFW-Regeln greifen.
MAC Address Flapping und Switch-Verwirrung
Docker nutzt intern virtuelle Interfaces (veth123). Da die Bridge "switching" betreibt, sieht der physische Switch beim Rechenzentrum (z.B. Hetzner) manchmal verschiedene MAC-Adressen von derselben Netzwerkkartenschnittstelle kommen.
Manche RZ-Switches klassifizieren das als "MAC Spoofing" oder "Arp Poisoning" und schalten den Switchport ab – der Server ist komplett offline.
Das war der Grund, warum Hetzner lange Zeit Docker-Installationen mit spezifischen Bridge-Setups restriktiv behandelte, bevor Workarounds implementiert wurden.
Hairpin NAT (NAT Reflection)
Kann ein Container seine eigene Host-IP ansprechen?
Angenommen, Container A (172.17.0.2) ist auf Host 1.2.3.4 an Port 80 gebunden.
Nun ruft Container A selbst curl http://1.2.3.4:80 auf.
Das Paket verlässt die Bridge, erreicht das externe Interface, muss dort die DNAT-Regel "bemerken" und scharf wenden (Hairpin), um zurück in die Bridge zu Container A zu fließen.
Docker muss dafür spezielles Hairpin-NAT aktivieren, was in komplexen Setups (oder wenn man an sysctl.conf dreht) oft zerbricht. Ohne Hairpining können Microservices sich nicht über die externe Public-URL finden.
5. Prüfen
Unterschied zu Host Network?
Beim Host Network (--network host) bekommt der Container keine eigene IP. Er nutzt direkt die IP des Hosts. Schneller (kein NAT), aber Port-Konflikte (nur ein Container kann Port 80 haben). Bridge ist sicherer und flexibler.Kann ich Bridges verbinden?
Nicht direkt. Du musst Routing einrichten. Oder einfacher: Hänge einen Container in zwei Netzwerke (docker network connect netz2 container1).Macvlan?
Eine Alternative zur Bridge. Der Container bekommt eine echte MAC-Adresse und wirkt wie ein physisches Gerät im LAN. Nützlich für Legacy-Apps, die Layer-2-Sichtbarkeit brauchen.
Zusammenfassung
- Wenn du Docker installierst, willst du nicht, dass jeder Container direkt im Internet hängt. Du willst ein privates Netzwerk für deine Container. Das Bridge Network ist der Standard ("Default"). Es ist wie ein virtueller Switch (Verteiler) innerhalb deines...
- Jeder Container landet automatisch im Netzwerk bridge. Man sieht es mit: docker network ls. Aber Achtung: Im "Default Bridge" Network funktioniert DNS nicht gut (man kann Container nicht per Namen anpingen). Best Practice: Erstelle ein User-Defined Bridge...
Optionale Praxisaufgabe
- Erkläre Bridge Network in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Bridge Network relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
IP Address S1
Überblick: Eine IP-Adresse ist die eindeutige Wohnadresse eines Geräts in einem Computernetzwerk. Stell dir vor, du möchtest deinem Freund einen Brief schreiben. Wenn du nur "An Tom" draufschreibst, kommt der Brief nie an. Du brauchst Straße, Hausnummer und Postleitzahl.
Einfach erklärt: Im Alltag begegnen dir zwei Arten von IPs, die oft verwechselt werden:
Warum hat dein Laptop zu Hause meist eine IP, die mit
192.168...anfängt?Das ist ein reservierter Bereich für private Netzwerke (RFC1918). Diese IPs werden im Internet nicht geroutet.Was ist der Unterschied zwischen
127.0.0.1und deiner öffentlichen IP?127.0.0.1bist nur du (interner Monolog). Deine öffentliche IP ist deine Adresse für die Außenwelt.Warum brauchen wir IPv6 wirklich dringend?
Weil wir mehr als 4 Milliarden Geräte haben (Handys, IoT, Autos). IPv4 ist mathematisch am Ende.
Host Network S2
Überblick: Normalerweise leben Container in ihrer eigenen Blase (eigenes Netzwerk, eigene IP). Mit Host Network platzt die Blase. Der Container teilt sich die Netzwerkkarte direkt mit dem Computer (Host), auf dem er läuft. Er bekommt keine eigene IP-Adresse. Wenn der Container Port 80 öffnet, ist Port 80 auf dem Host offen. Es ist so, als würdest du das Programm direkt auf dem Server installieren, ohne Container-Netzwerk dazwischen. Es ist extrem schnell (kein Overhead), aber gefährlich (Port-Konflikte).
Einfach erklärt: Docker: docker run --network host nginx Versuche mal, zwei davon zu starten. Der zweite wird crashen: "Address already in use". Warum? Weil Port 80 auf dem Host nur einmal existiert. Bei Bridge-Netzwerken ginge das (jeder Container hat eigene IP).
Funktioniert DNS?
Ja, aber anders. Der Container nutzt/etc/resolv.confvom Host. Er kann keine Kubernetes-Services (db.default.svc) mehr auflösen (außer man biegt DNS manuell um), weil er nicht mehr im Pod-Netzwerk ist.Unterschied zu Port Mapping (
-p 80:80)?Bei Port Mapping ist der Container isoliert, nur ein Port wird durch die Firewall gebohrt (Loch). Bei Host Network ist die ganze Wand weg. Port Mapping ist für Apps, Host Network für Infrastruktur.Mac/Windows?
Auf Docker Desktop (Mac/Win) funktioniert--network hostNICHT so wie unter Linux. Der Container landet im Netz der Linux VM, nicht auf deinem Windows-Laptop. Port 80 ist dann auf dem Laptop nicht erreichbar. Das verwirrt jeden Anfänger.
Overlay Network S3
Überblick: Du hast zwei Server in verschiedenen Rechenzentren (oder Clouds). Sie können sich nur über das öffentliche Internet erreichen. Du willst aber, dass die Container auf Server A und Server B so tun, als wären sie im gleichen Raum (LAN). Du baust ein Overlay Network. Das ist ein virtueller Tunnel. Der Container schickt ein Paket an "10.0.0.5". Der Server verpackt dieses Paket in ein normales Internet-Paket (UDP), schickt es an Server B. Server B packt es aus und gibt es an Container B. Für die Container sieht alles flach und einfach aus. Die komplexe Realität (Router, Internet) wird "überlagert" (Overlay).
Einfach erklärt: In Docker Swarm / Kubernetes ist das Standard. docker network create -d overlay my-net. Wenn du das machst, können Container auf verschiedenen Hosts miteinander sprechen. Der User (Entwickler) merkt nicht, dass da Tunneling passiert. Er pingt einfach den Hostnamen.
Underlay?
Das physische Netzwerk (Kabel, Switches, echte IPs). Das Overlay liegt auf dem Underlay. Wenn das Underlay kaputt ist (Kabel durchgeschnitten), geht das Overlay auch nicht.Warum UDP?
TCP-in-TCP Tunneling ("TCP Meltdown") ist katastrophal. Wenn das innere Paket verloren geht, wiederholt der innere TCP-Stack. Wenn das äußere auch wiederholt, potenziert sich die Latenz. Deshalb nutzt man für Tunnel immer UDP (Fire & Forget).Geneve Protokoll?
Der Nachfolger von VXLAN. Flexibler für Metadaten (Security Policies, Tracing IDs). Wird von OVN (Open Virtual Network) und modernen Clouds genutzt.
NAT (Network Address Translation) S2
Überblick: Die Welt hat zu wenig IPv4-Adressen. Dein Haus hat nur eine echte IP (vom Provider). Aber du hast 10 Geräte (Handy, Laptop, TV). Wie surfen alle gleichzeitig? Der Router macht NAT. Er ist der Postbote. Die Geräte haben interne IPs (192.168.x.x - Private Adressen). Wenn das Handy Google aufruft, tauscht der Router den Absender ("Handy") gegen "Ich (Router)" aus. Google antwortet an den Router. Der Router schaut in sein Notizbuch ("Wer wollte Google? Ah, das Handy!") und leitet das Paket weiter. Nach außen sieht es so aus, als ob alle Geräte ein Gerät wären.
Einfach erklärt: In Docker/K8s ist NAT allgegenwärtig ("Masquerading"). Wenn ein Container (172.17.0.2) nach draußen will (curl google.com), muss der Host-Linux-Kernel NAT machen. Befehl: iptables -t nat -L. Regel: MASQUERADE. Bedeutet: "Verstecke den Container hinter der IP des Hosts." Ohne NAT würde Google versuchen, an "172.17.0.2" zu antworten. Diese Adresse ist aber im Internet nicht routingfähig - Timeout.
Braucht IPv6 NAT?
Nein! IPv6 hat so viele Adressen, dass jeder Toaster eine eigene, öffentliche IP haben kann. End-to-End Connectivity ist wiederhergestellt. NAT ist ein "Hack" für das IPv4-Problem.Was ist "Hairpin NAT"?
Wenn ich von intern meine eigene externe IP aufrufe. Das Paket geht zum Router und muss "in der Haarnadelkurve" wieder zurück ins LAN. Viele billige Router können das nicht.Warum ist NAT eine "Firewall"?
Nebeneffekt: Von außen kommt niemand rein (außer auf Antwort-Pakete). Wer deine interne IP nicht kennt und kein Port-Forwarding hat, prallt am Router ab. Das ist ein Sicherheits-Feature "by accident".
Schritt 17 / 35
Bind Mount
Lokale Ordner in Container einhaengen.
S2
Schritt 17 / 35
Bind Mount
Lokale Ordner in Container einhaengen.
1. Verstehen
Container sind standardmäßig isoliert. Sie sehen deine Festplatte nicht. Manchmal willst du aber eine Datei von deinem PC in den Container spiegeln. Zum Beispiel: Du entwickelst eine Webseite. Der Webserver läuft im Container. Der Code liegt auf deinem Desktop. Ein Bind Mount bohrt ein Loch in den Container und "bindet" einen Ordner von deinem Host-PC an einen Ordner im Container. Wenn du auf dem PC die Datei änderst, sieht der Container sofort die Änderung. Es ist wie ein magisches Fenster zwischen zwei Welten.
Merksatz: Eine Methode in Docker, um eine Datei oder ein Verzeichnis vom Host-System direkt in einen Container einzublenden (zu mounten), wobei Änderungen auf beiden Seiten sofort wirksam sind.
2. Anwenden
Beim Starten des Containers:
docker run -v /home/user/projekt:/app nginx
/home/user/projekt: Pfad auf deinem PC (Host)./app: Pfad im Container. Der Inhalt von/appwird überdeckt durch den Inhalt deines Projekts.
In Docker Compose (Standard für Entwicklung):
services:
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html
Sobald du index.html speicherst, reloadet der Browser (Live Reload).
Praxisroutine
In der Praxis lernst du Bind Mount, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Performance & Filesystem Events
Bind Mounts sind langsam, besonders auf Mac/Windows.
Docker läuft dort in einer VM (Linux). Jede Dateiänderung muss über die Grenze (Hypervisor) synchronisiert werden (VirtioFS, gRPC FUSE).
Bei 10.000 Dateien (z. B. node_modules) wird npm install extrem langsam.
Lösung: Named Volumes für node_modules nutzen (Hack: "Volume Trick"), damit diese nicht synchronisiert werden.
2. Permissions (Die Hölle)
Auf Linux haben Dateien User-IDs (UID 1000).
Im Container läuft der Prozess oft als Root (UID 0).
Wenn der Container eine Datei schreibt, gehört sie plötzlich root auf deinem Host-PC. Du kannst sie nicht mehr löschen (Permission Denied).
Lösung: User-Remapping (user: "${UID}:${GID}" in Compose) oder Podman (Rootless Containers).
3. Security Implication
Bind Mounts erlauben dem Container Zugriff auf den Host.
Wenn du -v /:/host mountest, kann der Container dein ganzes Betriebssystem löschen.
In Production sind Bind Mounts daher oft verboten (Security Risk). Man nutzt dort Docker Volumes (verwaltet von Docker, liegen sicher in /var/lib/docker).
4. Vertiefen
VirtioFS und gRPC FUSE (Mac & Windows)
Unter Linux ist ein Bind Mount trivial: Cgroups und Namespaces mappen den Inode auf dem Host direkt in den Container. Fast null Overhead.
Auf macOS und Windows läuft Docker aber in einer leichtgewichtigen Linux-VM.
Ein Bind Mount muss also die Grenze von macOS-Dateisystem (APFS) zu Linux (ext4) überwinden.
Früher nutzte Docker dafür osxfs, was bei vielen kleinen Dateien (node_modules) extrem langsam war. Heute nutzt es gRPC FUSE oder (noch neuer) VirtioFS.
VirtioFS teilt den Host-Speicher auf Page-Ebene (Shared Memory) mit der VM, anstatt ihn über ein Netzwerkprotokoll zu synchronisieren. Das beschleunigt I/O-Heavy Server-Setups (wie PHP Symfony oder Ruby on Rails) dramatisch.
Das UID/GID Mapping Problem
Das größte Frustpotenzial auf Linux. Wenn du einen Host-Ordner ~/projekt bind-mountest und der Container läuft intern als User root (UID 0), dann haben alle von ihm erstellten Logs und Dateien auf deinem Host-PC plötzlich root-Rechte.
Mit sudo chown ... reparierst du das ständig.
Die Profi-Lösung: User Namespaces.
Docker mappt den internen root User (UID 0) auf eine ungefährliche, ungenutzte High-Number-UID auf dem Host (z.B. User 100000). Das bedeutet, der Container glaubt, er sei Root (darf also Pakete installieren), hat aber auf dem Host-System absolut keine Rechte. Dieses Feature ist essenziell für echte Multi-Tenant-Sicherheit, muss in der Docker-Daemon-Konfiguration aber hart aktiviert werden (userns-remap).
SELinux Contexts (:Z und :z)
Auf Systemen wie RHEL oder Fedora ist SELinux standardmäßig aktiv.
Wenn du $ docker run -v /var/data:/data postgres ausführst, wird PostgreSQL crashen.
SELinux verbietet dem Container den Zugriff auf den container_file_t Kontext.
Der Trick: Du musst das Suffix :Z (großes Z) anhängen.
docker run -v /var/data:/data:Z postgres.
Docker weist SELinux an, den Security-Kontext des Ordners /var/data umzuschreiben, sodass ihn genau dieser Container (Private, unshared) nutzen darf. Ein kleines :z würde es als "shared" deklarieren, sodass mehrere Container ihn gleichzeitig nutzen können.
5. Prüfen
Unterschied zu Volume?
Volume: Docker verwaltet den Speicherort (Blackbox). Bind Mount: Du bestimmst den Pfad (C:\Users\...). Volumes sind performanter und portabler. Bind Mounts sind bequemer für Entwicklung (Live-Edit).Was passiert, wenn der Host-Pfad nicht existiert?
Docker erstellt ihn automatisch als leeren Ordner (und zwar als Root). Das führt oft zu Verwirrung ("Warum ist mein Config-File ein Ordner?").Read-Only Mount?
Ja,-v ./config:/etc/config:ro. Der Container kann lesen, aber nicht schreiben. Gute Praxis für Konfigurationsdateien.
Zusammenfassung
- Container sind standardmäßig isoliert. Sie sehen deine Festplatte nicht. Manchmal willst du aber eine Datei von deinem PC in den Container spiegeln. Zum Beispiel: Du entwickelst eine Webseite. Der Webserver läuft im Container. Der Code liegt auf deinem...
- Beim Starten des Containers: docker run -v /home/user/projekt:/app nginx /home/user/projekt: Pfad auf deinem PC (Host). /app: Pfad im Container. Der Inhalt von /app wird überdeckt durch den Inhalt deines Projekts.
Optionale Praxisaufgabe
- Erkläre Bind Mount in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Bind Mount relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Dateisystem S1
Überblick: Ein Dateisystem organisiert Dateien und Ordner auf einem Speichergerät. Es merkt sich Namen, Pfade, Größen, Rechte und wo die Daten physisch liegen. Ohne Dateisystem wäre eine Festplatte nur ein großer ungeordneter Datenbereich.
Einfach erklärt: Wenn du eine Datei speicherst, kopierst, loeschst oder suchst, arbeitest du mit dem Dateisystem. Betriebssysteme nutzen Rechte, Pfade und Metadaten, um Zugriff zu steuern. In Servern und Containern sind Volumes, Mounts und Backups besonders wichtig.
Tiefer verstanden: Dateisysteme verwalten Blöcke, Inodes oder vergleichbare Metadatenstrukturen. Sie können Journaling, Snapshots, Quotas, Verschluesselung und Rechte unterstützen. Beispiele sind ext4, NTFS, APFS, XFS und ZFS.
Praxisgrenze: Dateien lokal im Webprozess zu speichern ist in skalierenden Systemen oft riskant. Der nächste Request kann auf einem anderen Server landen. Auch geloeschte Dateien, defekte Rechte, volle Partitionen und fehlende Backups sind typische Betriebsprobleme.
Was speichert ein Dateisystem ausser dem Inhalt?
Metadaten wie Name, Pfad, Größe, Zeitstempel und Rechte.Warum sind Backups wichtig?
Weil Dateisysteme gegen Bedienfehler, Defekte oder Angriffe nicht automatisch schützen.Was ist eine typische Serverfalle?
Uploads nur lokal abzulegen, obwohl mehrere Server oder Container beteiligt sind.
Tmpfs Mount (RAM Disk) S2
Überblick: Normalerweise schreiben Programme auf die Festplatte (HDD/SSD). Das ist langsam und überlebt einen Neustart. Manchmal willst du das Gegenteil: 1. Es soll extrem schnell sein (Cache). 2. Es soll sofort weg sein, wenn der Strom ausgeht (Passwörter). Dafür gibt es tmpfs. Du mountest einen Teil des RAMs (Arbeitsspeicher) als "Ordner". /mnt/ramdisk. Alles, was du da reinschreibst, landet nie auf dem Datenträger.
Einfach erklärt: Docker: docker run --tmpfs /app/cache nginx K8s: yaml volumes: - name: secrets emptyDir: medium: Memory Wenn der Container stoppt, sind die Daten sofort weg. Keine "Undelete" Tools können sie retten.
Performance Gewinn?
Dramatisch. RAM ist 100x schneller als SSD. Latenz im Nanosekunden-Bereich. Perfekt für temporäre Compile-Dateien oder Session-Caches.Unterschied zu Ramdisk?
Altmodische Ramdisks reservierten fix 1GB RAM. Wenn leer, war der RAM trotzdem weg.tmpfswächst und schrumpft dynamisch. Es belegt nur so viel RAM, wie Dateien drin sind./dev/shm?Shared Memory. Ein Standard-tmpfs in Linux, das Prozesse nutzen, um Speicherbereiche zu teilen (Inter Process Communication). Docker container haben oft ein zu kleines/dev/shm(64MB), was Chrome/PyTorch crashen lässt. Mount es größer!
Schritt 18 / 35
Docker Volume
Verwalteten Storage für Container nutzen.
S2
Schritt 18 / 35
Docker Volume
Verwalteten Storage für Container nutzen.
1. Verstehen
Container sind vergesslich. Wenn sie sterben, löscht Docker ihre Festplatte.
Docker Volumes sind das Gedächtnis.
Ein Volume ist ein spezieller Ordner, der außerhalb des Containers sicher verwahrt wird.
Der Container darf ihn benutzen ("mounten"), aber er gehört Docker.
Wenn du den Container löschst, bleibt das Volume da.
Du kannst es später einem neuen Container geben ("Hier sind deine alten Erinnerungen").
Im Gegensatz zu Bind Mounts (Pfad auf deinem Desktop) liegen Volumes in einem von Docker verwalteten Bereich (/var/lib/docker/volumes) und sind daher robuster und portabler.
Merksatz: Ein von Docker verwaltetes Dateisystemobjekt zur persistenten Datenspeicherung, das unabhängig vom Lebenszyklus eines Containers existiert und von mehreren Containern genutzt werden kann.
2. Anwenden
- Erstellen:
docker volume create mein-daten-topf. - Nutzen:
docker run -v mein-daten-topf:/app/data nginx. - Inspect:
docker volume inspect mein-daten-topf. (Zeigt den echten Pfad auf der Linux-Platte). - Löschen:
docker volume rm mein-daten-topf. (Geht nur, wenn kein Container es mehr benutzt!). - Aufräumen:
docker volume prune(Löscht alle ungenutzten Volumes. Vorsicht!).
Praxisroutine
In der Praxis lernst du Docker Volume, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Volume Plugins (REX-Ray, Portworx)
Der Standard-Treiber (local) speichert auf der lokalen Festplatte.
Das ist doof im Cluster (Swarm/K8s). Wenn der Container auf Server B umzieht, sind seine Daten noch auf Server A.
Volume Plugins lösen das.
Der Container sagt: "Ich brauche Volume X".
Das Plugin sagt: "Moment, ich hänge die AWS EBS Disk an Server B an und mounte sie."
Das ermöglicht "Stateful Microservices".
2. Copy-on-Write Verhalten
Wenn du ein leeres Volume in /usr/share/nginx/html mountest, kopiert Docker den Inhalt aus dem Image (die index.html) in das Volume.
Das ist super praktisch ("Populate Volume").
Wenn du aber einen Bind Mount nimmst, verdeckt ("overshadow") er den Ordner. Er ist leer. Nginx zeigt "403 Forbidden".
Das ist der häufigste Anfängerfehler beim Wechsel von Volume zu Bind Mount.
3. Backups
Wie sichere ich ein Volume?
Du kommst auf Mac/Windows nicht an /var/lib/docker/volumes ran (liegt in der VM).
Der offizielle Weg:
docker run --rm -v mein-volume:/data -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /data
Starte einen Hilfs-Container, mounte das Volume UND einen lokalen Ordner, und zippe die Daten rüber.
4. Vertiefen
Die Trennung von Base-Image und Volume
Man darf Storage / Graph Drivers (Overlay2, btrfs) nicht mit Volume Drivers (local, NFS, cloud) verwechseln.
Alle Änderungen, die ein Container ohne Volumes vornimmt (z. B. apt install oder Datei-Upload in /tmp), landen im "Container Layer" (verwaltet vom Storage Driver via Copy-on-Write).
Diese CoW-Architektur ist für Leseoperationen rasant, aber beim Schreiben extrem CPU- und I/O-hungrig, da Dateien vor der Manipulation erst aus unteren layern hochkopiert (Read-Modify-Write) werden müssen.
Dokumentierte Best Practice: Schreibintensive Anwendungen (PostgreSQL, Elasticsearch) müssen zwingend in ein Volume schreiben. Ein Volume umgeht den Storage Driver des Daemons völlig und schreibt direkt nativ auf das Host-Dateisystem, wodurch der Storage-I/O-Overhead entfällt und native NVMe/SSD Speeds ermöglicht werden.
NFS Volumes & UID Mapping Hell
Wenn Cluster (Swarm) Daten teilen müssen, ist "Local" tot. Oft rufen Teams NFS-Volumes ("Network File System") auf den Plan, z. B. NetApp Filer oder AWS EFS.
Du generierst Volumes durch Mount-Flags direkt: --opt type=nfs --opt o=addr=192.168.1.1,rw --opt device=:/path/to/dir.
Das massive Problem dabei ist Permission-Squashing / UID Mapping. Ein Alpine-Container greift als User root (UID 0) auf das NFS-Laufwerk zu. Der NFS-Server verbietet aus Sicherheit UID-0-Zugriffe (root_squash) und ändert den Besitzer auf nobody (meist UID 65534). Die Datenbank im Container verliert augenblicklich das Schreibrecht und stirbt mit "Permission Denied", was oftmals tagelanges Linux-Rechte-Debugging auslöst.
Volume Backup & Recovery Strategies (Immutable Data)
Volume Backups bedienen per Definition "Out-of-Band" Abläufe.
Da Docker keine Snapshot-APIs mitliefert (anders als VMware oder AWS für EBS), nutzen Admins "Tarballing" via Sidecar Container (z.B. den Officiellen Trick über docker run --rm --volumes-from <cid>).
In Produktion, insbesondere für Datenbanken, ist simples "Wegkopieren" fatal.
Eine Backup-Lösung darf niemals ein Volume per VFS komprimieren, während der Daemon aktiv Datenbank-Transactions dorthin flusht. Das Resultat ist "Torn Pages" (korrupte Blöcke). Der korrekte Life-Cycle lautet: Container stoppen oder Read-Only locken (z. B. Redis BGSAVE triggern), Datei kopieren/tar-en, und danach Unlocken. Bei distributed Storage-Backends übernimmt dies ein CSI Snapshot in Kubernetes.
5. Prüfen
Sind Volumes schneller als Bind Mounts?
Auf Linux nativ: Nein (beides gleich). Auf Mac/Windows: JA! Bind Mounts müssen durch das langsame osxfs/VirtioFS Dateisystem. Volumes liegen komplett in der Linux-VM und sind rasend schnell (Native Speed).Kann ich ein Volume mit 2 Containern gleichzeitig nutzen?
Ja. Beide können lesen und schreiben. Aber Vorsicht vor "Race Conditions" (Wer schreibt zuletzt?). Docker sperrt nichts. Die App muss das regeln.Dangling Volumes?
Volumes, die kein Container mehr nutzt. Sie fressen oft GB an Platz. Docker löscht sie nie automatisch (außer beiprune), weil "User Data is precious".
Zusammenfassung
- Container sind vergesslich. Wenn sie sterben, löscht Docker ihre Festplatte. Docker Volumes sind das Gedächtnis. Ein Volume ist ein spezieller Ordner, der außerhalb des Containers sicher verwahrt wird. Der Container darf ihn benutzen ("mounten"), aber er...
- Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
Optionale Praxisaufgabe
- Erkläre Docker Volume in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Volume relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Dateisystem S1
Überblick: Ein Dateisystem organisiert Dateien und Ordner auf einem Speichergerät. Es merkt sich Namen, Pfade, Größen, Rechte und wo die Daten physisch liegen. Ohne Dateisystem wäre eine Festplatte nur ein großer ungeordneter Datenbereich.
Einfach erklärt: Wenn du eine Datei speicherst, kopierst, loeschst oder suchst, arbeitest du mit dem Dateisystem. Betriebssysteme nutzen Rechte, Pfade und Metadaten, um Zugriff zu steuern. In Servern und Containern sind Volumes, Mounts und Backups besonders wichtig.
Tiefer verstanden: Dateisysteme verwalten Blöcke, Inodes oder vergleichbare Metadatenstrukturen. Sie können Journaling, Snapshots, Quotas, Verschluesselung und Rechte unterstützen. Beispiele sind ext4, NTFS, APFS, XFS und ZFS.
Praxisgrenze: Dateien lokal im Webprozess zu speichern ist in skalierenden Systemen oft riskant. Der nächste Request kann auf einem anderen Server landen. Auch geloeschte Dateien, defekte Rechte, volle Partitionen und fehlende Backups sind typische Betriebsprobleme.
Was speichert ein Dateisystem ausser dem Inhalt?
Metadaten wie Name, Pfad, Größe, Zeitstempel und Rechte.Warum sind Backups wichtig?
Weil Dateisysteme gegen Bedienfehler, Defekte oder Angriffe nicht automatisch schützen.Was ist eine typische Serverfalle?
Uploads nur lokal abzulegen, obwohl mehrere Server oder Container beteiligt sind.
Tmpfs Mount (RAM Disk) S2
Überblick: Normalerweise schreiben Programme auf die Festplatte (HDD/SSD). Das ist langsam und überlebt einen Neustart. Manchmal willst du das Gegenteil: 1. Es soll extrem schnell sein (Cache). 2. Es soll sofort weg sein, wenn der Strom ausgeht (Passwörter). Dafür gibt es tmpfs. Du mountest einen Teil des RAMs (Arbeitsspeicher) als "Ordner". /mnt/ramdisk. Alles, was du da reinschreibst, landet nie auf dem Datenträger.
Einfach erklärt: Docker: docker run --tmpfs /app/cache nginx K8s: yaml volumes: - name: secrets emptyDir: medium: Memory Wenn der Container stoppt, sind die Daten sofort weg. Keine "Undelete" Tools können sie retten.
Performance Gewinn?
Dramatisch. RAM ist 100x schneller als SSD. Latenz im Nanosekunden-Bereich. Perfekt für temporäre Compile-Dateien oder Session-Caches.Unterschied zu Ramdisk?
Altmodische Ramdisks reservierten fix 1GB RAM. Wenn leer, war der RAM trotzdem weg.tmpfswächst und schrumpft dynamisch. Es belegt nur so viel RAM, wie Dateien drin sind./dev/shm?Shared Memory. Ein Standard-tmpfs in Linux, das Prozesse nutzen, um Speicherbereiche zu teilen (Inter Process Communication). Docker container haben oft ein zu kleines/dev/shm(64MB), was Chrome/PyTorch crashen lässt. Mount es größer!
Schritt 19 / 35
Container Lifecycle
Start, Stop, Restart und Loeschung verstehen.
S1
Schritt 19 / 35
Container Lifecycle
Start, Stop, Restart und Loeschung verstehen.
1. Verstehen
Ein Container ist wie ein Lebewesen. Er wird geboren, arbeitet, schläft vielleicht, und stirbt. Den Programmierer interessiert vor allem der Tod:
- Stirbt er unerwartet? (Absturz -> Neustart nötig).
- Stirbt er geplant? (Update -> Graceful Shutdown).
Der Lifecycle beschreibt diese Phasen:
Created->Running->Paused->Exited(Stopped) ->Dead(Deleted). Zu verstehen, warum ein Container in welchem Zustand ist, ist die Basis für Debugging.
Merksatz: Die Abfolge von Zuständen, die ein Container von der Erstellung (Create) über die Ausführung (Run) bis zur Beendigung (Stop/Kill) und Entfernung (Rm) durchläuft.
2. Anwenden
Befehle für die Phasen:
docker create: Baut den Container, startet ihn aber nicht (Zustand: Created). Selten genutzt.docker start: Weckt ihn auf (Zustand: Running).docker run: Machtcreate+startin einem (Standard).docker stop: Sendet Signal "Bitte fertig werden". Nach 10s -> "Runterfahren" (Zustand: Exited).docker kill: Zieht den Stecker sofort (Zustand: Exited mit Fehlercode).docker rm: Löscht die Hülle (Garbage Collection).
Praxisroutine
In der Praxis lernst du Container Lifecycle, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Signals (SIGTERM vs. SIGKILL)
Das wichtigste Konzept für Ops.
Wenn du stop drückst, sendet Docker SIGTERM (Signal 15) an PID 1.
Die App sollte das fangen (trap), offene Verbindungen schließen, Daten speichern und sich beenden exit(0).
Tut sie das nicht innerhalb der Grace Period (Default 10s), sendet Docker SIGKILL (Signal 9).
Das ist der "Hard Kill". Datenverlust möglich!
Häufiger Fehler: Nginx/Java ignoriert SIGTERM, weil es in einem Shell-Skript (entrypoint.sh) gewrappt ist und das Skript das Signal nicht weiterleitet ("PID 1 Problem").
2. Restart Policies
Was passiert nach dem Tod?
no: Bleib tot. (Standard).on-failure: Nur neu starten, wenn Exit Code != 0 (Crash).always: Immer neu starten (auch wenn ich manuellstopgedrückt habe! Docker Daemon Restart weckt ihn wieder).unless-stopped: Wie always, aber merkt sich, wenn ich manuell gestoppt habe. (Beste Wahl für Server).
3. Init Process (Tini)
Linux-Prozesse erwarten einen "Reaper" (Init System), der Zombie-Prozesse aufräumt.
Ein normaler Container hat kein systemd.
Wenn Prozesse sterben, bleiben sie als "Zombies" (<defunct>) in der Tabelle, bis PID 1 sie "erntet" (waitpid).
Wenn deine App das nicht tut, läuft die Prozess-Tabelle voll -> Server Crash.
Lösung: --init Flag in Docker (nutzt tini) oder Supervisord.
4. Vertiefen
1. PID 1 und das Zombie-Reaping Problem
In Linux-Systemen startet das Betriebssystem beim Boot einen Init-Prozess (oft systemd), der die magische PID 1 erhält. Er hat die harte Pflicht, verwaiste Kindprozesse (Zombies), die beendet sind, "einzusammeln" (Reaping), damit die Process Table im Kernel nicht vollläuft.
Ein Container hat kein systemd. Startet er per ENTRYPOINT ["npm", "start"], wird Node.js zur PID 1. Node hat oft keine Ahnung von Zombie-Reaping oder Signal-Handling für Sub-Prozesse.
Das führt zu Memory Leaks in Form von Process Descriptors. Abhilfe schafft die Option --init im Docker-Befehl (oder init: true in Docker Compose). Das spannt den winzigen C-Daemon tini als PID 1 vor deine App, der das Reaping perfekt übernimmt.
2. OOM-Killer (Exit Code 137)
Eines der gefürchtetsten Lifecycle-Events ist der gewaltsame Tod durch Erschöpfung des Speichers.
Überschreitet ein Container das ihm durch Cgroups diktierte RAM-Limit, wird der Linux Out Of Memory Killer (OOM-Killer) aktiv.
Er scannt die Prozesse, sucht den Container aus und schickt einen asynchronen SIGKILL (Signal 9). Die App hat keine Chance zur Gegenwehr, sie stirbt in Millisekunden. Der Container terminiert mit Exit Code 137 ($128 + 9$). Um solche Abstürze zu debuggen, hilft nur noch ein Memory Profiling der App (z.B. Heap Dumps in Java/Go) und die Lektüre der /var/log/syslog des Host-Systems.
3. Graceful Shutdown & Kubernetes PreStop Hooks
Wenn Kubernetes beschließt, einen Pod (Kubernetes) (Container) herunterzufahren, weil man eine neue Version veröffentlicht (Rolling Update), sendet es SIGTERM (Signal 15).
Das Backend (z.B. Go Server oder Spring Boot) muss den Graceful Shutdown implementieren:
- Sofort aufhören, neue HTTP-Anfragen vom Load Balancer anzunehmen.
- Den aktuellen (in-flight) Anfragen Zeit geben, ihre Datenbank-Transaktionen abzuschließen.
- Danach aktiv und sauber via
exit(0)sterben. In Kubernetes gibt es dazu sogenannte PreStop Hooks — Lebenszyklus-Hooks (Bash-Befehle), die garantiert ausgeführt werden, exakt bevor das SIGTERM-Signal abgefeuert wird, um z.B. einen Container gezielt aus dem internen DNS/Service-Registry abzumelden.
5. Prüfen
Was bedeutet Exit Code 137?
128 + 9 = 137. Das ist SIGKILL. Entweder hast dukillgedrückt, oder der OOM Killer (Out of Memory) hat den Prozess erschossen. Ein klassisches Indiz für Speicherprobleme.Was bedeutet Exit Code 0?
Erfolg. "Ich bin fertig und habe keine Fehler." Typisch für "One-Shot" Container (Batch Jobs), aber untypisch für Webserver (die sollten nie Exit 0 machen, außer beim Shutdown).Warum dauert
docker stopmanchmal genau 10 Sekunden?Weil deine App SIGTERM ignoriert. Docker wartet höflich 10s und tötet sie dann. Fixe dein Signal Handling im Code!
Zusammenfassung
- Ein Container ist wie ein Lebewesen. Er wird geboren, arbeitet, schläft vielleicht, und stirbt. Den Programmierer interessiert vor allem der Tod: Stirbt er unerwartet? (Absturz - Neustart nötig). Stirbt er geplant? (Update - Graceful Shutdown). Der Lifecycle...
- Befehle für die Phasen: 1. docker create: Baut den Container, startet ihn aber nicht (Zustand: Created). Selten genutzt. 2. docker start: Weckt ihn auf (Zustand: Running). 3. docker run: Macht create + start in einem (Standard). 4. docker stop: Sendet Signal...
Optionale Praxisaufgabe
- Erkläre Container Lifecycle in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Container Lifecycle relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Prozess S1
Überblick: Ein Prozess ist ein laufendes Programm. Wenn du einen Browser startest, erzeugt das Betriebssystem einen oder mehrere Prozesse. Jeder Prozess bekommt Speicher, Rechte und eine laufende Ausführung.
Einfach erklärt: Im Task-Manager oder mit ps unter Linux siehst du Prozesse. Dort erkennst du, welches Programm CPU, RAM oder Netzwerk nutzt. Wenn eine Anwendung hängt, beendet man oft den Prozess statt die ganze Maschine neu zu starten.
Tiefer verstanden: Ein Prozess hat einen eigenen virtuellen Adressraum, offene Dateien, Umgebungsvariablen, Rechte und mindestens einen Thread. Das Betriebssystem plant Prozesse über den Scheduler ein und wechselt zwischen ihnen per Context Switch.
Praxisgrenze: Prozesse isolieren Fehler besser als Threads, kosten aber mehr Speicher und Verwaltungsaufwand. In Servern entscheidet das Prozessmodell über Stabilität, Parallelität und Debugbarkeit. Container nutzen Prozess-Isolation, Namespaces und Cgroups, sind aber keine vollständigen virtuellen Maschinen.
Was ist ein Prozess?
Ein laufendes Programm mit eigenem Speicher, Rechten und Betriebssystemzustand.Warum sind Prozesse nützlich?
Sie isolieren Programme voneinander und machen Ressourcenverbrauch sichtbar.Was ist der Unterschied zu einem Thread?
Ein Thread läuft innerhalb eines Prozesses und teilt sich dessen Speicher mit anderen Threads.
RAM S1
Überblick: RAM ist das Kurzzeitgedächtnis deines Computers. Alles, was du gerade jetzt machst (diese Webseite lesen, Musik hören), liegt im RAM. Es ist extrem schnell, aber vergesslich. Sobald du den Strom ausschaltest, ist der RAM leer. Deshalb musst du deine Hausarbeit speichern (auf die Festplatte schreiben), bevor du den PC herunterfährst.
Einfach erklärt: Wie viel RAM brauchst du? 8 GB: Standard für Surfen und Office. 16 GB: Gut für Gaming und Fotobearbeitung. 32 GB+: Für Videoschnitt und Profi-Anwendungen.
Warum speichert man nicht einfach alles im RAM?
1. Weil alles weg wäre, wenn der Strom ausfällt. 2. Weil RAM viel teurer ist als SSD-Speicher (pro Gigabyte).Was bedeutet "Chrome frisst RAM"?
Jeder offene Tab in Chrome ist ein eigener Prozess. Das ist sicher (wenn einer abstürzt, lebt der Rest weiter), kostet aber viel Arbeitsspeicher.Was ist der Unterschied zu VRAM?
VRAM (Video RAM) sitzt auf der Grafikkarte. Er ist speziell dafür optimiert, riesige Texturen und 3D-Modelle für Spiele zu speichern.
Load Balancer S1
Überblick: Stell dir eine Supermarkt-Kasse vor. Wenn 100 Kunden an einer Kasse stehen, dauert es ewig. Die Kassiererin bricht zusammen. Ein Load Balancer ist der Mitarbeiter, der am Eingang steht: "Kasse 1 ist voll? Geh bitte zu Kasse 2. Kasse 2 voll? Kasse 3 ist frei!" Er verteilt die Last (Kunden) gerecht auf alle verfügbaren Ressourcen (Server). So stürzt kein Server ab, und alle Kunden werden schnell bedient.
Einfach erklärt: Webseiten wie Facebook haben nicht einen Server, sondern Tausende. Die Adresse facebook.com zeigt auf einen riesigen Load Balancer. Der schickt dich zu Server Nr. 4821 (der vielleicht gerade wenig zu tun hat). Wenn Server Nr. 4821 kaputt geht, merkt der Load Balancer das sofort ("Health Check") und schickt keine Kunden mehr hin. Du merkst nichts davon.
Brauche ich das für meinen Blog?
Nein. Ein Server schafft locker 1000 Besucher gleichzeitig. Load Balancer brauchst du, wenn du Millionen Hits hast (High Traffic).Was ist Hardware vs. Software LB?
Früher waren es teure Spezial-Geräte (F5 Big-IP). Heute macht man das meist per Software (Nginx, HAProxy) oder direkt in der Cloud (AWS ELB).Ist er ein Single Point of Failure?
Ja! Wenn der Verteiler ausfällt, kommt niemand mehr zu den Servern. Deshalb hat man meistens zwei Load Balancer, die sich gegenseitig überwachen (Failover).
Datenbank S1
Überblick: Eine Datenbank ist ein digitaler Aktenschrank, in dem Informationen extrem ordentlich sortiert sind. Stell dir eine Excel-Tabelle vor, aber viel mächtiger. Dort speichert Facebook alle deine Freunde. Amazon alle deine Bestellungen. Deine Bank alle Kontobewegungen. Ohne Datenbanken müsste man alles in Textdateien schreiben – und das Suchen würde ewig dauern.
Einfach erklärt: Die meisten Datenbanken nutzen eine Sprache namens SQL (Structured Query Language), um mit ihnen zu reden. Ein Befehl sieht so aus: SELECT FROM users WHERE age 18; ("Gib mir alle Benutzer, die älter als 18 sind").
Was ist der Unterschied zwischen einer Datenbank und einer Excel-Tabelle?
Excel ist für Menschen (visuell). Datenbanken sind für Computer (massiv skalierbar, multiuser-fähig, sicher). Excel stürzt bei 1 Mio. Zeilen ab, Datenbanken lachen darüber.Warum nutzt man nicht für alles NoSQL?
Weil SQL-Datenbanken (Tabellen) extrem gut darin sind, Beziehungen darzustellen ("Kunde hat Bestellung hat Artikel"). NoSQL ist flexibler, aber oft schlechter bei komplexen Verknüpfungen (Joins).Was passiert, wenn zwei Leute gleichzeitig denselben Datensatz ändern?
Die Datenbank sperrt ihn kurzzeitig ("Locking"). Einer muss warten, bis der andere fertig ist, damit keine Daten überschrieben werden (Concurrency Control).
Schritt 20 / 35
Container Isolation
Prozess-, Datei- und Netzwerkisolation einordnen.
S2
Schritt 20 / 35
Container Isolation
Prozess-, Datei- und Netzwerkisolation einordnen.
1. Verstehen
Viele Leute denken, Container sind wie "kleine virtuelle Server". Das stimmt nicht. Container sind Prozesse (wie Word oder Chrome) auf dem gleichen Betriebssystem wie alle anderen. Aber sie tragen eine "VR-Brille" (Namespaces) und Fesseln (cgroups). Die Isolation sorgt dafür, dass:
- Der Container denkt, er wäre allein auf der Welt (sieht keine anderen Prozesse).
- Er nicht auf Dateien außerhalb seines Ordners zugreifen kann.
- Er den Server nicht überlasten kann. Aber: Wenn der Linux-Kernel abstürzt (Kernel Panic), sterben alle Container. Bei einer VM (Virtual Machine) stirbt nur die eine VM. Container sind also "weniger isoliert" als VMs.
Merksatz: Die Trennung von Prozessen in Containern vom Host-System und anderen Containern durch Kernel-Features (Namespaces, cgroups), um Sicherheit und Ressourcen-Unabhängigkeit zu gewährleisten (Shared Kernel Architecture).
2. Anwenden
Standardmäßig ist Docker "ziemlich" sicher. Aber für echte Isolation (Multi-Tenant):
- User: Root vermeiden! Starte Container nie als
root(USER 1000im Dockerfile). - Read-Only Root FS: Verhindere, dass Malware Dateien ändert (
--read-only). - Capabilities droppen: Der Container braucht kein
NET_ADMIN(Netzwerk ändern). Nimm ihm die Rechte weg (--cap-drop ALL).
Praxisroutine
In der Praxis lernst du Container Isolation, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Die Illusion (Namespaces)
Der Kernel lügt den Prozess an.
- PID Namespace: Prozess 12345 auf dem Host sieht sich selbst als PID 1 im Container.
- Mount Namespace: Der Container sieht
/als sein Root, obwohl es auf dem Host/var/lib/docker/...ist. - Network Namespace: Eigener IP-Stack (
lo,eth0). Aber syscalls gehen direkt an den Host-Kernel! Es gibt keine "Hypervisor-Schicht".
2. Container Breakouts (Escape)
Wenn ich im Container Root bin und eine Lücke im Kernel finde (z. B. "Dirty Cow"), kann ich ausbrechen. Dann bin ich Root auf dem Host-Server. Game Over. Deshalb nutzt Google gVisor oder Kata Containers. Das sind "Micro-VMs", die jeden Container in eine echte kleine VM packen. Der Kernel wird nicht geteilt. Maximale Isolation auf Kosten von Performance.
3. Seccomp & AppArmor
Du kannst dem Kernel sagen: "Dieser Container darf nur read(), write() und exit() aufrufen. Wenn er reboot() ruft -> KILL."
Das ist Seccomp (Secure Computing Mode).
Docker hat ein Default-Profile, das gefährliche Syscalls blockiert.
AppArmor/SELinux legen noch eine Schicht Mandatory Access Control (MAC) oben drauf ("Darf Nginx auf /etc/passwd zugreifen? Nein, auch nicht als Root.").
4. Vertiefen
cgroups v1 vs. cgroups v2 (Control Groups)
Die Einschränkung von Ressourcen (CPU, RAM, Block I/O) obliegt den cgroups (Control Groups). Lange Zeit war cgroups v1 der Standard. Es war hochkomplex strukturiert; es erlaubte z. B., dass ein Prozess in Bezug auf CPU zu Gruppe A gehörte, in Bezug auf Speicher aber zu Gruppe B. Dies führte zu inkonsistentem Memory-Management (insbesondere OOMKills bei Swap), was den Kernel überforderte. Der moderne Standard (fast überall Default in Linux-Kerneln > 4.15) ist cgroups v2. V2 erzwingt eine strikte, einheitliche Hierarchie (Tree-Struktur). Ein Container ist exakt an einen Knotenpunkt im Baum für alle Ressourcentypen gebunden. Dies verbessert die Controller-Synchronisation im Kernel, erlaubt Container-Aware Speicher-Accounting und verhindert Freezes unter extremen Page-Cache Lasten.
Kata Containers & Firecracker (The MicroVM Pivot)
"Shared Kernel" bedeutet: Findet ein Hacker eine Privilege-Escalation im Linux-Socket oder Treiber-Subsystem, gehört ihm die Host-Machine und damit alle Container anderer Mieter. In Serverless-Umgebungen (AWS Fargate, Google Cloud Run) können Cloud-Anbieter diesen Multi-Tenant-Risk nicht eingehen. Sie verwerfen reine Linux Container-Namespaces zugunsten echter MicroVM-Kapselung wie AWS Firecracker oder den OS-Katalysator Kata Containers. Diese Systeme starten für jeden einzelnen Container eine stripped-down virtuelle Maschine. Der Hypervisor generiert echte PCI-Busse und Block-Devices pro KVM-Instanz. Da diese VMs einen extrem minimalen Footprint (Start in unter 50 Millisekunden) haben, verhalten sie sich auf DevOps-Automatisierungsebene identisch zu Containern, liefern aber hypervisor-backed Hardcore-Isolation.
eBPF (Cilium & Tetragon SecOps)
Da der Linux-Kernel den Flaschenhals und Single-Point-of-Failure für Isolation bildet, geht die moderne Sicherheit zunehmend in Richtung In-Kernel-Beobachtung mittels eBPF (Extended Berkeley Packet Filter).
Tools wie Tetragon überwachen alle Syscalls (z.B. execve, openat), die ein Container auf Kernel-Ebene vornimmt.
Wenn ein als Nginx deklarierter Container plötzlich versucht, ein Socket für eine unbekannte TCP-Verschlüsselung (crypt) zu registrieren, greift eBPF nicht im Userspace ein, sondern klemmt den Syscall hart auf unterster Kernel-Ebene ab, bevor überhaupt Memory allokiert wurde. Dies liefert quasi-Zero-Trust Echtzeit-Isolation, ohne Code rekompilieren zu müssen.
5. Prüfen
Sind Container so sicher wie VMs?
Nein. "Container don't contain". Der Shared Kernel ist ein Single Point of Failure. Für feindliche Multi-Tenancy (z. B. "Lasse Code von Fremden laufen") braucht man VMs (Firecracker/Kata).Was ist "Rootless Docker"?
Der Docker Daemon selbst läuft als normaler User (nicht Root). Selbst wenn man ausbricht, ist man auf dem Host nur ein User ohne Rechte. Großer Sicherheitsgewinn.Privileged Container?
--privileged. Gibt dem Container alle Capabilities und Zugriff auf alle Devices. Das hebt die Isolation effektiv auf. Mache das nie, außer du weißt exakt warum (z. B. Docker-in-Docker).
Zusammenfassung
- Viele Leute denken, Container sind wie "kleine virtuelle Server". Das stimmt nicht. Container sind Prozesse (wie Word oder Chrome) auf dem gleichen Betriebssystem wie alle anderen. Aber sie tragen eine "VR-Brille" (Namespaces) und Fesseln (cgroups). Die...
- Standardmäßig ist Docker "ziemlich" sicher. Aber für echte Isolation (Multi-Tenant): User: Root vermeiden! Starte Container nie als root (USER 1000 im Dockerfile). Read-Only Root FS: Verhindere, dass Malware Dateien ändert (--read-only). Capabilities droppen:...
Optionale Praxisaufgabe
- Erkläre Container Isolation in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Container Isolation relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Linux-Kernel S3
Überblick: Der Linux-Kernel ist der Kern eines Linux-Systems. Er verwaltet Hardware, Prozesse, Speicher, Dateisysteme und Netzwerkzugriffe. Anwendungen sprechen nicht direkt mit der Hardware, sondern über Kernel-Schnittstellen.
Einfach erklärt: Admins sehen den Kernel indirekt bei Treibern, Netzwerkproblemen, Container-Isolation, Dateisystemen und Performance. Container nutzen Kernel-Funktionen wie Namespaces und Cgroups. Moderne Netzwerk- und Security-Tools verwenden eBPF oder XDP.
Tiefer verstanden: Der Kernel stellt System Calls bereit, plant Prozesse, verwaltet virtuellen Speicher, kontrolliert Rechte und implementiert Netzwerk-Stacks. Module können Funktionen nachladen. Kernel-Version, Distribution-Patches und Konfiguration beeinflussen Stabilitaet und Feature-Support.
Praxisgrenze: Kernel-nahe Fehler können das ganze System betreffen. Unsichere Module, falsche Treiber oder riskante eBPF-Programme sind nicht wie normale App-Fehler isoliert. Kernel-Updates brauchen deshalb Rollback-Plan, Tests und Wartungsfenster.
Warum brauchen Container den Linux-Kernel?
Container teilen sich den Kernel des Hosts und nutzen Kernel-Funktionen wie Namespaces und Cgroups für Isolation.Was ist ein System Call?
Eine kontrollierte Schnittstelle, über die Programme Kernel-Funktionen anfordern.Was ist eine typische Falle?
Kernel-nahe Änderungen wie normale App-Updates zu behandeln, obwohl ein Fehler den ganzen Host betreffen kann.
Virtual Machine (VM) S2
Überblick: Ein Computer im Computer. Dein echter PC (Host) tut so, als wäre er mehrere PCs. Du startest ein Programm (VMware, VirtualBox), und darin bootet ein komplettes Windows oder Linux (Guest). Der Gast denkt, er hat eine echte Festplatte und CPU. In Wahrheit sind das nur Dateien auf deinem Host. Vorteil: Du kannst Linux auf Windows nutzen. Wenn die VM Viren bekommt, löschst du die Datei einfach. Dein echter PC bleibt sicher.
Einfach erklärt: Cloud (EC2): Nahezu 99% der "Cloud" sind VMs. Wenn du bei Amazon einen Server mietest ("EC2 Instanz"), kriegst du keinen echten Computer. Du kriegst eine VM auf einem riesigen Amazon-Server, auf dem 50 andere VMs laufen.
KVM?
Kernel-based Virtual Machine. Macht aus Linux einen Typ-1 Hypervisor. Standardtechnologie der meisten Clouds (AWS, Google Cloud).Nested Virtualization?
Eine VM in einer VM. (z. B. Docker Desktop auf Windows nutzt Hyper-V, um eine Linux-VM zu starten, in der Docker läuft).Overcommitment?
Der Trick der Cloud-Anbieter. Sie verkaufen mehr V-CPUs, als sie echte CPUs haben. Sie wetten darauf, dass nicht alle Kunden gleichzeitig 100% Last erzeugen. (Wie Banken, die nicht alles Geld im Tresor haben).
Schritt 21 / 35
Container DNS
Namensauflösung zwischen Containern verstehen.
S2
Schritt 21 / 35
Container DNS
Namensauflösung zwischen Containern verstehen.
1. Verstehen
Früher mussten Programmierer IP-Adressen wissen: "Datenbank ist auf 192.168.1.5".
In der Container-Welt ändern sich IPs ständig (siehe ClusterIP).
Deshalb brauchen Container ein eigenes Telefonbuch (DNS).
Jeder Container bekommt beim Start automatisch die Adresse des internen DNS-Servers (z. B. 127.0.0.11 in Docker).
Wenn dein Webserver sagt "Verbinde mit postgres-db", fragt er diesen DNS-Server.
Der DNS-Server antwortet sofort mit der aktuellen internen IP des Datenbank-Containers.
Du musst dich um IP-Adressen nie wieder kümmern.
Merksatz: Ein internes Namensauflösungssystem innerhalb einer Container-Plattform, das es ermöglicht, Dienste über ihren Namen (z. B. "db", "redis") statt über flüchtige IP-Adressen anzusprechen.
2. Anwenden
In Docker Compose:
services:
mein-web: ...
meine-db: ...
Im Code (Node.js):
const db = connect("postgres://meine-db:5432");
Docker setzt automatisch Einträge für meine-db.
In Kubernetes:
Service Name: users-api.
Namespace: production.
Vollständiger Name (FQDN): users-api.production.svc.cluster.local.
Innerhalb desselben Namespace reicht kurz: users-api.
Praxisroutine
In der Praxis lernst du Container DNS, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Docker Embedded DNS (127.0.0.11)
Docker fängt DNS-Anfragen auf Port 53 ab.
Es prüft: "Ist das ein Container-Name?" -> Antworte mit Container-IP.
"Ist das google.com?" -> Leite weiter an den Host-DNS (z. B. 8.8.8.8).
Das passiert im Docker Daemon (dockerd).
Wichtig: Das funktioniert nur in User-Defined Bridge Networks. Im default Bridge Network gibt es KEIN DNS (Legacy-Altlast).
2. CoreDNS (Kubernetes)
In K8s ist DNS ein eigener Pod: CoreDNS.
Er liest die Kubernetes API ("Service Watcher").
Sobald du einen Service erstellst, schreibt CoreDNS einen Record in seinen Speicher.
Die /etc/resolv.conf in jedem Pod zeigt auf die Cluster-IP von CoreDNS.
Wenn CoreDNS abstürzt, bricht die komplette Cluster-Kommunikation zusammen ("It's always DNS").
3. ndots:5 Problem
Eine berühmte Performance-Falle in K8s.
Linux DNS Resolver versuchen, Domänen zu "vervollständigen".
Du fragst: google.com.
K8s Config sagt: search default.svc.cluster.local svc.cluster.local cluster.local.
Der Container fragt erst: google.com.default.svc.cluster.local? (NXDOMAIN).
Dann: google.com.svc.cluster.local? (NXDOMAIN).
...
Erst beim 5. Versuch (ndots limit) fragt er google.com. (Root).
Das verdreifacht die DNS-Latenz für externe Aufrufe.
Lösung: FQDN nutzen (google.com.) oder ndots in Pod-Spec tunen.
4. Vertiefen
Das CoreDNS Plugin-System
Die Architektur von Kubernetes-CoreDNS basiert auf einer Kette von hochoptimierten Plugins, die in der Datei Corefile (welche in einer ConfigMap lebt) definiert werden.
Wenn eine Query (z. B. db.default.svc.cluster.local.) eintrifft:
- Das
kubernetesPlugin fängt die Request auf, schaut im Memory-Cache nach, ob ein entsprechender K8s-Service-Typ existiert, und retourniert die ClusterIP. - Schlägt das fehl, übernimmt das
forwardPlugin und leitet die Request an den Resolver des Host-Nodes, das VPC-DNS der Cloud (z. B. Route53) oder an8.8.8.8weiter, um das Internet aufzulösen. Erfahrene Betreiber manipulieren das Corefile oft (z. B. durch dasrewritePlugin), um Anfragen dynamisch von Legacy-Domains (db.legacy.corp) transparent auf K8s-interne ClusterIP-Domains umzuschreiben, ohne Applikationscode anfassen zu müssen.
NodeLocal DNSCache
Bei riesigen Clustern fliegen für jeden kleinen curl-Befehl hunderte DNS UDP-Pakete durch das Overlay-Netzwerk zum CoreDNS Pod.
UDP auf stark belasteten Linux-Kernel-Netzwerkstacks (und insbesondere im conntrack Subsystem für NAT) führt extrem schnell zu Paketabwürfen (Drops) und zwingt Clients zu langwierigen 5-Sekunden Retries.
Die Enterprise-Abhilfe ist der NodeLocal DNSCache.
K8s deployt dabei einen winzigen DNS-Cache (als DaemonSet-Pod) auf jeden verdammten Worker-Node im Cluster und kapert eine eigene Dummy-IP (169.254.20.10). Die Pods auf diesem Node rufen erst den lokalen Cache sofort über das Host-Interface ab, was Latenzen auf Mikrosekunden drückt und das zentrale CoreDNS um bis zu 90 % entlastet.
ExternalDNS
Wie machen wir den "Inside-Out" Weg?
Eine ClusterIP ist von außen nicht ansprechbar. Ein Ingress-Controller (Nginx) bekommt zwar externe Traffic, aber wer trägt den Traffic-Router-Eintrag (A-Record) bei Cloudflare oder AWS Route53 ein?
Manche Admins machen es manuell – fehleranfällig. Moderne Setups nutzen den ExternalDNS Controller.
Dieser Pod läuft im Cluster, beobachtet K8s Ingress- und K8s Service (Type LoadBalancer)-Objekte und pusht deren festgelegte Host-Namen via API direkt zum Cloud-Provider-DNS. So sind interne K8s Services wenige Sekunden nach der YAML-Erstellung weltweit als öffentliche api.firma-xyz.com bekannt.
5. Prüfen
Was ist "Service Discovery"?
Der Überbegriff. DNS ist eine Art der Service Discovery (Server-Side). Es gibt auch Client-Side Discovery (App fragt Consul/Eureka API). In K8s ist DNS der Standard.Warum geht
ping google.comim Container manchmal langsam?Siehe "ndots:5 Problem". Oder UDP-Timeouts (conntrack race condition) in älteren Kerneln. DNS nutzt UDP, was "Fire-and-Forget" ist und bei hoher Last verloren gehen kann.Kann ich DNS Einträge manuell setzen?
Ja, in Docker mit--add-host host:ip(schreibt in/etc/hosts). In K8s mithostAliases. Nützlich, um externe Legacy-Systeme unter einem festen Namen erreichbar zu machen.
Zusammenfassung
- Früher mussten Programmierer IP-Adressen wissen: "Datenbank ist auf 192.168.1.5". In der Container-Welt ändern sich IPs ständig (siehe ClusterIP). Deshalb brauchen Container ein eigenes Telefonbuch (DNS). Jeder Container bekommt beim Start automatisch die...
- In Docker Compose: yaml services: mein-web: ... meine-db: ... Im Code (Node.js): const db = connect("postgres://meine-db:5432"); Docker setzt automatisch Einträge für meine-db.
Optionale Praxisaufgabe
- Erkläre Container DNS in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Container DNS relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
DNS S1
Überblick: DNS ist das Telefonbuch des Internets. Computer verstehen keine Wörter wie google.de. Sie verstehen nur Zahlen (IP-Adressen) wie 142.250.185.35. Wenn du google.de eingibst, fragt dein Computer beim DNS-Server nach: "Hey, welche Nummer hat Google?" Der DNS-Server antwortet: "Google wohnt unter 142.250.185.35". Erst dann kann dein Computer die Verbindung aufbauen.
Einfach erklärt: Normalerweise macht dein Router (FritzBox) das automatisch (er fragt den DNS deines Providers). Aber viele Pros ändern ihren DNS-Server. Warum? Geschwindigkeit: Google DNS (8.8.8.8) oder Cloudflare (1.1.1.1) sind oft schneller als der vom Provider. Zensur umgehen: Manche Provider sperren Webseiten per DNS ("Du darfst Kinox.to nicht auflösen"). Ein anderer DNS-Server hebt die Sperre auf. Sicherheit: Manche DNS-Server (Quad9) blockieren automatisch bekannte Viren-Seiten.
Was passiert, wenn der DNS-Server ausfällt?
Das Internet "fühlt" sich kaputt an. Du kommst auf keine Webseite mehr. Skype oder WhatsApp könnten aber noch gehen, wenn sie IPs direkt benutzen.Was ist
hosts?Eine Textdatei auf deinem PC (C:\Windows\System32\drivers\etc\hosts). Das ist dein privates Mini-Telefonbuch. Was da steht, gilt vor dem DNS. Wichtig für Entwickler ("Gaukle dem PC vor, dass testseite.local auf meinem PC läuft").Ist DNS verschlüsselt?
Standardmäßig nein! Jeder (WLAN-Betreiber) kann sehen, welche Domains du abfragst. Neuere Standards wie DoH (DNS over HTTPS) verschlüsseln auch das Nachschlagen.
ClusterIP S2
Überblick: In einem Kubernetes-Cluster laufen deine Anwendungen in Pods. Pods sterben ständig und starten neu (Updates, Abstürze). Dabei bekommen sie jedes Mal eine neue IP-Adresse. Das ist ein Problem: Wie soll deine "Frontend"-App die "Datenbank"-App anrufen, wenn sich deren IP jede Minute ändert? ClusterIP ist die Lösung. Es ist eine stabile, "magische" IP-Adresse, die sich nie ändert. Kubernetes gibt sie deinem Service. "Ruf einfach 10.96.0.1 (die ClusterIP) an. Wir leiten dich automatisch an den aktuell laufenden Pod weiter." Es ist der interne Telefonbucheintrag im Cluster.
Einfach erklärt: In YAML: yaml apiVersion: v1 kind: Service metadata: name: my-backend spec: selector: app: backend-app Ziel-Pods ports: - port: 80 Port der ClusterIP targetPort: 8080 Port im Container type: ClusterIP Default (muss nicht angegeben werden) Ergebnis: kubectl get svc zeigt 10.96.x.x. Andere Pods im Cluster können nun http://my-backend (DNS) aufrufen. Kubernetes löst das zu der stabilen IP auf.
Kann ich ClusterIP vom Internet erreichen?
Nein! Sie ist strikt intern (RFC 1918 Private Ranges, meist 10.x.x.x im Service CIDR). Um von außen reinzukommen, brauchst duNodePort,LoadBalanceroderIngress.Was passiert, wenn alle Pods tot sind?
Die ClusterIP existiert noch, aber die Verbindung läuft ins Leere (Connection Refused oder Timeout), weil iptables kein gültiges Ziel (Endpoint) mehr hat.Session Affinity?
Standardmäßig ist es "Round Robin" (Zufall). Du kannstsessionAffinity: ClientIPsetzen, dann landet die gleiche Source-IP immer beim gleichen Pod (bis zum Timeout). Wichtig für Caching.
Service Mesh S3
Überblick: Ein Service Mesh ist eine Infrastrukturschicht für Kommunikation zwischen Diensten. Es kuemmert sich um Dinge wie Verschluesselung, Routing, Retry, Telemetrie und Policies, ohne dass jeder Dienst alles selbst implementieren muss.
Einfach erklärt: In Microservice-Umgebungen sprechen viele Dienste miteinander. Ein Service Mesh kann mTLS erzwingen, Traffic auf neue Versionen routen, Fehler sichtbar machen und Verbindungen beobachten. Bekannte Werkzeuge sind Istio und Linkerd.
Tiefer verstanden: Viele Service Meshes nutzen Sidecar-Proxies oder nodebasierte Proxies. Control Plane und Data Plane werden getrennt. Die Control Plane verteilt Regeln, die Data Plane verarbeitet Traffic. Typische Features sind Traffic Splitting, Circuit Breaking, mTLS und Metriken.
Praxisgrenze: Ein Service Mesh löst keine schlechte Service-Architektur. Es fuegt Komplexitaet, Latenz, Zertifikatsbetrieb und Debug-Aufwand hinzu. Für kleine Systeme kann es zu schwer sein. Sinnvoll wird es, wenn Governance, Sicherheit und Observability den Aufwand rechtfertigen.
Warum nutzt man ein Service Mesh?
Um Kommunikation zwischen Diensten sicherer, beobachtbarer und steuerbarer zu machen.Was ist mTLS?
Beidseitig authentifizierte TLS-Verbindungen, bei denen Client und Server Zertifikate nutzen.Was ist eine typische Falle?
Ein Mesh einzufuehren, obwohl Team, Monitoring und Betriebsreife dafür noch nicht bereit sind.
Schritt 22 / 35
Docker Socket
Warum der Docker Socket sicherheitskritisch ist.
S3
Schritt 22 / 35
Docker Socket
Warum der Docker Socket sicherheitskritisch ist.
1. Verstehen
Der Docker Socket (/var/run/docker.sock) ist das Ohr des Docker Daemons.
Hier hört er auf Befehle.
Normalerweise flüstert nur der docker CLI Befehl ("Starte Container!") in dieses Ohr.
Aber: Du kannst dieses Ohr auch in einen Container hineinlegen (mounten).
Warum?
Damit ein Container (z. B. Jenkins oder Portainer) andere Container steuern kann.
"Ich bin Jenkins (im Container) und ich will einen Test-Container starten."
Das nennt man Docker-in-Docker (via Socket Binding).
Merksatz: Ein Unix-Domain-Socket, der als primäre Kommunikationsschnittstelle für die Docker-API dient. Zugriff auf diesen Socket ist gleichbedeutend mit Root-Zugriff auf dem Host-System.
2. Anwenden
In docker-compose.yml für Monitoring-Tools:
services:
portainer:
image: portainer/portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Jetzt kann Portainer alle Container auflisten und stoppen. Ohne diesen Mount wäre Portainer blind.
Praxisroutine
In der Praxis lernst du Docker Socket, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Das Sicherheits-Desaster (Root Escalation)
Den Socket zu mounten ist brandgefährlich.
Beweis:
Ich bin Hacker im Container jenkins (non-root).
Ich sehe /var/run/docker.sock.
Ich installiere docker CLI.
Ich tippe: docker run -v /:/host alpine cat /host/etc/shadow.
Der Daemon (draußen!) führt das aus. Er mountet die Host-Festplatte in den neuen Alpine-Container.
Ich lese das Passwort vom Host-Admin.
Fazit: Wer den Socket hat, hat den Host.
2. Socket Proxy (Die Lösung)
Wenn du Container-Metriken brauchst (Traefik, Prometheus), aber keine Schreibrechte geben willst.
Nutze einen Socket Proxy (z. B. Tecnativa).
Das ist ein kleiner Container dazwischen.
Er leitet GET /containers/json weiter (Erlaubt).
Er blockiert POST /containers/create (Verboten).
Damit kann Traefik Labels lesen, aber nichts kaputtmachen.
3. TCP Socket (-H tcp://)
Du kannst den Socket auch übers Netzwerk freigeben (Port 2375/2376). Tue das niemals im offenen Internet ohne mTLS (Zertifikate). Bots scannen das Internet nach Port 2375. Innerhalb von Sekunden installieren sie Crypto-Miner auf deinem Cluster. Standard: "Bind to localhost only".
4. Vertiefen
1. Unix Domain Socket Permissions & Group-IDs
Der Docker-Socket (/var/run/docker.sock) ist technisch ein Inter-Process Communication (IPC) Socket. Er gehorcht strikten POSIX File-Permissions (meist srw-rw---- root:docker).
Mountet man ihn als Volume via -v in einen Pod/Container, erbt der Zielprozess exakt dieses Berechtigungs-Set der Host-Inode. Läuft der Jenkins-User im Container unter der UID 1000 ohne GID Zugehörigkeit zum Host-docker (GID oft 999), knallt der Aufruf mit "Permission Denied".
Entwickler machen dann den fatalen Fehler und setzen ein verzweifeltes chmod 777 /var/run/docker.sock zur Laufzeit auf dem Host, womit schlichtweg jeder kompromittierte Redis-Deamon im Cluster das System bedingungslos übernehmen und root-Level Ausbrüche durch Container-Spin-Ups forcieren kann.
2. Rootless Docker & Sysbox
Das "Wer den Socket hat, ist Gott"-Dogma verfällt mit der Cloud-Native Security Era.
Durch Rootless-Docker und v2 Cgroups operiert der gesamte Docker Daemon ( dockerd) selbst im User-Space ohne Host-Root Rechte. Wenn ein Hacker hier den Socket schnappt und -v /:/host fährt, mountet er maximal das isolierte Filesystem des unprivilegierten Users.
Darüber hinaus nutzt man echte Sandboxes wie Sysbox OCI Runtimes: Hier ist der Daemon so isoliert von Kernel-Ring 0, dass ein Container-interner Docker-Daemon (DinD) völlig sicher, und ohne das unsägliche --privileged Flag oder das Leaken des Host-Sockets in Kubernetes laufen kann, da Sysbox das Namespace-Nesting für /dev nativ vortäuscht.
3. API-Filterung mittels eBPF / mTLS Gateways
Ist der direkte Host-Socket zwingend (z.B. bei Traefik Edge Routern) verbietet man das Raw-Binding durch Reverse-Proxy Injection.
Man platziert Services wie docker-socket-proxy im selben internen Network. Der Proxy lauscht auf Socket-Mounts, veröffentlicht das Docker HTTPS/REST API über TLS 1.3 im Container-Network, kappt aber rigoros HTTP POST, DELETE und PUT Requests (Read-Only Mode) in seinem HAProxy Modul.
Noch härteres Engineering verlegt dies durch eBPF Kernel Hooks: Bevor das JSON Paket am Unix-Socket überhaupt beantwortet wird, decodieren Kernel-Routinen (wie Tetragon) die Socket-Payload, verbieten Schreibzugriffe applikativ in Mikrosekunden und fälschen Zero-Trust-Logs in Elastic.
5. Prüfen
Was ist
DooD?Docker-out-of-Docker. Das Verfahren, den Socket zu mounten (-v /var/run/docker.sock:...), damit der Container den Host-Docker nutzt. Im Gegensatz zu "DinD" (Docker-in-Docker), wo wirklich ein neuer Daemon im Container läuft (verschachtelt, langsam, privilegiert). DooD ist meist performanter.Dateirechte?
Der Socket gehörtroot:docker. Deshalb musst du deinen User zur Gruppedockerhinzufügen (usermod -aG docker user), um ohnesudodocker nutzen zu können. (Warnung: Das macht deinen User effektiv zum Root-User).Windows Named Pipe?
Auf Windows gibt es keine Unix Sockets. Dort heißt es//./pipe/docker_engine. Das Prinzip (API Endpoint) und das Risiko sind identisch.
Zusammenfassung
- Der Docker Socket (/var/run/docker.sock) ist das Ohr des Docker Daemons. Hier hört er auf Befehle. Normalerweise flüstert nur der docker CLI Befehl ("Starte Container!") in dieses Ohr. Aber: Du kannst dieses Ohr auch in einen Container hineinlegen (mounten)....
- In docker-compose.yml für Monitoring-Tools: yaml services: portainer: image: portainer/portainer volumes: - /var/run/docker.sock:/var/run/docker.sock Jetzt kann Portainer alle Container auflisten und stoppen. Ohne diesen Mount wäre Portainer blind.
Optionale Praxisaufgabe
- Erkläre Docker Socket in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Socket relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 23 / 35
Docker Security Scanning
Images auf Schwachstellen prüfen.
S2
Schritt 23 / 35
Docker Security Scanning
Images auf Schwachstellen prüfen.
1. Verstehen
Ein Docker Image ist wie ein Rucksack. Du packst alles rein, was deine App braucht (Ubuntu, Python, Libraries). Aber was, wenn du aus Versehen eine kaputte Bibliothek einpackst, von der jeder Hacker weiß ("Log4j Lücke")? Docker Security Scanning ist wie der Scanner am Flughafen. Er durchleuchtet deinen Rucksack (Image), bevor er ins Flugzeug (Server) darf. Er schaut in jede Datei und jede Bibliothek. Er vergleicht das Gefundene mit einer Polizeidatenbank (CVE-Liste). Wenn er eine Bombe findet, sagt er: "Alarm! CVE-2021-44228 gefunden. Bitte austauschen."
Merksatz: Der automatisierte Prozess des Analysierens von Container-Images auf bekannte Sicherheitslücken (CVEs), Malware und Fehlkonfigurationen, oft integriert in CI/CD-Pipelines.
2. Anwenden
Kommandozeile (Trivy):
trivy image python:3.4-alpine
Output:
python:3.4-alpine (alpine 3.9.2)
Total: 34 (UNKNOWN: 0, LOW: 2, MEDIUM: 15, HIGH: 11, CRITICAL: 6)
In Docker Desktop:
docker scan my-image (Nutzt Snyk Engine).
Der Scanner zeigt dir genau: "In /usr/local/lib/node_modules/... liegt eine alte Version. Upgrade auf v1.2.3 empfohlen."
Praxisroutine
In der Praxis lernst du Docker Security Scanning, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Static vs. Dynamic Analysis
Die meisten Scanner machen SCA (Software Composition Analysis).
Sie sehen sich nur die Paket-Listen an (apk info, dpkg -l, package.json).
Das ist statisch und extrem schnell.
Problem: Wenn du eine Binary (curl) manuell kompilierst (make install), taucht sie in keiner Paketliste auf. Der Scanner ist blind!
Lösung: Scanner, die auch Binaries signieren/hashen oder zur Laufzeit scannen (Dynamic Analysis).
2. Distroless Scanning
Distroless Images haben keinen Paketmanager (kein apt, kein apk).
Trivy und Co. müssen hier schlauer sein und direkt die installierten Binaries/Libraries auf der Festplatte finden.
Das funktioniert oft gut, ist aber schwieriger zu parsen als eine saubere package-lock.json.
3. False Positives & VEX
Scanner sind paranoid. Sie melden oft Lücken in Libraries, die du gar nicht nutzt ("Dead Code"). Oder Lücken im Linux-Kernel des Base-Images, die im Container gar nicht relevant sind (da der Host-Kernel genutzt wird!). Moderne Scanner unterstützen VEX (Vulnerability Exploitability eXchange). Das ist eine "Entschuldigung" vom Hersteller: "Ja, wir haben CVE-X, aber wir sind nicht betroffen, weil wir Funktion Y deaktiviert haben." Scanner lesen das VEX und unterdrücken den Fehlalarm.
4. Vertiefen
False Negatives und Scanner-Evasion
Security-Scanner in Docker verlassen sich primär auf Metadaten (Paketmanager-DBs). Das ist leicht auszutricksen.
Wenn ein Hacker ein Image kompromittiert, patcht er oft das System-Tool (/usr/bin/ls), berührt aber die APT-Datenbank (/var/lib/dpkg/status) nicht. Der Scanner liest die Datenbank, sieht "Paket coreutils Version 8.30", und meldet "Grün" – während das Binary bereits bösartig verändert ist.
Enterprise-SCA kombiniert daher den Metadaten-Scan mit Hash-Verifizierung. Trivy oder Aqua prüfen den SHA256-Hash des tatsächlichen Executable-Files auf Platte gegen die kryptografische Signatur des Original-Distributoren-Pakets.
Reachability Analysis (EPSS & Call Graphs)
Die neueste Evolutionststufe im Docker Security Scanning ist "Reachability".
Ein Scan findet oft 300 CVEs in Java-Bibliotheken (Log4j oder Spring). Admins haben keine Zeit, alles zu fixen.
Die Frage ist nicht: "Ist die unsichere Library installiert?", sondern: "Rufen wir in unserem Java-Code tatsächlich die genaue Funktion (die verwundbar ist) auf?"
Moderne Scanner analysieren den Call Graph (AST - Abstract Syntax Tree) zur Build-Zeit. Wenn der Scanner merkt, dass die anfällige Funktion parseJndiEndpoint() niemals im Flow der Applikation aufgerufen wird, de-priorisiert er den Fund von "Critical" auf "Info", da kein Angreifer die ungenutzte Schwachstelle (den Dead Code) von außen dynamisch triggern kann.
Host-Kernel Blindspots
Ein massives Versäumnis beim Image-Scan: Scanner prüfen isoliert das Image filesystem (z. B. OpenSSL Lücken in /lib/ssl.so).
Sie prüfen nicht den Linux-Kernel.
Ein Docker-Daemon mounted den Kernel (/boot/vmlinuz) transparent vom Hostsystem ein (Shared Kernel).
Hast du ein perfekt CVE-freies Container-Image (0 Lücken), aber dein EC2-Worker läuft auf einem ungepatchten Ubuntu 18.04-Kernel (z. B. "Dirty Pipe" Vulnerability), liefert dir das CVE-freie Image falsche Sicherheit. Ein Container-Ausbruch ist trivial, doch Trivy/Snyk scannen diese Host-Grenze im Standardbetrieb oft nicht mit (es sei denn als Node-Agent im Kubernetes-DaemonSet modus).
5. Prüfen
Wann sollte ich scannen?
Immer in der CI-Pipeline ("Shift Left"). Wenn der Scan rot ist, darf das Image gar nicht erst in die Registry gepusht werden. Spätestens aber in der Registry (täglicher Cronjob), weil heute eine neue Lücke für ein altes Image bekannt werden kann.Was ist SBOM?
Software Bill of Materials. Eine Zutatenliste für Software. Scanner erzeugen oft eine SBOM ("Das ist alles drin"). Das ist die Basis für Compliance.Scannt es meinen Code?
Jein. Image Scanner fokussieren sich auf OS-Pakete und Libraries (Dependencies). Für deinen eigenen Code (Logikfehler, SQL Injection) brauchst du SAST (Static Application Security Testing) wie SonarQube, nicht Trivy.
Zusammenfassung
- Ein Docker Image ist wie ein Rucksack. Du packst alles rein, was deine App braucht (Ubuntu, Python, Libraries). Aber was, wenn du aus Versehen eine kaputte Bibliothek einpackst, von der jeder Hacker weiß ("Log4j Lücke")? Docker Security Scanning ist wie der...
- Kommandozeile (Trivy): trivy image python:3.4-alpine Output: python:3.4-alpine (alpine 3.9.2) Total: 34 (UNKNOWN: 0, LOW: 2, MEDIUM: 15, HIGH: 11, CRITICAL: 6) In Docker Desktop: docker scan my-image (Nutzt Snyk Engine). Der Scanner zeigt dir genau: "In...
Optionale Praxisaufgabe
- Erkläre Docker Security Scanning in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Docker Security Scanning relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
CVE (Common Vulnerabilities and Exposures) S2
Überblick: Software hat Fehler. Manche Fehler erlauben es Hackern, einzubrechen. Wenn so ein Fehler in einer bekannten Software (wie Windows, Chrome oder Log4j) gefunden wird, bekommt er einen Namen. Dieser Name ist die CVE-ID. Beispiel: CVE-2021-44228 (Log4Shell). 2021: Das Jahr. 44228: Eine laufende Nummer. Damit weiß jeder Admin auf der Welt genau: "Ah, diese Lücke meinst du." Es ist der globale Katalog für Sicherheitslücken.
Einfach erklärt: Du scannst deine Systeme (Container, Server) regelmäßig mit einem Vulnerability Scanner (Trivy, Snyk, Nessus). Der Scanner meldet: "Dein Docker Image hat CVE-2023-1234." Du googlest die ID oder schaust in die NIST NVD (National Vulnerability Database). Dort steht: "Update sofort auf Version 1.2.3, sonst Hack." Deine Aufgabe: Patchen (Update installieren).
Was ist ein Zero-Day?
Eine Lücke, die Hackern bekannt ist, aber dem Hersteller noch nicht (0 Tage Zeit zum Fixen). Oft haben diese noch keine CVE-ID oder bekommen sie erst später.Muss ich CVEs mit Score "Low" patchen?
Kommt auf deine Policy an. Oft reicht es beim nächsten regulären Update. Bei "Critical" und "High" gibt es meist SLAs (z. B. Fix innerhalb von 24h).Werden alle Lücken CVEs?
Nein. Wenn ich eine Lücke auf deiner privaten Webseite finde, ist das keine CVE. CVEs sind für öffentlich verfügbare Software (Standardsoftware, Libraries).
SBOM (Software Bill of Materials) S3
Überblick: Wenn du eine Tiefkühl-Lasagne kaufst, steht hinten drauf: "Mehl, Tomaten, Rindfleisch, E450." Das ist wichtig für Allergiker. Kaufst du Software, steht da oft nur: "Lasagne.exe". Niemand weiß, was drin ist (welche Open-Source-Bibliotheken). Eine SBOM ist die Zutatenliste für Software. Sie listet jede winzige Komponente auf ("Log4j Version 2.14, OpenSSL 1.1.1"). Wenn bekannt wird, dass "Log4j" giftig ist (Sicherheitslücke), weißt du sofort: "Oh Gott, meine Lasagne ist betroffen!"
Einfach erklärt: Seit dem "SolarWinds"-Hack und "Log4Shell" fordern Regierungen (US Executive Order) eine SBOM. Tools erstellen sie automatisch beim Kompilieren: syft oder cyclonedx-cli. Format: JSON oder XML (Standards: CycloneDX oder SPDX). Du als Entwickler siehst sie selten, aber dein Sicherheits-Team braucht sie dringend.
Verhindert SBOM Hacks?
Nein. Die Zutatenliste macht das Essen nicht gesünder. Aber sie hilft dir, schneller zu reagieren, wenn eine Zutat faul wird.Ist das Pflicht?
Für Behörden-Software in den USA: Ja. In der EU (Cyber Resilience Act): Bald ja. Für private Hobby-Projekte: Nein.Kann man SBOMs fälschen?
Ja. Deshalb sollten sie kryptografisch signiert sein (Sigstore), damit man beweisen kann, dass die Liste wirklich vom Hersteller kommt.
Schritt 24 / 35
Container Security
Rechte, Images und Laufzeit absichern.
S3
Schritt 24 / 35
Container Security
Rechte, Images und Laufzeit absichern.
1. Verstehen
Container (Docker) sind wie Tupperdosen für Software. Viele denken: "Was in der Dose ist, kann nicht raus." Falsch. Container sind keine echten Virtual Machines. Sie teilen sich den gleichen Kernel (das Herz) mit dem Host-Betriebssystem. Wenn ein Hacker aus der Dose ausbricht ("Container Breakout"), gehört ihm der ganze Server inkl. aller anderen Dosen. Container Security schützt davor.
- Image Scanning: Prüfen, ob die Dose schon beim Einpacken verfault war (Viren im Image).
- Runtime Protection: Überwachen, ob jemand versucht, ein Loch in die Dose zu bohren.
Merksatz: Die Praxis des Schützens von Container-Anwendungen (vom Image-Build bis zur Laufzeit) vor Schwachstellen, Malware und unbefugtem Zugriff.
2. Anwenden
- Nicht als Root laufen lassen!
USER 1001im Dockerfile. Wenn du als Root im Container bist, bist du (oft) auch Root auf dem Host, wenn du ausbrichst. - Minimal Base Images: Nutze
alpineoderdistroless. Was nicht da ist (keincurl, keine Shell), kann der Hacker nicht nutzen ("Living off the land"). - Read-Only Filesystem: Verbiete dem Container, Dateien zu schreiben, wenn er es nicht muss.
Praxisroutine
In der Praxis lernst du Container Security, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Image Scanning (Trivy / Clair)
Scanner zerlegen das Image Layer für Layer.
Sie vergleichen installierte Pakete mit Datenbanken (CVEs).
"Hilfe, dein Image nutzt openssl 1.0 -> High Severity CVE!"
Das passiert vor dem Deployment (in der CI/CD Pipeline).
2. Admission Controllers (OPA Gatekeeper)
Türsteher für Kubernetes. "Du willst diesen Container starten? Er läuft als Root? -> Zugriff verweigert!" Policy as Code direkt im Cluster.
Technische Einordnung im System
Technisch ist Container Security nicht isoliert. Es wirkt mit Nachbarbegriffen zusammen, hat Voraussetzungen und erzeugt Folgen. Für ein robustes Verständnis prüfst du drei Fragen: Welche Daten oder Bedingungen braucht dieser Schritt? Welche Ausgabe oder Wirkung entsteht? Was passiert bei falschen, fehlenden oder zu großen Eingaben?
Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
4. Vertiefen
1. Linux Capabilities (Dropping)
Auch ein Prozess, der nicht "root" ist, kann verheerenden Schaden anrichten. Der Linux-Kernel teilt Superuser-Mächte in feingranulare Capabilities auf.
Ein Default-Docker-Container startet mit einem Standard-Set, das CAP_CHOWN (Darf er File-Owner ändern?) oder CAP_DAC_OVERRIDE erlaubt. Eines der stärksten Security-Prinzipien ist es, alle Capabilities zu droppen (--cap-drop=ALL) und nur jene, die wirklich gebraucht werden (z. B. CAP_NET_BIND_SERVICE, um einen Server auf Port 80 zu starten), wieder hinzuzugeben. Damit wird der Blast-Radius beim Container Escape radikal minimiert.
2. Seccomp-BPF & AppArmor
Wie verhindert man, dass ein Container-Prozess Systemaufrufe (Syscalls) startet, mit denen er den Kernel exploitieren könnte?
Mit Seccomp (Secure Computing Mode). Durch Injection eines BPF-Profils verbietet man hunderte von ungenutzten Syscalls (wie ptrace zum RAM-Lesen anderer Prozesse). Versucht die Malware im Container den Aufruf, crasht der Container durch Kernel-Intervention (SIGKILL).
Systeme wie AppArmor oder SELinux legen das als Mandatory Access Control (MAC) für Dateisysteme aus: "Dieser NGINX-Container darf streng nur /usr/share/nginx/html/ lesen und absolut keinen Write auf /etc/ machen, selbst wenn die Linux Discretionary Permissions es erlauben würden."
3. eBPF Runtime Threat Security
Werden statische Scanner (Trivy/Clair) überlistet (z.B. Zero-Day-Exploiting im Memory), greift die Runtime Security Cloud Native Ära an (Tools wie Falco oder Tetragon).
Durch eBPF hängen sich Security-Dämonen direkt in den Kernel Space und überwachen System-Aufrufe live: Startet plötzlich ein unschuldiger NGINX-Prozess via execve eine bash Binärdatei? Öffnet der Frontend-Pod (der mit dem Internet redet) eine TCP-Verbindung direkt in den versteckten Payment-Pod? Die eBPF Rule-Engine schlägt innerhalb von Mikrosekunden Alarm oder schlachtet den manipulierten Container.
5. Prüfen
Sind VMs sicherer?
Ja. Eine VM hat ihren eigenen Kernel. Ein Ausbruch ist viel schwerer ("Hypervisor Escape"). Dafür sind VMs langsamer und fetter. Techniken wie "gVisor" oder "Kata Containers" versuchen, VMs so leicht wie Container zu machen (Sandboxing).Was sind Privileged Container?
docker run --privileged. Das ist wie "Sicherheit ausschalten". Der Container darf fast alles, was der Host darf (Hardwarezugriff). Niemals ohne extrem guten Grund nutzen!Reicht eine Firewall?
Nein. Innerhalb von Kubernetes (East-West Traffic) hilft die klassische Firewall kaum. Man braucht Network Policies oder Service Mesh.
Zusammenfassung
- Container (Docker) sind wie Tupperdosen für Software. Viele denken: "Was in der Dose ist, kann nicht raus." Falsch. Container sind keine echten Virtual Machines. Sie teilen sich den gleichen Kernel (das Herz) mit dem Host-Betriebssystem. Wenn ein Hacker aus...
- Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
- Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Optionale Praxisaufgabe
- Erkläre Container Security in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Container Security relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
IT-Sicherheit S1
Überblick: IT-Sicherheit bedeutet, digitale Systeme vor Missbrauch, Ausfall und Datenverlust zu schützen. Es geht nicht nur um Hacker, sondern auch um Fehlkonfigurationen, schwache Passwörter, fehlende Backups und falsche Berechtigungen. Gute Sicherheit macht Risiken sichtbar und begrenzt Schaden.
Einfach erklärt: Praktische Sicherheit beginnt mit Updates, starken Passwörtern, MFA, Backups, Rollenrechten und sauberem Logging. Bei Webanwendungen gehoeren Eingabevalidierung, sichere Sessions, Rate Limits und Schutz vor Injection dazu. Im Betrieb sind Monitoring und Incident-Prozesse entscheidend.
Tiefer verstanden: Sicherheitsarbeit verbindet Prävention, Erkennung und Reaktion. Prävention reduziert Angriffswege, Erkennung findet Auffaelligkeiten und Reaktion begrenzt Schaden. Dazu gehoeren Threat Modeling, Zugriffskontrolle, Netzwerksegmentierung, Dependency-Scanning, Secrets-Management und Audit Logs.
Praxisgrenze: Absolute Sicherheit gibt es nicht. Jede Massnahme hat Kosten, Bedienaufwand und Restrisiken. Gefaehrlich sind Sicherheitsfeatures ohne Betrieb: ein WAF ohne Alerts, Logs ohne Review oder Backups ohne Restore-Test. Sicherheit muss zur Bedrohung, Datenart und Nutzergruppe passen.
Was sind die drei klassischen Schutzziele?
Vertraulichkeit, Integritaet und Verfügbarkeit. Daten sollen geheim bleiben, korrekt bleiben und erreichbar sein.Warum reichen Passwörter allein oft nicht?
Sie können gestohlen, erraten oder wiederverwendet werden. MFA senkt das Risiko deutlich.Was ist eine typische Falle?
Sicherheitswerkzeuge einzubauen, aber Alerts, Updates, Rollen und Wiederherstellung nicht zu betreiben.
SBOM (Software Bill of Materials) S3
Überblick: Wenn du eine Tiefkühl-Lasagne kaufst, steht hinten drauf: "Mehl, Tomaten, Rindfleisch, E450." Das ist wichtig für Allergiker. Kaufst du Software, steht da oft nur: "Lasagne.exe". Niemand weiß, was drin ist (welche Open-Source-Bibliotheken). Eine SBOM ist die Zutatenliste für Software. Sie listet jede winzige Komponente auf ("Log4j Version 2.14, OpenSSL 1.1.1"). Wenn bekannt wird, dass "Log4j" giftig ist (Sicherheitslücke), weißt du sofort: "Oh Gott, meine Lasagne ist betroffen!"
Einfach erklärt: Seit dem "SolarWinds"-Hack und "Log4Shell" fordern Regierungen (US Executive Order) eine SBOM. Tools erstellen sie automatisch beim Kompilieren: syft oder cyclonedx-cli. Format: JSON oder XML (Standards: CycloneDX oder SPDX). Du als Entwickler siehst sie selten, aber dein Sicherheits-Team braucht sie dringend.
Verhindert SBOM Hacks?
Nein. Die Zutatenliste macht das Essen nicht gesünder. Aber sie hilft dir, schneller zu reagieren, wenn eine Zutat faul wird.Ist das Pflicht?
Für Behörden-Software in den USA: Ja. In der EU (Cyber Resilience Act): Bald ja. Für private Hobby-Projekte: Nein.Kann man SBOMs fälschen?
Ja. Deshalb sollten sie kryptografisch signiert sein (Sigstore), damit man beweisen kann, dass die Liste wirklich vom Hersteller kommt.
Runtime Protection S3
Überblick: Du hast eine Alarmanlage am Haus (Firewall). Du hast stabile Schlösser (Secure Code). Aber was, wenn der Einbrecher trotzdem drin ist? (Weil er den Postboten bestochen hat). Runtime Protection ist der Wachhund im Haus. Er bellt sofort, wenn jemand etwas Verdächtiges tut. "Warum öffnet der Postbote den Safe?" (Anomalie). "Warum telefoniert die Kaffeemaschine nach China?" (Exfiltration). Es schützt die Software während sie läuft (zur Laufzeit), indem es ihr Verhalten überwacht.
Einfach erklärt: Tools wie Falco (Open Source) oder kommerzielle EDR-Lösungen. Du definierst Regeln: "Ein Webserver (Nginx) darf niemals curl ausführen oder /etc/shadow lesen." Wenn er es doch tut, schreit Falco: "ALARM! Hacker im Nginx Container!" In Kubernetes läuft das meist als DaemonSet (ein Wächter pro Node).
Reicht Virenscanner nicht?
Nein. Virenscanner suchen nach bekannten Dateien ("Signaturen"). Runtime Protection sucht nach Verhalten. Ein Hacker, der "live" Befehle tippt, hat keine Datei, die man scannen kann ("Fileless Malware").Gibt es False Positives?
Ja, viele. Wenn der Admin sich einloggt, um zu debuggen, denkt das Tool: "Hacker!". Man muss das System tunen ("Baselining").Blockiert es oder meldet es nur?
Meistens erst mal nur Melden (Alerting), um die Produktion nicht zu stören. Im Hochsicherheitsbereich: Blockieren (Kill Process).
DevSecOps S3
Überblick: Früher: 1. Entwickler (Dev) bauen Software. 2. Admins (Ops) installieren sie. 3. Ganz am Ende kommt der Sicherheitsbeauftragte (Sec) und sagt: "Halt, alles unsicher. Neu machen!" (Alle sind genervt).
Einfach erklärt: Automatisierung ist der Schlüssel. In deine CI/CD-Pipeline (Jenkins/GitLab) baust du Scanner ein: SAST (Static Analysis): Prüft den Code bevor er läuft ("Passwort im Klartext gefunden!"). SCA (Software Composition Analysis): Prüft deine Bibliotheken ("Du nutzt eine alte Version von Log4j, die gehackt werden kann!"). Wenn der Scanner meckert, stoppt der Build. Das Problem kommt gar nicht erst in Produktion.
Brauche ich noch Pentester?
Ja. Automatisierte Tools finden 80% der Fehler (die einfachen). Für die komplexen Logik-Fehler brauchst du immer noch menschliche Hacker (White Hats).Verlangsamt das nicht alles?
Am Anfang ja. Aber langfristig wirst du schneller, weil du nicht mehr kurz vor Release alles stoppen und reparieren musst ("Hotfix-Feuerwehr").Ist es nur ein Buzzword?
Ein bisschen. Eigentlich sollte "DevOps" schon immer Sicherheit beinhalten. Aber weil es oft vergessen wurde, hat man das "Sec" explizit in den Namen geschoben.
Schritt 25 / 35
cgroups (Control Groups)
Ressourcenlimits für Container verstehen.
S3
Schritt 25 / 35
cgroups (Control Groups)
Ressourcenlimits für Container verstehen.
1. Verstehen
Dein Computer hat begrenzte Ressourcen: CPU, RAM, Festplatte. Normalerweise kämpfen alle Programme darum ("Survival of the Fittest"). Wenn Chrome abstürzt und 100% CPU frisst, ruckelt deine Maus. cgroups (Control Groups) sind der Türsteher im Linux-Kernel. Du kannst Prozesse in Gruppen stecken und Regeln aufstellen:
- "Gruppe 'Datenbank' darf maximal 4GB RAM nutzen."
- "Gruppe 'Webserver' darf nur CPU 1 und 2 nutzen." Wenn die Datenbank versucht, mehr RAM zu nehmen, sagt der Kernel "Nein" (oder tötet sie). Das ist die technologische Basis für Docker. Nur so können Container sicher nebeneinander laufen, ohne sich gegenseitig zu stören ("Noisy Neighbor Problem").
Merksatz: Ein Linux-Kernel-Feature, das es ermöglicht, Systemressourcen (CPU, Speicher, Disk I/O, Netzwerk) für eine Gruppe von Prozessen zu limitieren, zu priorisieren und zu überwachen.
2. Anwenden
Als Docker-Nutzer siehst du cgroups ständig:
docker run --cpus="1.5" --memory="512m" nginx
Das übersetzt Docker im Hintergrund in cgroup-Regeln.
- Es erstellt einen cgroup Ordner:
/sys/fs/cgroup/cpu/docker/<container-id>. - Es schreibt
150000incpu.cfs_quota_us. - Es schreibt
536870912inmemory.limit_in_bytes.
Du kannst es prüfen mit docker stats. Das Tool liest einfach die cgroup-Metriken aus.
Praxisroutine
In der Praxis lernst du cgroups (Control Groups), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. v1 vs. v2
Es gibt zwei Versionen der cgroup API.
- cgroup v1: Hierarchisch chaotisch. Jede Ressource (cpu, memory) hatte eigene Ordnerstrukturen. Schwer zu koordinieren.
- cgroup v2 (Unified Hierarchy): Der neue Standard (in modernen Distros und K8s). Alles ist in einem Baum. Ermöglicht bessere Features wie "Resource Pressure Stall Information" (PSI) und sichereres Rootless Docker.
2. OOM Killer (Out of Memory)
Was passiert, wenn die cgroup voll ist?
Wenn ein Prozess das Limit (Hard Limit) erreicht, greift der OOM Killer innerhalb der cgroup ein.
Er tötet den Prozess mit dem höchsten Verbrauch.
Exit Code 137 (128 + 9 SIGKILL) in Docker ist das klassische Zeichen: "Der Cgroup-Türsteher hat zugeschlagen".
Der Rest des Systems (Host) bleibt unberührt.
3. CPU Shares vs. CPU Quota
- CPU Quota (Hard Limit): "Du bekommst exakt 0.5 CPUs". Wenn Limit erreicht ist, wird der Prozess vom Scheduler "gedrosselt" (Throttling). Er pausiert für den Rest der Periode (100ms). Führt zu Latenz-Spikes!
- CPU Shares (Soft Limit): "Du bekommst Priorität 1024". Wenn die CPU leer ist, darfst du 100% nehmen. Wenn Stau ist, kriegst du deinen Anteil. Besser für Auslastung, aber weniger vorhersehbar.
4. Vertiefen
1. CPU CFS Quota vs. CPU Shares (Hard vs. Soft)
Wie verteilt Kubernetes die Rechenkraft auf Pods?
Wird unter resources: requests CPU gefordert, setzt cgroups die cpu.shares. Das ist eine rein relative Zahl (z.B. 1024 vs 512). Alle Container nutzen 100% der Hardware. Nur falls Ressourcenknappheit entsteht, priorisiert der Kernel den 1024-Prozess mit gnadenlos doppelter CPU-Länge (Soft-Limit).
Nutzt man resources: limits, feuert cgroups die scharfe Waffe: CFS Quota (Completely Fair Scheduler). In einem Fenster von zumeist 100ms kriegt der Container $X$ Mikrosekunden Rechenzeit. Ist der Burst innerhalb von 20ms aufgebraucht, "throttelt" der Kernel den Prozess brutal für die restlichen 80ms (Freeze). Selbst wenn das Rechenzentrum leer steht, blockiert cgroups künstlich und induziert furchtbare 99th-Percentile Latenz-Aussetzer bei Java-Gartner-Knoten.
2. EBPF und OOM-Debugging
Früher war der "OOM Killer" ein Phantom der Blackbox. Wenn ein Java-Heap den Root-CGroup des Docker-Containers überlief, stürzte alles mit SIGKILL und Exit Code 137 ab, oft gänzlich ohne Log.
Mit modernen eBPF (Extended Berkeley Packet Filter) Hooks schaut die Cloud-Welt tief ins cgroup-Subsystem. Tools greifen sich im Kernel-Space sofort Pointers ab, sobald die Funktion mem_cgroup_out_of_memory triggert. Sie exportieren den exakten Call-Stack, den Call-Graph-RSS-Graphen sowie Block-I/O Engpässe des Userspace, noch drei Millisekunden bevor der Container endgültig verdampft, ins Elasticsearch-Dashboard.
3. Namespace/Cgroup v2 unified hierarchy
Cgroups v1 war evolutionärer Bastelcode. Ein Prozess lag bei Memory in einem anderen Hierarchiebaum als bei CPU, was es extrem anfällig für "Race Conditions" bei Start/Stop-Orchestrierungen machte. Cgroups v2 (Standard seit Kubernetes 1.25+ und dem systemd Umbruch) verschmilzt das Konzept. Ein Task gehört zu genau einer Node in einem einzigen, zentralen cgroup-V2-Baum, durch alle Controller tiefgeschachtelt hinweg. Dadurch erst wurde es möglich zu beobachten, dass exzessive Speicher-Auslagerung (Swap) in Wahrheit ein I/O-Bandbreitenproblem zur Platte darstellt. Mit V2 kann der Controller endlich Memory-Druck und Disk-Latencies als kombiniertes Limit regeln ("Pressure Stall Information").
5. Prüfen
Ist cgroup Virtualisierung?
Nein. Es ist nur Ressourcen-Buchhaltung. Der Prozess läuft immer noch direkt auf der Hardware (CPU). Er wird nur vom Scheduler öfter gestoppt.Unterschied zu Namespaces?
Die goldene Regel der Container: Namespaces isolieren das Sehen (was darf ich sehen? Prozess-IDs, Mounts). Cgroups isolieren das Nutzen (wie viel darf ich verbrauchen? CPU, RAM). Beides zusammen macht einen Container.Kann ich Disk I/O limitieren?
Ja (blkio Controller). Wichtig in der Cloud, damit ein Container nicht die ganze SSD-Bandbreite klaut und andere Kunden ausbremst.
Zusammenfassung
- Dein Computer hat begrenzte Ressourcen: CPU, RAM, Festplatte. Normalerweise kämpfen alle Programme darum ("Survival of the Fittest"). Wenn Chrome abstürzt und 100% CPU frisst, ruckelt deine Maus. cgroups (Control Groups) sind der Türsteher im Linux-Kernel. Du...
- Als Docker-Nutzer siehst du cgroups ständig: docker run --cpus="1.5" --memory="512m" nginx Das übersetzt Docker im Hintergrund in cgroup-Regeln. 1. Es erstellt einen cgroup Ordner: /sys/fs/cgroup/cpu/docker/. 2. Es schreibt 150000 in cpu.cfsquotaus. 3. Es...
Optionale Praxisaufgabe
- Erkläre cgroups (Control Groups) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem cgroups (Control Groups) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Linux-Kernel S3
Überblick: Der Linux-Kernel ist der Kern eines Linux-Systems. Er verwaltet Hardware, Prozesse, Speicher, Dateisysteme und Netzwerkzugriffe. Anwendungen sprechen nicht direkt mit der Hardware, sondern über Kernel-Schnittstellen.
Einfach erklärt: Admins sehen den Kernel indirekt bei Treibern, Netzwerkproblemen, Container-Isolation, Dateisystemen und Performance. Container nutzen Kernel-Funktionen wie Namespaces und Cgroups. Moderne Netzwerk- und Security-Tools verwenden eBPF oder XDP.
Tiefer verstanden: Der Kernel stellt System Calls bereit, plant Prozesse, verwaltet virtuellen Speicher, kontrolliert Rechte und implementiert Netzwerk-Stacks. Module können Funktionen nachladen. Kernel-Version, Distribution-Patches und Konfiguration beeinflussen Stabilitaet und Feature-Support.
Praxisgrenze: Kernel-nahe Fehler können das ganze System betreffen. Unsichere Module, falsche Treiber oder riskante eBPF-Programme sind nicht wie normale App-Fehler isoliert. Kernel-Updates brauchen deshalb Rollback-Plan, Tests und Wartungsfenster.
Warum brauchen Container den Linux-Kernel?
Container teilen sich den Kernel des Hosts und nutzen Kernel-Funktionen wie Namespaces und Cgroups für Isolation.Was ist ein System Call?
Eine kontrollierte Schnittstelle, über die Programme Kernel-Funktionen anfordern.Was ist eine typische Falle?
Kernel-nahe Änderungen wie normale App-Updates zu behandeln, obwohl ein Fehler den ganzen Host betreffen kann.
Prozess S1
Überblick: Ein Prozess ist ein laufendes Programm. Wenn du einen Browser startest, erzeugt das Betriebssystem einen oder mehrere Prozesse. Jeder Prozess bekommt Speicher, Rechte und eine laufende Ausführung.
Einfach erklärt: Im Task-Manager oder mit ps unter Linux siehst du Prozesse. Dort erkennst du, welches Programm CPU, RAM oder Netzwerk nutzt. Wenn eine Anwendung hängt, beendet man oft den Prozess statt die ganze Maschine neu zu starten.
Tiefer verstanden: Ein Prozess hat einen eigenen virtuellen Adressraum, offene Dateien, Umgebungsvariablen, Rechte und mindestens einen Thread. Das Betriebssystem plant Prozesse über den Scheduler ein und wechselt zwischen ihnen per Context Switch.
Praxisgrenze: Prozesse isolieren Fehler besser als Threads, kosten aber mehr Speicher und Verwaltungsaufwand. In Servern entscheidet das Prozessmodell über Stabilität, Parallelität und Debugbarkeit. Container nutzen Prozess-Isolation, Namespaces und Cgroups, sind aber keine vollständigen virtuellen Maschinen.
Was ist ein Prozess?
Ein laufendes Programm mit eigenem Speicher, Rechten und Betriebssystemzustand.Warum sind Prozesse nützlich?
Sie isolieren Programme voneinander und machen Ressourcenverbrauch sichtbar.Was ist der Unterschied zu einem Thread?
Ein Thread läuft innerhalb eines Prozesses und teilt sich dessen Speicher mit anderen Threads.
Schritt 26 / 35
Linux Namespace
Die technische Basis der Isolation.
S3
Schritt 26 / 35
Linux Namespace
Die technische Basis der Isolation.
1. Verstehen
Stell dir vor, du wohnst in einem Haus (Server) mit vielen Zimmern. Normalerweise können alle in den Flur schauen und sehen, wer sonst noch da ist. Namespaces sind wie magische Zimmer. Wer im Zimmer "Container A" sitzt, glaubt, er sei alleine im Haus. Er sieht keine anderen Bewohner. Er sieht eine eigene Uhr, eigene Möbel (Festplatte), eigene Fenster (Netzwerk). Für den Hausmeister (Kernel) wohnen aber alle im selben Haus. Das ist der Trick hinter Containern: Die Prozesse laufen auf dem gleichen Kernel, aber sie sehen unterschiedliche Welten.
Merksatz: Ein Feature des Linux-Kernels, das Systemressourcen (wie Prozess-IDs, Netzwerk, Mount-Punkte) so isoliert, dass Prozesse innerhalb eines Namespace den Eindruck haben, sie hätten das System für sich allein.
2. Anwenden
Als Admin nutzt du unshare (CLI Tool), um Namespaces zu testen:
unshare --fork --pid --mount-proc /bin/bash
Du bist jetzt in einer neuen Shell.
Tippe ps aux.
Du siehst nur zwei Prozesse: Deine Bash und ps.
Alle anderen hunderte Prozesse des Systems sind unsichtbar.
Docker macht genau das für jeden Container.
Praxisroutine
In der Praxis lernst du Linux Namespace, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Die 7 (oder 8) Namespaces
- PID: Eigene Prozess-Nummern (PID 1 im Container).
- NET: Eigener Netzwerk-Stack (eth0, IP, iptables).
- MNT: Eigene Mounts (Das Image-Dateisystem).
- UTS: Eigener Hostname (
my-container). - IPC: Eigene Shared Memory Segmente (damit Container A nicht in RAM von B schreibt).
- USER: Eigene User-IDs (Root im Container = Nobody draußen).
- CGROUP: Eigene Cgroup-View (selten genutzt).
- TIME: Eigene Uhrzeit (Neu in Kernel 5.6!).
2. Enter Namespace (nsenter)
Ein mächtiges Debugging-Tool.
Wenn ein Container spinnt, aber keine Shell (/bin/bash) hat.
Du kannst vom Host aus in den Namespace "springen".
- Finde PID:
docker inspect --format '{{.State.Pid}}' my-container-> 12345. nsenter --target 12345 --net --pidJetzt bist du mit deiner Host-Shell im Netzwerk- und Prozess-Namespace des Containers. Du kannstip addrtippen und siehst die Container-IP, obwohl du "draußen" bist.
3. User Namespaces (The Missing Link)
Lange Zeit war Docker unsicher, weil "Root im Container" auch "Root am Host" war (wenn man ausbricht). User Namespaces mappen UIDs. Container UID 0 (Root) -> Host UID 100.000 (Subuid). Selbst bei einem Kernel-Exploit bricht der Hacker aus und ist... Nobody. Das ist der Heilige Gral der Container-Sicherheit, aber komplex einzurichten (File Permissions).
4. Vertiefen
1. File Deskriptor Leakage und unshare() Internals
Der pure clone()-Syscall reicht nicht, um eine Container-Runtime zu bauen. Ein gefährlicher Vektor für Container-Breaches ist das Leakage von File Deskriptoren vom Host in den Namespace.
Wenn der Parent-Prozess per fork(CLONE_NEWPID | CLONE_NEWNET) den Namespace spannt, erbt das Kind (der Container-Init) still und heimlich alle offenen File Descriptoren (Sockets, File-Handles).
Wenn im Host noch /etc/shadow als offener Descriptor 5 im C-Speicher lag, nützt im Container selbst der radikalste Mount-Namespace absolut nichts. Das Container-Binary greift trivial in C via read(5, buf) komplett am Namespace vorbei in den Host-Rootfs hinein! Echtes "Jailen" erfordert daher striktes FD-Srubbing (Close-on-Exec O_CLOEXEC) bevor in den Container execve gedroppt wird.
2. ARP-Poisoning & veth-Pair Netzwerk Isolation (NET Namespace)
Wie telefoniert ein NET Namespace? Die Applikation sieht drinnen eth0, doch faktisch ist das ein Software-Illusion.
Linux nutzt hier Virtual Ethernet Pairs (veth-pairs). Das ist ein virtuelles Kupferkabel. Das CNI-Plugin (Calico/Flannel) stopft das eine Ende (eth0) in den NET Namespace des Pods. Das andere Ende (veth13ab2) verbleibt im Host-Root-Namespace und wird an eine Linux-Bridge (docker0 oder cbr0).
Eine riesige L2-Sicherheitslücke in rohen Bridges: Pod A kann triviale ARP-Spoofing Pakete an die Bridge schicken ("Ich bin das Gateway-MAC"). Ohne harte iptables / eBPF-Policing im Host zwingt man Netzwerke in Kubenretes massiv in Denial Of Service Zustände, da Namespaces auf L2-Ebene nativ kaum Isolation zur Nachbar-Switch-Schnittstelle besitzen.
3. User Namespaces vs. OverlayFS (Shiftfs Problem)
Bis 2021 hatten User-Namespaces ein fundamentales Produktions-Desaster. Podman warb intensiv für Rootless-Containers (UID 0 innen gemappt auf User 1000 außen).
Aber was passiert, wenn man das Ubuntu-Docker-Image aus dem Internet zieht, dessen Dateien dem User 0 (Root) gehören?
Da der Worker Node als User 1000 läuft, durfte er beim Starten die /bin/bash im Ext4/OverlayFS nicht ausführen ("Permission Denied").
Die Kernel-Lösung nannte sich ursprünglich shiftfs und mündete schlussendlich in Ubuntu/Linux >= 5.12 in ID-mapped mounts. Der Kernel fälscht bei jedem Dateizugriff des Containers auf Festplattenebene die Berechtigungen im VFS-Layer "on-the-fly". Die Festplatte glaubt, UID 1000 fragt an, aber Container-intern antwortet der VFS Layer mit "Datei gehört UID 0". Diese VFS ID-Maps eliminierten das grausame stundenlange "Chownen" von Imagedaten für sichere K8s-Server.
5. Prüfen
Sind Namespace Virtualisierung?
Nein. Es ist Isolation. Es wird keine Hardware emuliert. Ein Syscallopen()geht direkt an den Host-Kernel. Deshalb sind Container "Bare Metal" schnell.Was teilt man sich?
Den Kernel! Und (ohne User NS) oft den User. Und Zeit (vor Kernel 5.6). Wenn der Kernel crasht (Panic), sterben alle Namespaces.Zombies im PID Namespace?
Wenn PID 1 im Namespace stirbt, tötet der Kernel alle anderen Prozesse im Namespace (SIGKILL). Ein Namespace ohne PID 1 kann nicht existieren.
Zusammenfassung
- Stell dir vor, du wohnst in einem Haus (Server) mit vielen Zimmern. Normalerweise können alle in den Flur schauen und sehen, wer sonst noch da ist. Namespaces sind wie magische Zimmer. Wer im Zimmer "Container A" sitzt, glaubt, er sei alleine im Haus. Er...
- Als Admin nutzt du unshare (CLI Tool), um Namespaces zu testen: unshare --fork --pid --mount-proc /bin/bash Du bist jetzt in einer neuen Shell. Tippe ps aux. Du siehst nur zwei Prozesse: Deine Bash und ps. Alle anderen hunderte Prozesse des Systems sind...
Optionale Praxisaufgabe
- Erkläre Linux Namespace in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Linux Namespace relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Linux-Kernel S3
Überblick: Der Linux-Kernel ist der Kern eines Linux-Systems. Er verwaltet Hardware, Prozesse, Speicher, Dateisysteme und Netzwerkzugriffe. Anwendungen sprechen nicht direkt mit der Hardware, sondern über Kernel-Schnittstellen.
Einfach erklärt: Admins sehen den Kernel indirekt bei Treibern, Netzwerkproblemen, Container-Isolation, Dateisystemen und Performance. Container nutzen Kernel-Funktionen wie Namespaces und Cgroups. Moderne Netzwerk- und Security-Tools verwenden eBPF oder XDP.
Tiefer verstanden: Der Kernel stellt System Calls bereit, plant Prozesse, verwaltet virtuellen Speicher, kontrolliert Rechte und implementiert Netzwerk-Stacks. Module können Funktionen nachladen. Kernel-Version, Distribution-Patches und Konfiguration beeinflussen Stabilitaet und Feature-Support.
Praxisgrenze: Kernel-nahe Fehler können das ganze System betreffen. Unsichere Module, falsche Treiber oder riskante eBPF-Programme sind nicht wie normale App-Fehler isoliert. Kernel-Updates brauchen deshalb Rollback-Plan, Tests und Wartungsfenster.
Warum brauchen Container den Linux-Kernel?
Container teilen sich den Kernel des Hosts und nutzen Kernel-Funktionen wie Namespaces und Cgroups für Isolation.Was ist ein System Call?
Eine kontrollierte Schnittstelle, über die Programme Kernel-Funktionen anfordern.Was ist eine typische Falle?
Kernel-nahe Änderungen wie normale App-Updates zu behandeln, obwohl ein Fehler den ganzen Host betreffen kann.
Prozess S1
Überblick: Ein Prozess ist ein laufendes Programm. Wenn du einen Browser startest, erzeugt das Betriebssystem einen oder mehrere Prozesse. Jeder Prozess bekommt Speicher, Rechte und eine laufende Ausführung.
Einfach erklärt: Im Task-Manager oder mit ps unter Linux siehst du Prozesse. Dort erkennst du, welches Programm CPU, RAM oder Netzwerk nutzt. Wenn eine Anwendung hängt, beendet man oft den Prozess statt die ganze Maschine neu zu starten.
Tiefer verstanden: Ein Prozess hat einen eigenen virtuellen Adressraum, offene Dateien, Umgebungsvariablen, Rechte und mindestens einen Thread. Das Betriebssystem plant Prozesse über den Scheduler ein und wechselt zwischen ihnen per Context Switch.
Praxisgrenze: Prozesse isolieren Fehler besser als Threads, kosten aber mehr Speicher und Verwaltungsaufwand. In Servern entscheidet das Prozessmodell über Stabilität, Parallelität und Debugbarkeit. Container nutzen Prozess-Isolation, Namespaces und Cgroups, sind aber keine vollständigen virtuellen Maschinen.
Was ist ein Prozess?
Ein laufendes Programm mit eigenem Speicher, Rechten und Betriebssystemzustand.Warum sind Prozesse nützlich?
Sie isolieren Programme voneinander und machen Ressourcenverbrauch sichtbar.Was ist der Unterschied zu einem Thread?
Ein Thread läuft innerhalb eines Prozesses und teilt sich dessen Speicher mit anderen Threads.
Schritt 27 / 35
Unprivileged Container
Container ohne Root-Risiko betreiben.
S3
Schritt 27 / 35
Unprivileged Container
Container ohne Root-Risiko betreiben.
1. Verstehen
Standardmäßig ist der "Root"-User im Docker Container auch der "Root"-User auf dem Host-Server. Er hat zwar eingeschränkte Sicht (Namespaces), aber wenn er ausbricht (Container Escape), ist er Gott auf deinem Server. Ein Unprivileged Container läuft zwar im Container als "Root" (UID 0), ist aber auf dem Host ein Niemand (UID 1001). Selbst wenn der Hacker ausbricht, hat er auf dem Server keine Rechte. Er kann nichts löschen, nichts installieren. Das ist der Goldstandard für Container-Sicherheit.
Merksatz: Ein Container, dessen Prozesse auf dem Host-System einem nicht-privilegierten Benutzer zugeordnet sind (User Namespace Remapping), um die Auswirkungen eines Container-Ausbruchs zu minimieren.
2. Anwenden
Der einfache Weg (Non-Root User): Im Dockerfile:
USER 1001
Der Prozess läuft als User 1001. Er darf keine Systemdateien anfassen und keine Privileged Ports (< 1024) binden.
Der harte Weg (User Namespace Remapping):
In daemon.json:
"userns-remap": "default"
Docker mappt Container-Root (0) auf Host-User (100000).
Für den Container sieht es aus wie Root. Für den Host ist es User 100000.
Praxisroutine
In der Praxis lernst du Unprivileged Container, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Rootless Docker / Podman
Docker brauchte früher einen Daemon, der als Root lief (dockerd).
Sicherheitsrisiko: Wer mit dem Daemon redet, hat Root-Rechte.
Rootless Docker (und Podman) läuft komplett im Userspace.
Der Daemon selbst gehört deinem User.
Kein sudo docker mehr nötig.
Nutzt newuidmap und newgidmap (SUID binaries), um Namespaces ohne Root aufzubauen.
2. Capabilities Dropping
Auch wenn du als Root im Container läufst, nimmt Docker dir standardmäßig viele Kräfte weg (Linux Capabilities).
CAP_SYS_ADMIN(Der Gott-Modus): Weg.CAP_NET_ADMIN(IPs ändern): Weg. Wenn dudocker run --privilegedmachst, gibst du alle Capabilities zurück. Tu das niemals in Produktion (außer für Docker-in-Docker).
3. Bind Mount Probleme
Bei User Remapping (Host User 1000 -> Container Root 0) gibt es oft Probleme mit Volumes. Du mountest einen Ordner rein. Der Container schreibt eine Datei (als Root). Auf dem Host gehört die Datei User 100000 (Subuid). Du (User 1000) kannst sie nicht lesen/löschen! "Permission Denied". Lösung: Podman macht das oft automatisch besser ("Permission Shift").
4. Vertiefen
1. User Namespace Remapping Deep Dive
Technisch nutzt Linux das User Namespace Feature.
In /etc/subuid wird festgelegt, welche IDs ein User verwenden darf.
Beispiel: Rixx:100000:65536.
Das bedeutet: Der User Rixx darf im Container die UID 0 (Root) nutzen. Der Kernel mappt diese "0" auf die reale UID "100000" auf dem Host.
Wenn der Prozess im Container nun versucht, /etc/shadow des Host-Systems zu lesen, sieht der Kernel den Zugriff von UID 100000. Da /etc/shadow nur für die echte UID 0 lesbar ist, wird der Zugriff verweigert. Der Hacker "denkt" er ist Root, ist aber in einer Sandbox mit einer Pseudo-Identität gefangen.
2. Rootless Networking (slirp4netns)
Ein unprivilegierter Container hat ein Problem: Er darf keine Netzwerk-Interfaces auf dem Host anlegen (Veth-Pairs).
Um trotzdem Internet zu haben, nutzt Rootless-Docker oder Podman das Tool slirp4netns.
Dies emuliert einen kompletten TCP/IP-Stack im Userspace. Es schickt Ethernet-Pakete über einen TAP-Socket und übersetzt sie in normale System-Calls.
Der Preis: Performance. Rootless Networking ist ca. 10-20% langsamer als Root-Networking und hat Probleme mit MTU-Größen und ICMP (Ping funktioniert oft nicht ohne Hacks). In High-Performance Umgebungen muss man dies durch spezialisierte Plugins (wie cni-ovn) optimieren.
3. Das SUID-Dilemma & No-New-Privileges
Obwohl der Container unprivilegiert ist, könnte ein bösartiges Progrämmchen im Container versuchen, über SUID-Binaries (wie sudo) mehr Rechte zu erlangen.
Sicherheitsarchitekten setzen daher in Produktion zusätzlich das Flag --security-opt=no-new-privileges.
Dieser Kernel-Befehl verbietet es einem Prozess und all seinen Kindern, jemals wieder Privilegien zu erhöhen (auch nicht über SUID). Das schließt das letzte Schlupfloch, falls ein Hacker im Container einen Weg finden sollte, vom "Pseudo-Root" zum "Echten Root" zu werden.
5. Prüfen
Warum Port 80 Problem?
Nur Root darf Ports < 1024 binden (Linux Regel). Ein unprivilegierter Container (Nginx als User 1001) muss Port 8080 nutzen. (Ab Kernel 4.11 kann man das lockern viasysctl net.ipv4.ip_unprivileged_port_start).Ist "USER 1000" sicher genug?
Viel sicherer als Root. Aber wenn es im Kernel eine Lücke gibt ("Dirty Pipe"), könnte User 1000 trotzdem Root werden. User Namespaces (Remapping) sind eine extra Schicht Sicherheit.Kubernetes?
Man nutztsecurityContextim Pod:runAsNonRoot: true. K8s verweigert den Start, wenn das Image als Root laufen will. Wichtig für Policy (OPA Gatekeeper).
Zusammenfassung
- Standardmäßig ist der "Root"-User im Docker Container auch der "Root"-User auf dem Host-Server. Er hat zwar eingeschränkte Sicht (Namespaces), aber wenn er ausbricht (Container Escape), ist er Gott auf deinem Server. Ein Unprivileged Container läuft zwar im...
- Der einfache Weg (Non-Root User): Im Dockerfile: dockerfile USER 1001 Der Prozess läuft als User 1001. Er darf keine Systemdateien anfassen und keine Privileged Ports (< 1024) binden.
Optionale Praxisaufgabe
- Erkläre Unprivileged Container in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Unprivileged Container relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Least Privilege S1
Überblick: Gib einem Handwerker nicht deinen ganzen Schlüsselbund, sondern nur den Schlüssel für den Keller. Gib einer App nicht Admin-Rechte ("God Mode"), wenn sie nur Logfiles schreiben muss. Das Prinzip der geringsten Rechte (Principle of Least Privilege). Jeder User und jedes Programm bekommt nur genau so viele Rechte, wie es unbedingt braucht, um die Arbeit zu tun. Nicht mehr. Warum? Wenn die App gehackt wird, kann der Hacker nur Logfiles schreiben, aber nicht die Datenbank löschen. Der Schaden ("Blast Radius") ist begrenzt.
Was ist "Privilege Escalation"?
Der Angriff, bei dem man mit wenig Rechten anfängt (User) und eine Lücke nutzt, um mehr Rechte zu bekommen (Root). Least Privilege erschwert das, verhindert es aber nicht (Kernel Bugs).Ist es unbequem?
Ja. Zu wenig Rechte -> "Permission Denied". Entwickler hassen es ("Mach mir einfach Full Access, damit es läuft!"). Sicherheit ist immer ein Trade-Off mit Bequemlichkeit ("Friction").Wie finde ich die "Least Privileges"?
Schwer. Man fängt oft restriktiv an, schaut in die Audit-Logs ("Access Denied"), und gibt dann genau dieses Recht dazu. Tools wie AWS IAM Access Analyzer helfen dabei ("Dieser User hat S3FullAccess, nutzt aber seit 90 Tagen nur Read. Ich schlage ReadOnly vor.").
Schritt 28 / 35
Kubernetes
Der Schritt von einzelnen Hosts zu Orchestrierung.
S1
Schritt 28 / 35
Kubernetes
Der Schritt von einzelnen Hosts zu Orchestrierung.
1. Verstehen
Stell dir vor, du hast 1 Container (Lunchbox). Den trägst du leicht selbst. Stell dir vor, du hast 10.000 Container (einen Frachtschiff-Hafen). Du brauchst einen Kranführer, der den Überblick behält. "Container A muss auf Schiff B. Container C ist abgestürzt, wir brauchen einen neuen." Kubernetes (K8s) ist dieser Kranführer für Software-Container. Es wurde von Google erfunden (die starten Milliarden Container pro Woche) und steuert riesige Server-Flotten automatisch.
Merksatz: Ein Open-Source-System zur Automatisierung der Bereitstellung, Skalierung und Verwaltung von Container-Anwendungen.
2. Anwenden
Du sagst Kubernetes nicht: "Starte Server X". Du gibst ihm einen Wunschzettel (YAML-Datei): "Ich hätte gerne immer 3 Kopien meiner Webseite. Sie sollen auf Servern mit viel RAM laufen." Kubernetes macht den Rest:
- Es sucht freie Server.
- Es startet die 3 Kopien.
- Wenn eine abstürzt, startet es sofort eine neue (Self-Healing).
Sobald mehrere Teams und Services im Cluster laufen, begrenzt eine Network Policy (Kubernetes), welche Pods miteinander sprechen dürfen. Ohne solche Regeln ist ein Cluster zwar funktional, aber schwerer sauber zu segmentieren.
Praxisroutine
In der Praxis lernst du Kubernetes, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Pods
Kubernetes kennt keine "Container". Die kleinste Einheit ist ein Pod. Ein Pod ist wie eine Erbsenschote: Meist ist nur 1 Erbse (Container) drin, manchmal aber auch zwei, die sich eng umarmen (z. B. ein Log-Collector-Container direkt neben der App).
2. Service Discovery
Wenn Pod A mit Pod B reden will, ist das schwer, weil Pods ständig sterben und neu starten (neue IP). Kubernetes bietet Services: Eine stabile Telefonnummer für eine Gruppe von Pods. "Ruf Service B an", und Kubernetes leitet dich zu einem der gerade lebenden Pods weiter.
Technische Einordnung im System
Technisch ist Kubernetes nicht isoliert. Es wirkt mit Nachbarbegriffen zusammen, hat Voraussetzungen und erzeugt Folgen. Für ein robustes Verständnis prüfst du drei Fragen: Welche Daten oder Bedingungen braucht dieser Schritt? Welche Ausgabe oder Wirkung entsteht? Was passiert bei falschen, fehlenden oder zu großen Eingaben?
Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
4. Vertiefen
1. Control Plane Architecture (etcd)
K8s ist ein gewaltiges State-Machine Cluster.
In der Control Plane (dem Hirn von K8s) liegt die Quelle der Wahrheit: etcd. Ein hochverfügbarer, verteilter Key-Value Store (basierend auf dem Raft-Konsensalgorithmus). Dort liegt der YAML-Wunsch.
Der Rest von K8s besteht aus endlosen "Controlern" (Scheduler, ReplicaSet-Controller). Diese Controller laufen in der Schleife und fragen sich sekündlich: "Was ist der Ist-Zustand des RZs? Und was ist der Soll-Zustand in etcd?". Stimmen sie nicht überein (eine Node brannte ab, ReplicaCount ging von 3 auf 2 runter), greift der Controller ein und startet einen Pod. Das gesamte System reagiert asynchron auf State-Drifts in etcd.
2. CNI und Kube-Proxy (Networking)
Wie spricht Pod A auf Server 1 mit Pod B auf Server 2?
Mit rohem Docker ist das ein Albtraum. Kubernetes nutzt CNI (Container Network Interface) Plugins (Calico, Cilium). Diese erzeugen ein "Overlay Network" (Flannel). Jeder Pod erhält intern die Illusion eines gigantischen, flachen L2-LANs, auch wenn die physischen Server im Rechenzentrum dutzende Router dazwischen haben.
Der kube-proxy ist zudem ein winziger Daemon auf jeder physischen Node, welcher rohe Linux iptables (oder eBPF) manipuliert. Er ist der Grund, warum ein K8s-Service IPX an tausende Pods loadbalancen kann, ohne jemals einen traditionellen Hardware-Router der Telekom zu benötigen.
3. eBPF und Cilium (Die nächste Generation K8s)
kube-proxy und rohe iptables stoßen bei massiver Skalierung (100.000 Services) extrem an Leistungsgrenzen (Lineare Suchzeiten für Routing).
Die Lösung ist eBPF (Extended Berkeley Packet Filter). Es erlaubt das Ausführen von blitzschnellem C-Bytecode direkt im Linux-Kernel-Space, ohne das Kernel-Modul zu modifizieren. K8s CNI Plugins wie Cilium nutzen eBPF. Damit greifen sie Traffic, Security-Policys und Observability gnadenlos tief "im Hardware-Kern" ab. Latenzen stürzen ab, und Container in Kubernetes können auf Netzwerkebene nahezu Bare-Metal Geschwindigkeiten erreichen.
5. Prüfen
Ist Kubernetes schwer?
Ja, extrem. Es gilt als eines der komplexesten Tools der IT. Für kleine Webseiten ist es völliger Overkill ("Kanonen auf Spatzen"). Da reicht Docker Compose.Was heißt "K8s"?
Zwischen dem "K" und dem "s" stehen 8 Buchstaben (ubernete). IT-ler sind faul beim Tippen. (Genauso wie "i18n" für Internationalization).Wer nutzt es?
Fast jeder Enterprise-Konzern (Spotify, Adidas, Mercedes). Es ist der Standard für moderne Cloud-Infrastruktur.
Zusammenfassung
- Stell dir vor, du hast 1 Container (Lunchbox). Den trägst du leicht selbst. Stell dir vor, du hast 10.000 Container (einen Frachtschiff-Hafen). Du brauchst einen Kranführer, der den Überblick behält. "Container A muss auf Schiff B. Container C ist abgestürzt,...
- Du sagst Kubernetes nicht: "Starte Server X". Du gibst ihm einen Wunschzettel (YAML-Datei): "Ich hätte gerne immer 3 Kopien meiner Webseite. Sie sollen auf Servern mit viel RAM laufen." Kubernetes macht den Rest: Es sucht freie Server. Es startet die 3...
- Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Optionale Praxisaufgabe
- Erkläre Kubernetes in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Kubernetes relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Server S1
Überblick: Ein Server ist ein Diener (engl. "to serve" = dienen). Es ist ein Computer, der darauf wartet, dass andere (Clients) etwas von ihm wollen. Webserver: "Zeig mir diese Webseite!" Mailserver: "Nimm meine E-Mail an!" Fileserver: "Speichere diese Datei!"
Einfach erklärt: Im Büro steht oft ein "Serverraum". Da steht der Firmenserver. Darauf liegen alle Word-Dateien, damit alle Kollegen gleichzeitig darauf zugreifen können. Wenn der Server abstürzt, kann keiner arbeiten ("Das Netz ist weg").
Tiefer verstanden: Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Braucht ein Server einen Bildschirm?
Nein. Man verwaltet ihn "headless" (kopflos) über das Netzwerk (Fernwartung mit SSH oder Remote Desktop). Ein Monitor steht nur für Notfälle im Serverraum.Was ist "Server Down"?
Der Server reagiert nicht. Gründe: Stromausfall, Internet weg, abgestürzt oder überlastet (DDoS).Warum sind Server so laut?
Wegen den Lüftern. Sie erzeugen enorme Hitze und müssen extrem gekühlt werden. Die kleinen Lüfter drehen mit 15.000 Umdrehungen pro Minute und klingen wie ein Triebwerk.
Microservices S1
Überblick: Stell dir ein riesiges Schweizer Taschenmesser vor, das 10 Kilo wiegt (Monolith). Es hat Löffel, Säge, Lupe und Zange. Wenn die Säge bricht, musst du das ganze Messer zur Reparatur geben. Du hast keinen Löffel mehr.
Einfach erklärt: Amazon.com ist nicht eine Webseite. Es sind hunderte Microservices. Service A: Zeigt Produkte an. Service B: Verwaltet den Warenkorb. Service C: Schreibt Rechnungen. Service D: Empfiehlt ähnliche Produkte.
Tiefer verstanden: Diese Sicht ist wichtig, weil echte Systeme selten am Hauptpfad scheitern. Sie scheitern an Randfällen, Berechtigungen, Zeitpunkten, Formaten, Reihenfolgen oder stillen Annahmen.
Sind Microservices immer besser?
Nein! Für kleine Startups sind sie der "Overkill". Sie sind extrem komplex zu verwalten (Deployment, Netzwerk). Fang mit einem Monolithen an. Zerlege ihn erst, wenn du groß bist.Wie groß ist ein "Micro"-Service?
Faustregel: Er sollte von einem kleinen Team ("Two Pizza Team", 5-8 Leute) komplett verstanden und gewartet werden können.Brauche ich Docker dafür?
Praktisch ja. Man kann Microservices auch so betreiben, aber Container sind das ideale Zuhause für sie. Jeder Service bekommt seinen eigenen Container.
Cloud Computing S1
Überblick: "Die Cloud" ist einfach nur der Computer von jemand anderem. Statt deine Fotos auf deiner Festplatte zu speichern, speicherst du sie auf den Festplatten von Google oder Apple. Statt einen teuren Server in den Keller zu stellen, mietest du Rechenpower bei Amazon (AWS).
Einfach erklärt: Wir nutzen die Cloud ständig: 1. SaaS (Software as a Service): Netflix, Gmail, Spotify. Die App läuft nicht bei dir, sondern auf deren Servern. 2. IaaS (Infrastructure as a Service): Als Firma mietest du "nackte" Server bei AWS, um darauf deine eigene Software laufen zu lassen. 3. Storage: Dropbox, Google Drive, iCloud. Deine Dateien sind überall verfügbar, egal ob Handy oder Laptop.
Wo sind meine Daten, wenn sie "in der Cloud" sind?
Auf physischen Servern in einem Rechenzentrum (Data Center), das meistens einem Tech-Giganten (Amazon, Google, Microsoft) gehört.Ist die Cloud sicher?
Meistens sicherer als dein eigener PC, weil Profis die Server bewachen. Aber: Du bist dafür verantwortlich, gute Passwörter zu nutzen (Shared Responsibility Model).Warum lieben Start-ups die Cloud?
Weil sie keine teure Hardware kaufen müssen (niedrige Investitionskosten = CAPEX) und sofort weltweit wachsen können.
Network Policy (Kubernetes) S2
Überblick: In Kubernetes dürfen standardmäßig alle mit allen reden. Pod A (dev) kann Datenbank Z (prod) scannen. Das ist unsicher (Zero Trust Albtraum). Eine Network Policy ist eine Firewall-Regel innerhalb des Clusters. Du sagst: "Datenbank Z darf nur von App Z angesprochen werden. Sonst niemandem." Das CNI-Plugin (der Netzwerk-Hausmeister) setzt das durch. Verkehr, der nicht explizit erlaubt ist, wird blockiert (Deny-All Strategie empfohlen).
Einfach erklärt: Der "Deny-All" Standard (sollte jeder Namespace haben): yaml kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} Alle Pods policyTypes: - Ingress Eingehend verboten Dann explizit öffnen ("Allow DB Access"): yaml spec: podSelector: matchLabels: app: db ingress: - from: - podSelector: matchLabels: app: backend ports: - port: 5432
Sind Policies Stateful?
Ja (wie iptables). Wenn ich "Ingress" erlaube, ist die Antwort ("Egress") automatisch erlaubt. Ich muss nicht beide Richtungen definieren.Was passiert ohne Policy?
"Allow Any". Alles ist offen. Das ist der Default-Zustand ("Flat Network") eines K8s Clusters.Debuggen?
Schrecklich schwer. "Warum geht der Request nicht durch?".kubectlzeigt keine Logs von gedroppten Paketen. Man braucht CNI-spezifische Tools (wiecilium monitoroder Hubble UI), um "Policy Verdict: DROP" zu visualisieren.
Schritt 29 / 35
Pod (Kubernetes)
Die kleinste laufende Einheit in Kubernetes.
S1
Schritt 29 / 35
Pod (Kubernetes)
Die kleinste laufende Einheit in Kubernetes.
1. Verstehen
In Docker ist der Container die kleinste Einheit.
In Kubernetes nicht. Da ist der Pod die kleinste Einheit.
Ein Pod ist eine Hülle um einen oder mehrere Container.
Warum?
Manchmal gehören zwei Container untrennbar zusammen (wie Erbse und Möhre).
Beispiel: Ein Webserver (Nginx) und ein Log-Shipper (Fluentd), der die Logs des Webservers hochlädt.
Sie müssen auf demselben Server landen. Sie müssen sich die IP teilen (localhost).
Der Pod garantiert das.
Du startest nie einen Container direkt. Du startest einen Pod (der einen Container enthält).
Merksatz: Die kleinste deploybare Recheneinheit in Kubernetes, bestehend aus einem oder mehreren Containern, die sich Speicher, Netzwerk und Spezifikationen teilen.
2. Anwenden
YAML "Manifest":
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-app
image: nginx
kubectl apply -f pod.yaml.
kubectl get pods.
Wichtig: Ein Pod ist vergänglich. Wenn er stirbt, ist er weg.
In Produktion nutzt du deshalb nie kind: Pod, sondern kind: Deployment (das Pods automatisch neu startet).
Praxisroutine
In der Praxis lernst du Pod (Kubernetes), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Shared Namespaces
Alle Container im Pod teilen sich:
- Network Namespace: Gleiche IP, gleicher Port-Bereich. Container A erreicht Container B über
localhost:8080. - IPC Namespace: Können über Shared Memory kommunizieren.
- UTS Namespace: Gleicher Hostname. Sie teilen sich nicht:
- PID Namespace: Jeder hat eigene Prozess-IDs (PID 1). (Außer
shareProcessNamespace: trueist gesetzt). - Filesystem: Jeder hat sein eigenes Image. Daten teilen geht nur über Volumes (
emptyDir).
2. Der "Pause" Container
Wenn du docker ps auf dem Node machst, siehst du für jeden Pod einen versteckten Container: k8s_POD_... pause.
Das ist der Pause Container.
Er tut nichts (schläft).
Sein einziger Job ist es, den Network Namespace offen zu halten.
Die "echten" Container (Nginx, Logsidecar) klinken sich in seinen Namespace ein.
Wenn Nginx crasht und neu startet, bleibt die IP gleich, weil der Pause Container (der Anker) weiterlebt.
3. Lifecycle (Phases vs Conditions)
Ein Pod hat einen Status (Phase): Pending -> Running -> Succeeded/Failed.
Aber das reicht nicht.
Ist er bereit (Ready)? Lebt er noch (Liveness)?
K8s nutzt Conditions: PodScheduled, Initialized, Ready.
Ein Pod ist Running, aber Ready: False, wenn der Readiness Probe fehlschlägt.
Services schicken nur Traffic an Ready: True.
Admins müssen lernen, kubectl describe pod zu lesen und Conditions zu verstehen.
4. Vertiefen
1. Init-Container (Die Vorarbeiter)
Neben dem Haupt-Container (z.B. die Spring-Boot-App) und Sidecars (Logs) hat ein Pod das Features der Init-Container. Init-Container starten strikt vor den App-Containern und müssen erfolgreich terminieren (Exit 0). Sie blockieren den Startup-Prozess des gesamten Pods. Nutzen: Stell dir vor, deine Webapp braucht dringend Datenbank-Strukturen. Der Init-Container bootet asynchron, pingt die Postgres-Datenbank alle 5 Sekunden bis sie aktiv antwortet, spielt die DDL-Migrationen (Flyway) ein, und beendet sich. Erst dann öffnet K8s dem echten App-Container den Lifecycle-Gate. Dies entkoppelt fehleranfälligen Set-up Code tiefgreifend vom eigentlichen Microservice. Wenn Init 1 fehlschlägt, fängt K8s mit Backoff-Timer von vorne an.
2. Pod Sandbox (CRI & Linux Kernel Isolation)
Was stoppt Container A physisch davon, den RAM von Container B zu fressen?
Die Kubelet-API kommuniziert über das CRI (Container Runtime Interface) mit containerd oder CRI-O. Die Runtime wendet knallharte Linux Control Groups (cgroups v2) bei Erzeugung der Pod-Sandbox an. Der Node-Kernel kapselt den Pod ein – eine Limit-Rule (memory=500Mi) ist somit kein App-Tipp, sondern ein Kernel-Gesetz.
Überschreitet Nginx die Grenze deines Java-Mem Leaks auch nur um 1 Byte, feuert der Linux OOM-Killer radikal SIGKILL tief im Kernel space, was den Container exekutiert und die API benachrichtigt. kubectl get pods zeigt "OOMKilled". Die cgroups garantieren Multi-Tenancy-Ressourcen fairness auf Cluster-Hardware.
3. QOS Classes (Quality of Service Classes)
Ein Worker Node (64GB RAM) betreibt 20 Pods. Nun knallt der Traffic hart ins Setup, alle Pods fordern mehr Speicher im Limit-Burst an, der Server droht mit einem Kernel-Panic wegzubrechen. Wen killt Kubelet zuerst? Kubernetes nutzt QoS-Klassen, basierend auf den YAML Requests/Limits:
Guaranteed: (Request = Limit). Aristokratie. Diese Pods werden als allerletztes vom OOM-Killer liquidiert. Perfekt für Prod-Datenbanken.Burstable: (Request < Limit). Mittelklasse.BestEffort: (Kein Request/Limit gesetzt). Bauernopfer. Der Node tötet diese Pods absolut mitleidlos bei der kleinsten Ressourcen-Enge gnadenlos ab.
5. Prüfen
Warum Mehrere Container?
Sidecar Pattern. Ein Hauptcontainer (App) und Helfer (Proxy, Logger, Backup-Agent). Sie sind eine "logische Einheit". Skalieren immer zusammen (1 App = 1 Sidecar).Kann ein Pod auf 2 Nodes laufen?
Niemals. Ein Pod ist atomar. Er landet ganz oder gar nicht auf einem Node. Wenn du Skalierung brauchst, startest du mehrere Pods (Replicas).Static Pods?
Spezialfall. Pods, die nicht vom API-Server, sondern direkt vom Kubelet auf dem Node (aus/etc/kubernetes/manifests) gestartet werden. Das wird genutzt, um den Cluster selbst (etcd, api-server) zu starten ("Bootstrapping").
Zusammenfassung
- In Docker ist der Container die kleinste Einheit. In Kubernetes nicht. Da ist der Pod die kleinste Einheit. Ein Pod ist eine Hülle um einen oder mehrere Container. Warum? Manchmal gehören zwei Container untrennbar zusammen (wie Erbse und Möhre). Beispiel: Ein...
- YAML "Manifest": yaml apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-app image: nginx kubectl apply -f pod.yaml. kubectl get pods. Wichtig: Ein Pod ist vergänglich. Wenn er stirbt, ist er weg. In Produktion nutzt du deshalb nie...
Optionale Praxisaufgabe
- Erkläre Pod (Kubernetes) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Pod (Kubernetes) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Deployment (K8s) S1
Überblick: Der Pod ist die kleinste Einheit in Kubernetes (ein Container). Aber du erstellst Pods fast nie direkt. Warum? Weil Pods sterblich sind. Wenn sie abstürzen, sind sie weg. Du willst aber, dass deine App immer läuft. Dafür gibt es das Deployment. Du sagst dem Deployment: "Sorge dafür, dass immer 3 Kopien (Replicas) meiner App laufen." Das Deployment ist der Manager. Es überwacht die Pods. Wenn einer stirbt, startet es sofort einen neuen. Und wenn du eine neue Version hast ("Update auf v2"), regelt das Deployment den Austausch (Rolling Update) ohne Ausfallzeit.
Einfach erklärt: Die wichtigste YAML-Datei in deinem Leben: yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 Ich will 3 Stück selector: matchLabels: app: nginx template: Bauplan für den Pod metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 Version v1 kubectl apply -f deploy.yaml. Update auf v2? Ändere nginx:1.14.2 zu nginx:latest und kubectl apply. Kubernetes tauscht die Pods Stück für Stück aus.
Kann ich Stateful Apps (Datenbanken) deployen?
Technisch ja, aber schlecht. Deployments geben Pods zufällige Namen (nginx-7b4f...). Datenbanken brauchen oft feste IDs ("db-0", "db-1") und stabile Speicher. Dafür gibt es StatefulSets.Was ist
kubectl scale?Ein imperativer Befehl, umreplicaszu ändern. Achtung: Wenn in deiner YAML nochreplicas: 3steht und du machstapply(GitOps), wird dein manuelles Scaling überschrieben!Paused Deployment?
Du kannst ein Deployment pausieren (kubectl rollout pause). Dann kannst du Bild, RAM, CPU ändern, ohne dass sofort Updates loslaufen. Erst beimresumewird alles angewendet. Nützlich für "Canary"-artige manuelle Tests.
Service S1
Überblick: Ein Service ist ein laufender Dienst, der eine bestimmte Aufgabe für andere Nutzer, Programme oder Systeme erledigt. Ein Webserver liefert Webseiten, ein Datenbankdienst speichert Daten, ein API-Service beantwortet Anfragen.
Einfach erklärt: Im Betrieb fragt man: Läuft der Service? Ist er erreichbar? Hat er Logs? Welche Abhaengigkeiten braucht er? In modernen Systemen werden Services oft automatisch gestartet, überwacht, skaliert und bei Fehlern neu gestartet.
Tiefer verstanden: Services haben Schnittstellen, Konfiguration, Laufzeitumgebung, Healthchecks und Abhaengigkeiten. Ein Service kann monolithisch, als Microservice, als Kubernetes Service oder als Hintergrunddienst auftreten. Wichtig ist die klare Grenze: Was gehört hinein, was nicht?
Praxisgrenze: Zu viele kleine Services erzeugen Netzwerk- und Betriebsaufwand. Zu große Services werden schwer wartbar. Ohne Healthchecks, Logs, Metriken und Deployment-Konzept ist ein Service im Fehlerfall schwer zu betreiben.
Was ist ein Service?
Ein laufender Dienst mit einer konkreten Aufgabe und meist einer Schnittstelle.Warum sind Healthchecks wichtig?
Sie zeigen automatisiert, ob ein Service erreichbar und funktionsfähig ist.Was ist eine typische Falle?
Services zu schneiden, ohne klare Verantwortlichkeiten und Betriebsgrenzen zu definieren.
Schritt 30 / 35
Service (K8s)
Pods stabil erreichbar machen.
S1
Schritt 30 / 35
Service (K8s)
Pods stabil erreichbar machen.
1. Verstehen
Pods sind sterblich. Ihre IP-Adressen ändern sich ständig (Neustart = neue IP).
Wie soll das Frontend das Backend finden, wenn die IP, die ich in die Config schreibe, morgen falsch ist?
Der Service ist die stabile Adresse (der Anker).
Er bekommt eine feste IP (ClusterIP) und einen DNS-Namen (my-backend).
Er leitet Anrufe an einen der gerade lebenden Pods weiter ("Load Balancing").
Auch wenn alle Backend-Pods sterben und neu aufstehen (neue IPs), bleibt die Service-IP gleich.
Das Frontend ruft immer nur den Service an.
Merksatz: Eine Abstraktionsschicht in Kubernetes, die eine logische Gruppe von Pods definiert und eine stabile Netzwerk-Vorschrift (IP und DNS) bereitstellt, um auf sie zuzugreifen.
2. Anwenden
Du definierst einen Service "my-service", der auf Port 80 lauscht und zu Pods mit Label app: backend auf Port 8080 weiterleitet.
selector:
app: backend
ports:
- port: 80
targetPort: 8080
Andere Pods im Cluster können jetzt curl http://my-service machen.
K8s DNS löst das auf die Service-IP auf.
Praxisroutine
In der Praxis lernst du Service (K8s), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Kube-Proxy & Iptables
Der Service ist kein "Prozess". ps aux zeigt keinen "Service".
Es ist nur eine Iptables-Regel auf jedem Node!
Der kube-proxy schreibt Regeln:
"Wenn Paket an Service-IP geht -> Würfel zufällig einen Pod aus der Liste -> DNAT zur Pod-IP."
Das ist extrem schnell (Kernel-Space), aber schwer zu debuggen.
Modern: IPVS (IP Virtual Server) statt Iptables für große Cluster (>1000 Services), weil Iptables bei vielen Regeln langsam wird (O(n)).
2. Endpoints Objekt
Der Service speichert nicht selbst, welche Pods dazu gehören.
Dafür gibt es das Endpoints Objekt.
Service Name -> Endpoints Name -> Liste von IPs (10.1.0.5, 10.1.2.3).
Wenn ein Pod Ready ist, fügt der Endpoint-Controller die IP zur Liste hinzu.
Wenn er crasht, nimmt er sie raus.
Experten-Hack: Du kannst einen Service ohne Selector bauen und das Endpoints-Objekt manuell füllen (z. B. um auf eine externe DB außerhalb des Clusters zu zeigen).
3. Headless Services
Manchmal will der Client kein LoadBalancing.
Er will alle Pod-IPs wissen (z. B. Cassandra Cluster, wo jeder Node wichtig ist).
Setze clusterIP: None im YAML.
DNS my-service liefert jetzt nicht eine Service-IP, sondern eine Liste ("A Records") von allen Pod-IPs.
Client kann sich verbinden ("Client-Side Load Balancing").
4. Vertiefen
1. IPVS Mode vs. Iptables Mode
Wie oben erwähnt, wird die Magie meist durch iptables gelöst. Dort ist die Performance jedoch O(n) – je mehr Regeln, desto länger sucht das Paket nach dem Ausgang.
Im IPVS Mode (IP Virtual Server) nutzt Kubernetes einen echten Layer-4 Load Balancer im Kernel.
Vorteil: Er nutzt Hash-Tabellen (O(1) Performance). Egal ob 10 oder 10.000 Services, die Geschwindigkeit bleibt fast identisch. Zudem unterstützt IPVS komplexere Load-Balancing Algorithmen wie Least-Connection (schicke das Paket an den Pod, der gerade am wenigsten zu tun hat), während Iptables meist nur stures Round-Robin (Zufall) kann.
2. Hairpin Mode & Local Traffic Policy
Ein klassisches Problem: Pod A möchte über den Service auf sich selbst zugreifen (Loopback).
In manchen Netzwerk-Setups blockt die Firewall das, weil das Paket "raus" geht und sofort wieder "rein" will. Kubernetes aktiviert dafür den Hairpin Mode (oder Promiscuous Mode am Bridge-Interface), damit Pakete die Kurve kriegen.
Ein weiteres wichtiges Feature ist externalTrafficPolicy: Local.
Normalerweise schickt die Service-IP das Paket an irgendeinen Pod im ganzen Cluster (ggf. über das Netzwerk auf einen anderen Node). Bei Local verwirft der Node das Paket, wenn auf ihm selbst kein passender Pod läuft. Das erhält die Quell-IP des Nutzers (Source IP Preservation), die sonst durch das SNAT des Clusters verloren ginge.
3. Service Discovery via Environment Variables
Bevor K8s DNS (CoreDNS) zum Standard wurde, war die einzige Art, einen Service zu finden, über Umgebungsvariablen.
Kubernetes injiziert in jeden Pod beim Start Variablen wie MY_BACKEND_SERVICE_HOST und MY_BACKEND_SERVICE_PORT.
Problem: Das funktioniert nur, wenn der Service vor dem Pod erstellt wurde. Wenn du den Service löschst und neu erstellst, hat der laufende Pod veraltete Variablen. Deshalb ist heute DNS der de-facto Standard, aber du findest diese "Geister-Variablen" immer noch in fast jedem Pod-Log, wenn du env tippst.
5. Prüfen
Service vs Ingress?
Service ist Layer 4 (TCP/UDP). Er versteht keine URLs. Ingress ist Layer 7 (HTTP) und sitzt vor den Services. Ingress routet nach Hostname, Service routet nach Label.Session Affinity?
Standardmäßig ist Round-Robin (Zufall). MitsessionAffinity: ClientIPkannst du erzwingen, dass User X immer beim gleichen Pod landet ("Sticky Session"). Wichtig für alte Apps mit lokalem Session Storage.Service Mesh?
Ersetzt den klassischenkube-proxyService oft durch intelligente Sidecars (Envoy). Damit gehen Canary Releases ("5% Traffic an v2") und Retries, was normale Services nicht können.
Zusammenfassung
- Pods sind sterblich. Ihre IP-Adressen ändern sich ständig (Neustart = neue IP). Wie soll das Frontend das Backend finden, wenn die IP, die ich in die Config schreibe, morgen falsch ist? Der Service ist die stabile Adresse (der Anker). Er bekommt eine feste IP...
- Du definierst einen Service "my-service", der auf Port 80 lauscht und zu Pods mit Label app: backend auf Port 8080 weiterleitet. yaml selector: app: backend ports: - port: 80 targetPort: 8080 Andere Pods im Cluster können jetzt curl http://my-service machen....
Optionale Praxisaufgabe
- Erkläre Service (K8s) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Service (K8s) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
ClusterIP S2
Überblick: In einem Kubernetes-Cluster laufen deine Anwendungen in Pods. Pods sterben ständig und starten neu (Updates, Abstürze). Dabei bekommen sie jedes Mal eine neue IP-Adresse. Das ist ein Problem: Wie soll deine "Frontend"-App die "Datenbank"-App anrufen, wenn sich deren IP jede Minute ändert? ClusterIP ist die Lösung. Es ist eine stabile, "magische" IP-Adresse, die sich nie ändert. Kubernetes gibt sie deinem Service. "Ruf einfach 10.96.0.1 (die ClusterIP) an. Wir leiten dich automatisch an den aktuell laufenden Pod weiter." Es ist der interne Telefonbucheintrag im Cluster.
Einfach erklärt: In YAML: yaml apiVersion: v1 kind: Service metadata: name: my-backend spec: selector: app: backend-app Ziel-Pods ports: - port: 80 Port der ClusterIP targetPort: 8080 Port im Container type: ClusterIP Default (muss nicht angegeben werden) Ergebnis: kubectl get svc zeigt 10.96.x.x. Andere Pods im Cluster können nun http://my-backend (DNS) aufrufen. Kubernetes löst das zu der stabilen IP auf.
Kann ich ClusterIP vom Internet erreichen?
Nein! Sie ist strikt intern (RFC 1918 Private Ranges, meist 10.x.x.x im Service CIDR). Um von außen reinzukommen, brauchst duNodePort,LoadBalanceroderIngress.Was passiert, wenn alle Pods tot sind?
Die ClusterIP existiert noch, aber die Verbindung läuft ins Leere (Connection Refused oder Timeout), weil iptables kein gültiges Ziel (Endpoint) mehr hat.Session Affinity?
Standardmäßig ist es "Round Robin" (Zufall). Du kannstsessionAffinity: ClientIPsetzen, dann landet die gleiche Source-IP immer beim gleichen Pod (bis zum Timeout). Wichtig für Caching.
NodePort (K8s Service) S1
Überblick: Stell dir vor, dein Kubernetes Cluster ist ein Hochhaus. Jedes Zimmer (Pod) hat eine Telefonnummer (IP), aber die kann man von draußen nicht anrufen. Ein NodePort ist ein Loch in der Außenwand. Du bohrst ein Loch in jeden Stock (Node) an der gleichen Stelle (Port 30080). Wenn jemand von der Straße (Internet) irgendeinen Stock auf Port 30080 anruft, wird er direkt zum richtigen Zimmer (Pod) verbunden. Das ist der primitivste Weg, um eine App nach draußen verfügbar zu machen. Nachteil: Du musst dir Ports merken (z. B. "App A ist 30001, App B ist 30002"). Und du hast nur 2768 Löcher (Ports 30000-32767).
Einfach erklärt: YAML: yaml apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: type: NodePort ports: - port: 80 (Service Port) targetPort: 8080 (Pod Port) nodePort: 30007 (Der Port außen!) selector: app: my-app Jetzt ist deine App erreichbar unter: http://node1-ip:30007 http://node2-ip:30007 Egal welche Node-IP du nimmst, Kubernetes (kube-proxy) routet es intern richtig weiter.
Is NodePort insecure?
Ja, wenn der Node direkt im Internet steht (Public IP). Jeder Port-Scanner findet deine App auf 30007. Du solltest eine Firewall (Security Group) davor haben, die nur deine Büro-IP erlaubt.Warum nutzen wir nicht immer NodePort?
Unbequem für Nutzer. Niemand tipptgoogle.com:30007. Du brauchst ein DNS-Namen und Port 80/443. NodePort ist gut für Admin-Tools oder Datenbanken, aber schlecht für Enduser-Webseiten.Port Kollision?
Wenn Team A Port 30001 wählt und Team B auch -> Deployment Fail. Kubernetes weist deshalb Ports zufällig zu, wenn dunodePort:im YAML weglässt. Das ist sicherer, aber dann musst du jedes Malkubectl get svcmachen, um den Port zu finden.
LoadBalancer (K8s Service) S2
Überblick: Du hast deine App im Cluster. Du willst, dass echte Menschen aus dem Internet sie erreichen. ClusterIP geht nur intern. NodePort ist hässlich (Port 30000+). Der LoadBalancer Service ist der Luxus-Weg. Du sagst Kubernetes: "Ich brauche eine echte, öffentliche IP-Adresse." Kubernetes ruft (wenn es in der Cloud läuft) bei AWS/Google/Azure an: "Hey, gib mir einen Cloud Load Balancer!" AWS erstellt einen echten Load Balancer, gibt dir eine echte IPv4 (35.1.2.3) und leitet Traffik von dort in deinen Cluster weiter. Es ist der einfachste Weg nach draußen ("Expose").
Einfach erklärt: YAML: yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - port: 80 targetPort: 8080 type: LoadBalancer Nach kubectl apply steht bei EXTERNAL-IP erst . Nach 1-2 Minuten steht dort die öffentliche IP. Jeder auf der Welt kann nun http:// aufrufen.
Was ist der Unterschied zu NodePort?
LoadBalancer baut auf NodePort auf. AWS routet Traffic anNodeIP:NodePort. Aber für den User ist es unsichtbar, er sieht nur die schöne LB-IP auf Port 80.Kann ich UDP balancen?
Ja, die meisten Clouds unterstützen das (z. B. für Game Server oder DNS). Ingress (HTTP) kann das meist nicht.Finalizers?
Wenn du den Service löschst, muss auch der AWS Load Balancer gelöscht werden (sonst zahlst du weiter!). Kubernetes nutzt "Finalizers", um sicherzustellen, dass erst die Cloud-Resource weg ist, bevor das K8s-Objekt verschwindet. Wenn LBs "hängen" bleiben, check die Finalizer!
Endpoint S1
Überblick: Wenn du in ein Restaurant gehst, gibt es verschiedene Schalter. Einen für "Bestellung aufgeben". Einen für "Essen abholen". Einen für "Bezahlen". Eine API (Kellner) im Internet funktioniert genauso. Die Schalter sind die Endpoints. Es sind spezifische URLs, an die du eine Nachricht schickst, um etwas Bestimmtes zu tun. https://api.shop.de/users - Liste aller User holen. https://api.shop.de/buy - Kaufen. Jeder Endpoint hat eine klare Aufgabe.
Einfach erklärt: Ein Endpoint besteht aus: 1. Methode: GET, POST, PUT, DELETE (Das Verb). 2. Pfad: /api/v1/products/123 (Das Nomen). In Express.js (Node Backend): javascript app.get('/products/:id', (req, res) = { // Endpoint Definition const id = req.params.id; // ... Hole Produkt aus DB }); Der Client ruft auf: GET /products/42.
Query Params vs. Path Params?
Path (/users/5) identifiziert eine eindeutige Ressource. Query (/users?role=admin) filtert oder sortiert. Wenn du eine Ressource meinst, nutze Path.Healthcheck Endpoint?
/healthoder/status. Ein spezieller Endpoint, der200 OKzurückgibt, wenn die DB Verbindung steht. Loadbalancer pingen diesen Endpoint alle 5 Sekunden, um zu wissen, ob der Server noch lebt.Was ist ein "Public Endpoint"?
Ein Endpoint ohne Authentifizierung (z. B. Login, Landing Page Dat). Alles hinter/admin/...sind "Protected Endpoints" (brauchen Token).
Schritt 31 / 35
Ingress
HTTP-Traffic von aussen in den Cluster fuehren.
S2
Schritt 31 / 35
Ingress
HTTP-Traffic von aussen in den Cluster fuehren.
1. Verstehen
Du hast 10 Services im Cluster (Webshop, Blog, Chat).
Du willst sie alle unter meine-firma.de erreichbar machen.
meine-firma.de/shop-> Service Ameine-firma.de/blog-> Service B Dafür brauchst du einen Empfangschef am Eingang. Das ist der Ingress. Er ist ein intelligenter Router (Reverse Proxy), der HTTP-Anfragen liest ("Ah, du willst zum Blog") und sie an den richtigen internen Service weiterleitet. Ohne Ingress bräuchtest du für jeden Service eine eigene teure öffentliche IP (LoadBalancer).
Merksatz: Ein Kubernetes-API-Objekt, das den externen Zugriff auf Dienste im Cluster verwaltet, typischerweise über HTTP/HTTPS, und Funktionen wie SSL-Terminierung und pfadbasiertes Routing bietet.
2. Anwenden
YAML "Wunschzettel":
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: shop.de
http:
paths:
- path: /api
backend:
service:
name: api-service
port: { number: 80 }
Wichtig: Das Ingress-Objekt allein tut nichts. Du brauchst einen Ingress Controller (ein Programm, das diesen Wunschzettel liest und umsetzt). Standard ist oft Nginx Ingress Controller oder Traefik.
Praxisroutine
In der Praxis lernst du Ingress, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Ingress vs. Gateway API
Ingress (die API) ist alt und limitiert.
Es kann nur HTTP(S). Kein TCP, kein UDP, keine komplexen Traffic-Splits (Canary 5%).
Jeder Controller (Nginx, HAProxy) hat eigene, inkompatible Annotationen erfunden (nginx.ingress.kubernetes.io/rewrite-target).
Die Zukunft ist die Gateway API.
Sie ist mächtiger, standardisiert und unterstützt Multi-Team Rollen (Infra-Team verwaltet Gateway, App-Team verwaltet Routes).
Ingress ist "Legacy", aber immer noch 90% Marktanteil.
2. SSL Termination
Der Ingress ist meistens der Punkt, wo HTTPS endet (Terminierung).
Er entschlüsselt das Paket. Ab da geht es oft unverschlüsselt (HTTP) weiter zu den Pods (Performance).
Der Ingress verwaltet die Zertifikate (oft automatisch via Cert-Manager + Let's Encrypt).
Du definierst im Ingress: tls: - secretName: my-cert.
Der Controller lädt das Zertifikat in den RAM.
3. Fanout & Name-based Virtual Hosting
Ingress spart Geld.
Du hast einen einzigen Cloud LoadBalancer (kostet 20€/Monat).
Dahinter hängt der Ingress Controller.
Der Ingress Controller bedient 100 Domains (a.com, b.com, c.com).
Er schaut in den Host-Header und routet intern.
Das nennt man Fanout.
Massive Skalierung mit minimaler Infrastruktur.
4. Vertiefen
In-Cluster Data Path (NodePort vs. HostPort)
Wie kommt der Traffic vom AWS LoadBalancer in den echten Nginx-Pod (den Controller)?
Hier existieren oft eklatante Missverständnisse.
Normalerweise wird der Ingress Controller via ServiceType: LoadBalancer exponiert. Der Cloud-LB schickt das Paket (via NodePort) blind an jeden Worker-Node (z. B. auf Port 31080). kube-proxy fängt das Paket per iptables ab und jagt es netzwerkintern zu dem Worker-Node, auf dem der Nginx-Pod tatsächlich lebt (Extra Hop).
Für massive Performance (Low Latency) schaltet man externalTrafficPolicy: Local. Dann leitet der Cloud-LB das Paket nur an die physikalischen Nodes weiter, auf denen auch wirklich ein Ingress-Pod läuft. Der Extra-Hop via kube-proxy entfällt komplett, und Source-IP-Adressen der Kunden bleiben erhalten statt von K8s NAT maskiert zu werden.
Header-Injection (X-Forwarded-For)
Sitzt dein App-Container hinter einem Ingress, verschleiert der Ingress als Proxy die originale IP des Endnutzers. Der Traffic scheint logisch vom Ingress-Pod zu stammen.
Damit Rate-Limiting oder Geo-IP-Auswertungen in der App nicht kollabieren, muss der Controller den HTTP-Header X-Forwarded-For (oder in neuerem Standard Forwarded) injizieren.
Bei mehrstufigen CDN-Setups (Cloudflare -> AWS LB -> Ingress) reichert jeder Proxy diesen Header iterativ um seine IP an. Die Application muss konfiguriert sein, dem Ingress (trust-proxy) zu glauben, sonst droht IP-Spoofing durch gefälschte Kunden-Header.
Ingress als Web Application Firewall (WAF)
Der Ingress ist der einzige Flaschenhals, durch den jeglicher externer Traffic fließen muss – ein perfekter Ort für Security. Enterprise-Controller (wie Nginx Plus oder ModSecurity-Module) verwandeln den simplen Router in eine WAF (Web Application Firewall). Noch bevor der Request den winzigen Python-Microservice erreicht, analysiert der Ingress den Payload auf verdächtige Regex-Muster (SQL-Injections, XSS-Cross-Site Scripting). Das Entkoppeln der WAF von der Applikation bedeutet, dass du alle 50 Microservices deines Clusters mit einer einzigen Zeile Konfiguration (Annotation im Ingress) global gegen Log4j-ähnliche Exploits absichern kannst, ohne jemals Code im Backend anpassen zu müssen.
5. Prüfen
Was ist eine IngressClass?
Wenn du zwei Controller hast (z. B. einen Nginx für Public Traffic, einen Traefik für Internal Traffic). MitingressClassName: publicsagst du, welcher Controller sich zuständig fühlen soll.Kann Ingress TCP?
Die API nicht. Aber der Nginx-Controller kann es über ConfigMaps (--tcp-services). Das ist aber ein "Hack". Für sauberes TCP Routing (Datenbanken) nutzt man besser Service Type LoadBalancer oder Gateway API.Pfad-Probleme?
Klassiker: Ingress/appleitet weiter an Service/. Die App bekommt Request auf/aber liefert Links zu/style.css(statt/app/style.css). Die Seite sieht kaputt aus. Lösung:RewriteAnnotationen oder (besser) App konfigurieren, dass sie unter/appläuft ("Base Path").
Zusammenfassung
- Du hast 10 Services im Cluster (Webshop, Blog, Chat). Du willst sie alle unter meine-firma.de erreichbar machen. meine-firma.de/shop - Service A meine-firma.de/blog - Service B Dafür brauchst du einen Empfangschef am Eingang. Das ist der Ingress. Er ist ein...
- YAML "Wunschzettel": yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - host: shop.de http: paths: - path: /api backend: service: name: api-service port: { number: 80 } Wichtig: Das Ingress-Objekt allein tut nichts....
Optionale Praxisaufgabe
- Erkläre Ingress in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Ingress relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Service S1
Überblick: Ein Service ist ein laufender Dienst, der eine bestimmte Aufgabe für andere Nutzer, Programme oder Systeme erledigt. Ein Webserver liefert Webseiten, ein Datenbankdienst speichert Daten, ein API-Service beantwortet Anfragen.
Einfach erklärt: Im Betrieb fragt man: Läuft der Service? Ist er erreichbar? Hat er Logs? Welche Abhaengigkeiten braucht er? In modernen Systemen werden Services oft automatisch gestartet, überwacht, skaliert und bei Fehlern neu gestartet.
Tiefer verstanden: Services haben Schnittstellen, Konfiguration, Laufzeitumgebung, Healthchecks und Abhaengigkeiten. Ein Service kann monolithisch, als Microservice, als Kubernetes Service oder als Hintergrunddienst auftreten. Wichtig ist die klare Grenze: Was gehört hinein, was nicht?
Praxisgrenze: Zu viele kleine Services erzeugen Netzwerk- und Betriebsaufwand. Zu große Services werden schwer wartbar. Ohne Healthchecks, Logs, Metriken und Deployment-Konzept ist ein Service im Fehlerfall schwer zu betreiben.
Was ist ein Service?
Ein laufender Dienst mit einer konkreten Aufgabe und meist einer Schnittstelle.Warum sind Healthchecks wichtig?
Sie zeigen automatisiert, ob ein Service erreichbar und funktionsfähig ist.Was ist eine typische Falle?
Services zu schneiden, ohne klare Verantwortlichkeiten und Betriebsgrenzen zu definieren.
ClusterIP S2
Überblick: In einem Kubernetes-Cluster laufen deine Anwendungen in Pods. Pods sterben ständig und starten neu (Updates, Abstürze). Dabei bekommen sie jedes Mal eine neue IP-Adresse. Das ist ein Problem: Wie soll deine "Frontend"-App die "Datenbank"-App anrufen, wenn sich deren IP jede Minute ändert? ClusterIP ist die Lösung. Es ist eine stabile, "magische" IP-Adresse, die sich nie ändert. Kubernetes gibt sie deinem Service. "Ruf einfach 10.96.0.1 (die ClusterIP) an. Wir leiten dich automatisch an den aktuell laufenden Pod weiter." Es ist der interne Telefonbucheintrag im Cluster.
Einfach erklärt: In YAML: yaml apiVersion: v1 kind: Service metadata: name: my-backend spec: selector: app: backend-app Ziel-Pods ports: - port: 80 Port der ClusterIP targetPort: 8080 Port im Container type: ClusterIP Default (muss nicht angegeben werden) Ergebnis: kubectl get svc zeigt 10.96.x.x. Andere Pods im Cluster können nun http://my-backend (DNS) aufrufen. Kubernetes löst das zu der stabilen IP auf.
Kann ich ClusterIP vom Internet erreichen?
Nein! Sie ist strikt intern (RFC 1918 Private Ranges, meist 10.x.x.x im Service CIDR). Um von außen reinzukommen, brauchst duNodePort,LoadBalanceroderIngress.Was passiert, wenn alle Pods tot sind?
Die ClusterIP existiert noch, aber die Verbindung läuft ins Leere (Connection Refused oder Timeout), weil iptables kein gültiges Ziel (Endpoint) mehr hat.Session Affinity?
Standardmäßig ist es "Round Robin" (Zufall). Du kannstsessionAffinity: ClientIPsetzen, dann landet die gleiche Source-IP immer beim gleichen Pod (bis zum Timeout). Wichtig für Caching.
HTTP S1
Überblick: HTTP ist die universelle Sprache des Internets. Jedes Mal, wenn du eine Webseite öffnest, eine App nutzt oder ein Video streamst, sprechen dein Gerät (Client) und der Server diese Sprache.
Welche HTTP-Methode nutzt dein Browser standardmäßig, wenn du eine Adresse in die Zeile tippst?
GET. Du forderst eine Ressource an, um sie anzuzeigen.Warum ist es technisch "schwierig", einen Warenkorb zu bauen, wenn HTTP stateless ist?
Weil der Server nach dem Hinzufügen des ersten Artikels sofort vergisst, wer du warst. Man muss den Zustand künstlich über Cookies/Sessions mitschleppen.Was bedeutet der Status Code 404 genau?
Der Server wurde erreicht (er lebt!), aber die Ressource (Datei/Seite), die du angefordert hast, liegt nicht an diesem Ort.
LoadBalancer (K8s Service) S2
Überblick: Du hast deine App im Cluster. Du willst, dass echte Menschen aus dem Internet sie erreichen. ClusterIP geht nur intern. NodePort ist hässlich (Port 30000+). Der LoadBalancer Service ist der Luxus-Weg. Du sagst Kubernetes: "Ich brauche eine echte, öffentliche IP-Adresse." Kubernetes ruft (wenn es in der Cloud läuft) bei AWS/Google/Azure an: "Hey, gib mir einen Cloud Load Balancer!" AWS erstellt einen echten Load Balancer, gibt dir eine echte IPv4 (35.1.2.3) und leitet Traffik von dort in deinen Cluster weiter. Es ist der einfachste Weg nach draußen ("Expose").
Einfach erklärt: YAML: yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - port: 80 targetPort: 8080 type: LoadBalancer Nach kubectl apply steht bei EXTERNAL-IP erst . Nach 1-2 Minuten steht dort die öffentliche IP. Jeder auf der Welt kann nun http:// aufrufen.
Was ist der Unterschied zu NodePort?
LoadBalancer baut auf NodePort auf. AWS routet Traffic anNodeIP:NodePort. Aber für den User ist es unsichtbar, er sieht nur die schöne LB-IP auf Port 80.Kann ich UDP balancen?
Ja, die meisten Clouds unterstützen das (z. B. für Game Server oder DNS). Ingress (HTTP) kann das meist nicht.Finalizers?
Wenn du den Service löschst, muss auch der AWS Load Balancer gelöscht werden (sonst zahlst du weiter!). Kubernetes nutzt "Finalizers", um sicherzustellen, dass erst die Cloud-Resource weg ist, bevor das K8s-Objekt verschwindet. Wenn LBs "hängen" bleiben, check die Finalizer!
Schritt 32 / 35
ConfigMap
Konfiguration vom Image trennen.
S2
Schritt 32 / 35
ConfigMap
Konfiguration vom Image trennen.
1. Verstehen
Früher hat man Konfigurationen fest in den Code geschrieben (db_host = "192.168.0.1"). Das ist böse.
Dann hat man sie in Dateien (config.ini) neben die .exe gelegt.
In Containern ist das schwierig, weil das Dateisystem flüchtig ist.
ConfigMap ist die Kubernetes-Lösung, um Konfiguration vom Code zu trennen (12-Factor App Prinzip).
Du speicherst deine nginx.conf oder game_settings.json als Objekt in der Kubernetes-Datenbank (etcd).
Beim Starten "injizierst" du diese Config in den Pod.
Vorteil: Du kannst das gleiche Docker-Image für "Dev", "Test" und "Prod" nutzen, nur mit unterschiedlichen ConfigMaps.
Merksatz: Ein Kubernetes API-Objekt zur Speicherung nicht-sensibler Konfigurationsdaten in Key-Value-Paaren, die Pods als Umgebungsvariablen, Befehlszeilenargumente oder Konfigurationsdateien nutzen können.
2. Anwenden
- Erstellen:
kubectl create configmap my-config --from-literal=color=blueOder per YAML:kind: ConfigMap data: app.properties: | color=blue mode=debug - Nutzen (als Env Var):
env: - name: APP_COLOR valueFrom: configMapKeyRef: name: my-config key: color - Nutzen (als Datei / Volume):
Du kannst die ganze ConfigMap als "virtuelles Laufwerk" mounten. Im Container taucht dann
/etc/config/app.propertiesauf.
Praxisroutine
In der Praxis lernst du ConfigMap, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Hot Reloading (Live Updates)
Wenn du eine ConfigMap änderst (kubectl edit cm), passiert im Pod... erstmal nichts.
Env Vars werden nur beim Start gelesen.
Aber: Wenn du sie als Volume mountest, aktualisiert Kubernetes die Datei im Container automatisch (mit leichter Verzögerung, ca. 1-2 Minuten, Kubelet Sync Period).
Moderne Apps nutzen "File Watcher" (z. B. Viper in Go oder Spring Cloud Config), um die Änderung zu bemerken und sich ohne Neustart neu zu konfigurieren.
Für Legacy-Apps brauchst du einen "Reloader Sidecar" (z. B. Reloader), der den Pod neustartet, wenn sich der Config-Hash ändert.
2. Immutable ConfigMaps
Seit K8s 1.19 kannst du immutable: true setzen.
Vorteil 1: Sicherheit (niemand pfuscht in der Prod-Config rum).
Vorteil 2: Performance. Der Kubelet muss nicht mehr pollen ("Hat sich was geändert?"), was die Last auf dem API-Server massiv senkt.
3. Size Limits
Etcd ist keine Festplatte. ConfigMaps sind auf 1 MB limitiert. Du kannst keine riesigen XML-Dateien oder Binaries darin speichern. Dafür brauchst du echte Volumes (PVC) oder Init-Container, die Daten von S3 laden.
4. Vertiefen
Symlink Magic bei Volume-Mounts
Wird eine ConfigMap als Datei gemountet (z. B. auf /etc/config/app.json), nutzt Kubernetes einen faszinierenden Trick, um Kubelet-CPU zu sparen.
Kubernetes mountet nicht direkt die Datei. Stattdessen erstellt es Unterordner mit Timestamps (..data_2023_10_01_12_00) und pflegt Symlinks.
Die gemountete Datei /etc/config/app.json ist lediglich ein Symlink auf den Ordner ..data, welcher wiederum ein Symlink auf den timestamp-Ordner ist.
Aktualisierst du die ConfigMap im API-Server, tauscht das Kubelet asynchron den Symlink von ..data blitzschnell (atomic) auf den neuen Timestamp-Ordner aus. Prozesse, die die Datei offen per File-Descriptor halten, lesen weiter die alte Version, aber Prozesse, die neu zugreifen oder auf IN_CREATE Events (inotify) lauschen, erfassen den Tausch.
Achtung: Dies funktioniert nicht bei subPath Mounts! Ein File, das per subPath gemountet wird, bricht die Symlink-Kette und wird nie aktualisiert (bis zum Pod-Neustart).
Generator-Patterns (Kustomize)
Das händische Erstellen von YAMLs für ConfigMaps ist lästig, besonders wegen des | (Block Scaler) für mehrzeilige Properties.
Das Kubernetes-eigene Tool Kustomize (kubectl apply -k) behebt dies mit dem configMapGenerator.
Du pflegst deine Konfiguration als stinknormale application.properties im Git. Kustomize liest beim Build diese Datei, packt sie in eine ConfigMap und – das ist der Trick – hängt einen Hash an den Namen an (z. B. my-config-v17ab12cd).
In deinem Deployment ändert Kustomize dann auch das configMapKeyRef auf diesen gehashten Namen.
Ändert sich die Property-Datei, entsteht beim nächsten Apply eine völlig neue ConfigMap und das Deployment ändert sein Template. Dies zwingt Kubernetes zu einem sauberen Rolling Restart der Pods mit der neuen Config, wodurch das "Reloader"-Problem elegant ohne Zusatzsoftware gelöst wird.
ConfigMap als Leader-Election Lock (Veraltet)
Früher (vor K8s 1.20) wurden ConfigMaps aus Mangel an Alternativen "missbraucht", um "Leases" (Verteilte Sperren) umzusetzen.
Wenn 3 Pods eines Controllers versuchen, die Arbeit zu machen, dürfen sie sich nicht überschneiden. Der Controller erzeugte eine ConfigMap und nutzte die Etcd-Metadaten (resourceVersion) als atomares Lock. Wer zuerst schreibt, ist der "Leader", die anderen warten.
Dies verursachte massiven Overhead im API Server. Heute nutzt man dafür eine spezialisierte Resource: das Lease Objekt (coordination.k8s.io).
5. Prüfen
Unterschied zu Secret?
ConfigMaps sind Klartext. Secrets sind (base64) kodiert und (hoffentlich) verschlüsselt (Encryption at Rest). Passwörter gehören nie in eine ConfigMap!Was passiert, wenn die ConfigMap fehlt?
Der Pod startet nicht ("CreateContainerConfigError"), weil er die Env Vars nicht auflösen kann. Er bleibt im Status "Pending" oder "Error", bis du die ConfigMap erstellst.Binary Data?
Möglich (binaryDataFeld), aber selten genutzt. ConfigMaps sind für Text gedacht.
Zusammenfassung
- Früher hat man Konfigurationen fest in den Code geschrieben (dbhost = "192.168.0.1"). Das ist böse. Dann hat man sie in Dateien (config.ini) neben die .exe gelegt. In Containern ist das schwierig, weil das Dateisystem flüchtig ist. ConfigMap ist die...
- Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
Optionale Praxisaufgabe
- Erkläre ConfigMap in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem ConfigMap relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Schritt 33 / 35
Secret (K8s)
Zugangsdaten sicherer verwalten.
S1
Schritt 33 / 35
Secret (K8s)
Zugangsdaten sicherer verwalten.
1. Verstehen
Ein Passwort gehört nicht in den Code.
Und auch nicht in eine ConfigMap (die ist offen lesbar).
Kubernetes hat dafür Secrets.
Es ist ein spezielles Objekt für sensible Daten (DB-Passwort, API-Token, SSL-Key).
Du kannst es als Datei in den Pod mounten (/etc/secrets/db-pass) oder als Variable (DB_PASS) nutzen.
Der Clou: Kubernetes stellt sicher, dass Secrets nicht versehentlich in Logs oder kubectl describe auftauchen (eingeschränkt).
Merksatz: Ein Kubernetes-Objekt zur Speicherung und Verwaltung sensibler Informationen wie Passwörter, OAuth-Token und SSH-Schlüssel, getrennt vom Pod-Code.
2. Anwenden
Erstellen:
kubectl create secret generic my-pass --from-literal=password=Geheim123
In YAML sieht es verschlüsselt aus?
data:
password: R2uheimMTIz
Nein! Das ist nur Base64.
Jeder kann echo R2uheimMTIz | base64 -d machen und "Geheim123" lesen.
Secrets sind standardmäßig nicht verschlüsselt, nur obfuskiert ("versteckt").
Wer Zugriff auf den Namespace hat, kann Secrets lesen.
Praxisroutine
In der Praxis lernst du Secret (K8s), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Encryption at Rest (Etcd)
Secrets liegen in der etcd Datenbank des Clusters.
Standardmäßig liegen sie dort im Klartext!
Wenn ein Hacker die Festplatte vom Master-Node klaut, hat er alle Passwörter.
Profis aktivieren Encryption at Rest.
Der API-Server verschlüsselt das Secret (AES-CBC), bevor er es in etcd schreibt.
Key-Management (KMS) ist hier wichtig (z. B. AWS KMS Plugin).
2. External Secrets Operator (ESO)
In GitOps darfst du keine Secrets (auch kein Base64!) ins Git committen. Lösung: External Secrets. Du legst das echte Passwort in AWS Secrets Manager, Azure KeyVault oder HashiCorp Vault. Im Cluster läuft der ESO. Er holt das Passwort aus dem Vault und erstellt ein lokales K8s Secret (temporär). Vorteil: Single Source of Truth, Audit Logs im Vault, und kein Secret im Git.
3. Immutable Secrets
Wenn eine App startet, liest sie das Secret.
Wenn du das Secret änderst ("Rotate Password")... merkt die App das?
Meistens Nein (Env Vars werden nur beim Start gesetzt).
Gemountete Files (volumeMount) werden eventuell aktualisiert (nach Minuten).
Sicherer Weg: Immutable Secrets.
Setze immutable: true. K8s verbietet Updates.
Wenn du rotieren willst, erstelle secret-v2 und deploye die App neu. Das verhindert Inkonsistenzen.
4. Vertiefen
1. Service Account Token Volume Projection
Früher (vor K8s 1.21) war das Standard-Token für Kubernetes Prozesse ein einfaches Secret, das ewig gültig war. Das war ein Sicherheitsrisiko.
Heute wird das Service Account Token nicht mehr als statisches Secret, sondern via Bound Service Account Token Volumes injiziert.
Kubernetes nutzt intern den kube-apiserver, um zeitlich begrenzte JWTs zu generieren, die direkt in den RAM des Pods gemountet werden. Diese Token laufen nach 1 Stunde ab und werden automatisch "rotiert". Stirbt der Pod, ist das Token sofort ungültig. Das verhindert, dass ein gestohlenes Token Tage später noch Zugriff auf die API erlaubt.
2. RBAC & Secret-Leaking Gefahren
Ein häufiger Fehler im Least Privilege Design: Ein Service (z.B. ein Backup-Skript) bekommt die Berechtigung get secrets.
Das Problem: In K8s ist get secret ein binäres Alles-oder-Nichts. Du kannst (ohne Zusatztools) kaum sagen: "Darf nur Secret A lesen, aber nicht Secret B".
Wer get secrets darf, kann auch das Secret des Cluster-Admins oder die Cloud-Zugangsdaten anderer Apps dumpen.
Lösung: Resource Names in RBAC-Rollen nutzen, um den Zugriff explizit auf bestimmte IDs einzuschränken, oder Tools wie Kyverno nutzen, um den Zugriff feingranularer zu policen.
3. Sidecar-Injection für dynamische Secrets
Bei Hochsicherheits-Systemen will man gar keine K8s-Secrets mehr nutzen (wegen der etcd Problematik).
Man nutzt die Agent Sidecar Injection von HashiCorp Vault.
Dabei wird beim Start des Pods automatisch ein kleiner Container (Sidecar) hinzugefügt. Dieser authentifiziert sich beim externen Vault, holt die Secrets und schreibt sie in ein gemeinsames emptyDir Volume (RAM-Disk). Deine App liest dann einfach eine Datei /secrets/config.json. Das K8s Master-System (Etcd) sieht diese Daten niemals. Es sind flüchtige Secrets, die nur im RAM des spezifischen Pods existieren.
5. Prüfen
tmpfs?
Secrets, die als Datei gemountet werden, liegen nie auf der Node-Festplatte. Sie liegen im RAM (tmpfs). Wenn der Strom ausfällt, sind sie weg. Das schützt vor Festplatten-Forensik.Environment vs Volume?
Env Var ist unsicherer. Wenn der Prozess crasht, steht das ganze Environment (inkl. Passwort) oft im Crash Dump Log. Files sind sicherer.bitnami-sealed-secrets?
Eine Alternative zu ESO. Du verschlüsselst das Secret lokal mit dem Public Key des Clusters. Das Ergebnis ("SealedSecret") darf ins Git. Nur der Controller im Cluster (Private Key) kann es entschlüsseln. Einfacher als Vault.
Zusammenfassung
- Ein Passwort gehört nicht in den Code. Und auch nicht in eine ConfigMap (die ist offen lesbar). Kubernetes hat dafür Secrets. Es ist ein spezielles Objekt für sensible Daten (DB-Passwort, API-Token, SSL-Key). Du kannst es als Datei in den Pod mounten...
- Erstellen: kubectl create secret generic my-pass --from-literal=password=Geheim123 In YAML sieht es verschlüsselt aus? yaml data: password: R2uheimMTIz Nein! Das ist nur Base64. Jeder kann echo R2uheimMTIz | base64 -d machen und "Geheim123" lesen. Secrets...
Optionale Praxisaufgabe
- Erkläre Secret (K8s) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem Secret (K8s) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Skizziere einen Mini-Test oder Diagnoseweg, mit dem du den Begriff praktisch überprüfst.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
Secret Management S2
Überblick: Programmierer sind faul. Sie schreiben DBPASSWORD="admin" direkt in den Code. Dann laden sie den Code auf GitHub. Zack, gehackt. Secret Management ist die Disziplin, Geheimnisse (API Keys, Passwörter, Zertifikate) sicher zu speichern, zu verteilen und zu rotieren. Regel Nr. 1: Keine Secrets im Code (Hardcoding)! Regel Nr. 2: Keine Secrets unverschlüsselt im Git! Nutze Umgebungsvariablen oder spezielle Tresore (Vaults).
Warum Rotation?
Ein Passwort, das 10 Jahre alt ist, hat wahrscheinlich schon irgendein Ex-Mitarbeiter notiert. Regelmäßige Rotation (alle 90 Tage) minimiert das Risiko. Automatisierung ist hier Pflicht (da manuell nervig).Was ist "Secret Zero"?
Das Henne-Ei-Problem. Um auf den Vault zuzugreifen, brauche ich ein Token (Secret Zero). Wo speichere ich das? Lösung: IAM-Rollen (AWS Instanzprofil) oder Kubernetes ServiceAccount Tokens, die automatisch injiziert und vertraut werden.SOPS?
"Secrets OPerationS". Ein Tool von Mozilla. Es verschlüsselt YAML-Werte (für Git), lässt Keys aber lesbar. Entschlüsselung via PGP oder AWS KMS. Beliebt in GitOps/Helm.
Least Privilege S1
Überblick: Gib einem Handwerker nicht deinen ganzen Schlüsselbund, sondern nur den Schlüssel für den Keller. Gib einer App nicht Admin-Rechte ("God Mode"), wenn sie nur Logfiles schreiben muss. Das Prinzip der geringsten Rechte (Principle of Least Privilege). Jeder User und jedes Programm bekommt nur genau so viele Rechte, wie es unbedingt braucht, um die Arbeit zu tun. Nicht mehr. Warum? Wenn die App gehackt wird, kann der Hacker nur Logfiles schreiben, aber nicht die Datenbank löschen. Der Schaden ("Blast Radius") ist begrenzt.
Was ist "Privilege Escalation"?
Der Angriff, bei dem man mit wenig Rechten anfängt (User) und eine Lücke nutzt, um mehr Rechte zu bekommen (Root). Least Privilege erschwert das, verhindert es aber nicht (Kernel Bugs).Ist es unbequem?
Ja. Zu wenig Rechte -> "Permission Denied". Entwickler hassen es ("Mach mir einfach Full Access, damit es läuft!"). Sicherheit ist immer ein Trade-Off mit Bequemlichkeit ("Friction").Wie finde ich die "Least Privileges"?
Schwer. Man fängt oft restriktiv an, schaut in die Audit-Logs ("Access Denied"), und gibt dann genau dieses Recht dazu. Tools wie AWS IAM Access Analyzer helfen dabei ("Dieser User hat S3FullAccess, nutzt aber seit 90 Tagen nur Read. Ich schlage ReadOnly vor.").
Schritt 34 / 35
PersistentVolume (PV) & Claim (PVC)
Cluster-Storage für produktive Daten.
S2
Schritt 34 / 35
PersistentVolume (PV) & Claim (PVC)
Cluster-Storage für produktive Daten.
1. Verstehen
In Docker nimmst du einfach ein Volume (-v).
In Kubernetes ist das komplizierter, weil User (Entwickler) und Admins (Ops) getrennt sind.
Der Admin verwaltet die Festplatten (PersistentVolume / PV). "Hier ist eine 100GB Disk von NetApp".
Der Entwickler bestellt Speicher (PersistentVolumeClaim / PVC). "Ich brauche 10GB".
Kubernetes ist der Makler.
Es sucht ein passendes PV für den PVC und verbindet sie ("Binding").
Der Entwickler muss nicht wissen, ob die Disk von AWS, NFS oder NetApp kommt. Er will nur 10GB.
Merksatz: Ein API-Objektpaar in Kubernetes zur Abstraktion von physischem Speicher. Das PV repräsentiert den realen Speicher, der PVC die Anforderung eines Nutzers an diesen Speicher.
2. Anwenden
Als Entwickler schreibst du nur den PVC:
kind: PersistentVolumeClaim
metadata:
name: my-db-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Und nutzt ihn im Pod:
volumes:
- name: data
persistentVolumeClaim:
claimName: my-db-claim
Kubernetes erstellt dank StorageClass (Dynamic Provisioning) automatisch eine echte Cloud-Disk (EBS) im Hintergrund. Du musst das PV nicht manuell anlegen.
Praxisroutine
In der Praxis lernst du PersistentVolume (PV) & Claim (PVC), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Access Modes (RWO vs RWX)
- ReadWriteOnce (RWO): Die Disk kann nur von einem Node gleichzeitig gemountet werden (Block Storage wie AWS EBS). Klassisch für Datenbanken.
- ReadWriteMany (RWX): Viele Nodes können gleichzeitig lesen/schreiben (NFS, EFS, GlusterFS). Nötig für skalierende Webserver mit Shared Assets.
- ReadWriteOncePod (RWOP): Neu (K8s 1.22). Noch strikter: Nur ein Pod darf mounten. (RWO erlaubt technisch, dass 2 Pods auf dem gleichen Node mounten, was Race Conditions erzeugt).
2. Reclaim Policy (Retain vs Delete)
Was passiert, wenn du den PVC löschst?
Delete(Standard in Cloud): Die echte Disk (EBS) wird gelöscht. Daten weg!Retain: Das PV wird "Released", aber die Daten bleiben auf der Disk. Ein Admin muss manuell aufräumen oder das PV wieder "Available" machen. Wichtig für Production DBs!
3. CSI (Container Storage Interface)
Früher war der Code für "AWS EBS Mounten" fest im Kubernetes-Code ("In-Tree"). Das war unflexibel. Jetzt gibt es CSI. Speicheranbieter schreiben eigene Treiber Plugins (als Pods!). Das erlaubt Snapshots, Volume Cloning und Resizing im laufenden Betrieb ("Expand PVC"), ohne dass K8s geupdated werden muss.
4. Vertiefen
Container Storage Interface (CSI) Architektur
Ursprünglich war die gesamte Logik, wie man eine NetApp oder AWS EBS Disk einhängt, als Go-Code fest in den Kube-Controller ("In-Tree") eingebacken. Ein Update von AWS verlangte ein Update von ganz Kubernetes.
Das CSI koppelt Storage radikal ab ("Out-of-Tree").
Ein CSI-Treiber besteht aus zwei Pod-Komponenten: Dem CSI-Controller (läuft oft im kube-system Namespace und redet per API mit dem Cloud-Provider zur Disk-Erstellung) und dem CSI-Node-DaemonSet (läuft auf jedem Worker-Node). Kubelet ruft per gRPC lokal auf dem Node den CSI-Node-Pod auf: "Hey, mountiere mir Bitte das Gerät /dev/nvmeX in das Filesystem für Pod Y". Somit können Drittanbieter beliebigen Storage abstrahieren.
VolumeBindingMode (WaitForFirstConsumer)
Der absolute Flaschenhals im Zusammenspiel zwischen Pod-Scheduler und Cloud-Storage.
Wenn eine StorageClass auf Immediate steht, triggert der PVC sofort die Cloud-Disk-Erstellung. Nehmen wir an, AWS baut eine EBS-Disk in der Region eu-central-1a.
Danach versucht K8s den Pod zu schedulen. Entdeckt K8s nun, dass in 1a kein CPU-RAM mehr frei ist, muss der Pod in eu-central-1b starten. Katastrophe: Eine EBS-Disk aus 1a kann man nicht in einen Worker in 1b mounten! Der Pod hängt auf ewig in "Pending".
Lösung: VolumeBindingMode: WaitForFirstConsumer. Der PVC erstellt die Disk nicht sofort. Er signalisiert dem Scheduler: "Schau erst, wo der Pod am sichersten landen kann (CPU, RAM, Tolerations)". Erst wenn die Node-Wahl (z. B. in 1b) absolut final feststeht, funkt K8s die Zone an den Storage-Provisioner und baut die Disk exakt im korrekten RZ in 1b.
In-Place Volume Expansion Control
Braucht deine DB plötzlich 200 GB statt 100 GB, nützt das Bearbeiten des PVC-Manifests nur dann etwas, wenn in der StorageClass allowVolumeExpansion: true steht.
Doch Vorsicht unter der Haube: Die Cloud vergrößert nur das Block-Gerät physikalisch (das ist Schritt 1).
Das Dateisystem auf dem Block (z. B. xfs oder ext4) ist noch immer 100 GB.
Kubelet spürt den Resizing-Wunsch, wartet bis der Pod gemountet ist ("Online Expansion") und schickt dem Kernel den resize2fs (oder xfs_growfs) Befehl, um den Mountpoint live auszudehnen ("FileSystemResizePending"-Phase). CNI und CSI müssen dies vollends unterstützen, fehlschlagende File-Resizes können den Pod im Reboot einfrieren.
5. Prüfen
Was ist eine StorageClass?
Das "Menü" für den Speicher. "Gold" = SSD, "Silver" = HDD. Im PVC sagst dustorageClassName: Gold. Kubernetes ruft den Provisioner, der Gold liefert.Kann ich ein PV verkleinern?
Nein. Dateisysteme (ext4, xfs) mögen das nicht. Vergrößern geht meistens (Online Expand). Wenn du zu groß bestellt hast: Pech gehabt (neues kleineres erstellen und Daten kopieren).Local Persistent Volumes?
Spezialfall. Du nutzt die lokale NVMe SSD im Node. Extrem schnell (kein Netzwerk). Aber wenn der Node stirbt, sind die Daten weg (da sie nicht im SAN liegen). K8s Scheduler muss den Pod zwingen, immer auf diesem Node zu starten (NodeAffinity).
Zusammenfassung
- In Docker nimmst du einfach ein Volume (-v). In Kubernetes ist das komplizierter, weil User (Entwickler) und Admins (Ops) getrennt sind. Der Admin verwaltet die Festplatten (PersistentVolume / PV). "Hier ist eine 100GB Disk von NetApp". Der Entwickler...
- Als Entwickler schreibst du nur den PVC: yaml kind: PersistentVolumeClaim metadata: name: my-db-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi Und nutzt ihn im Pod: yaml volumes: - name: data persistentVolumeClaim: claimName:...
Optionale Praxisaufgabe
- Erkläre PersistentVolume (PV) & Claim (PVC) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem PersistentVolume (PV) & Claim (PVC) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.
Erklärbegriffe zu diesem Schritt
StatefulSet (K8s) S2
Überblick: Deployments sind für Webserver (Rinder). Alle Pods (web-x8z, web-9a1) sind gleich. Wenn einer stirbt, startet ein neuer. Egal welcher. Datenbanken (Postgres, Mongo, Kafka) sind wie Haustiere (Pets). Sie haben Namen (mongo-0, mongo-1). Sie haben festen Wohnsitz (Disk). mongo-0 ist der Master. mongo-1 ist der Slave. Du kannst sie nicht beliebig tauschen. Wenn mongo-0 stirbt, muss er als mongo-0 wiederkommen (mit derselben Disk!). Das StatefulSet garantiert diese Ordnung. Es startet sie auch nacheinander: Erst 0, dann 1, dann 2.
Einfach erklärt: Die Pods heißen immer name-0, name-1 usw. (Ordinal Index). Sie haben auch stabile DNS-Namen: web-0.service.ns.svc.cluster.local. Wichtig: Du brauchst einen Headless Service (clusterIP: None), damit DNS funktioniert. Du nutzt volumeClaimTemplates im YAML, damit jeder Pod seinen eigenen PVC (data-web-0, data-web-1) bekommt. (Bei Deployments teilen sich alle den gleichen PVC oder crashen wegen RWO).
Warum "Pet Set"?
Der alte Name in Alpha Versionen. Anspielung auf "Cattle vs Pets". Deployments sind Cattle (austauschbar). StatefulSets sind Pets (einzigartig, müssen gepflegt werden).Update Strategie?
OnDelete: K8s macht gar nichts, wenn du das Image änderst. Du musst die Pods manuell löschen.RollingUpdate: K8s löscht erst Index N, wartet, dann Index N-1. Das ist sicherer für Leader Election.PVC Retain?
Wenn du das StatefulSet löschst, werden die PVCs nicht gelöscht. K8s sagt: "Daten sind heilig". Du musst die 50 PVCs manuell löschen, wenn du aufräumen willst.
Schritt 35 / 35
PersistentVolumeClaim (PVC)
Storage von Workloads anfordern.
S2
Schritt 35 / 35
PersistentVolumeClaim (PVC)
Storage von Workloads anfordern.
1. Verstehen
Wenn du in ein Restaurant gehst, reservierst du einen "Tisch für 2 Personen". Das ist dein Claim (Anspruch). Der Kellner (Kubernetes) sucht dann einen echten Tisch (PersistentVolume), der passt. Vielleicht einen Ecktisch (SSD) oder einen am Fenster (NFS). Du als Gast (Pod) weißt nicht, welcher Tisch es wird, bis du sitzt. Der PersistentVolumeClaim (PVC) ist genau diese Reservierung. Er sagt: "Ich brauche 10GB ReadWriteOnce". Ohne PVC kriegt dein Pod keinen Speicher.
Merksatz: Eine Anforderung eines Benutzers (oder Pods) nach Speicherressourcen, die vom Cluster durch das Binden an ein passendes PersistentVolume (PV) erfüllt wird.
2. Anwenden
Standard-YAML:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pv-claim
spec:
storageClassName: standard # "Ich will den normalen Speicher"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Der Status wechselt von Pending -> Bound (sobald K8s eine Disk gefunden oder erstellt hat).
Wenn es auf Pending bleibt: Wahrscheinlich hast du keine StorageClass oder die Cloud hat kein Quota mehr.
Praxisroutine
In der Praxis lernst du PersistentVolumeClaim (PVC), indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
3. Technisch einordnen
1. Binding Lifecycle
Ein PVC sucht ein PV.
Wenn storageClassName: "" (leer) ist, sucht er ein vorhandenes PV, das manuell angelegt wurde.
Wenn storageClassName: standard ist, ruft er den Provisioner (z. B. ebs.csi.aws.com), um ein neues PV zu erstellen.
Das Binding ist exklusiv (1:1). Ein 100GB PV bindet an einen 10GB PVC -> 90GB Verschwendung! (K8s kann PVs nicht splitten).
Deshalb immer Dynamic Provisioning nutzen (genau passend).
2. Volume Mode (Filesystem vs Block)
Normalerweise mountet K8s ein Dateisystem (ext4).
Aber Datenbanken (Postgres, Cassandra) wollen oft direkten Zugriff auf die Rohdaten (Raw Block Device) für Performance (kein Filesystem-Overhead).
spec:
volumeMode: Block
Der Pod sieht dann /dev/xvda statt /data. Er muss selbst formatieren oder direkt drauf schreiben.
3. PVC Expansion
Deine DB ist voll.
Du editierst den PVC: storage: 50Gi.
Der CSI-Treiber vergrößert das Volume in der Cloud.
Dann triggert Kubelet den resize2fs Befehl im laufenden Betrieb.
Der Pod merkt kurz "Disk friert ein", dann "Disk ist größer".
Achtung: Geht nur, wenn allowVolumeExpansion: true in der StorageClass gesetzt ist. Und verkleinern geht nie! D.h. 50Gi -> 20Gi ist unmöglich.
4. Vertiefen
Reclaim Policy & PVC Lifecycle (Retain vs Delete)
Was passiert mit dem echten Speicher (dem PV), wenn ich den "Gutschein" (den PVC) per kubectl delete pvc vernichte?
Das regelt die ReclaimPolicy im PV (geerbt von der StorageClass).
- Delete (Klassiker Clouds): Das CSI-Plugin ruft die EBS/GCE API an und löscht die Disk physikalisch mit sofortiger Wirkung. Deine DB-Daten sind für immer desintegriert.
- Retain (Production Standard für DBs): K8s belässt die Cloud-Disk am Leben ("Orphaned"). Das PV-Objekt geht in den State
Released. Du kannst nun keinen neuen PVC mehr darauf binden (!), da K8s davon ausgeht, dass die Daten sensibel sind. Ein Admin muss manuell alte PVC-Claims im YAML (claimRef) des PVs wipen, um das Bind-Lock freizugeben. Erst dann kann ein Recovery-Pod diesen Disk-Schatz wieder abgreifen.
Binding-Verhalten (Die Größen-Wüste)
Das Claim-Binding-Prinzip funktioniert wie eine knallharte Auktion.
Du forderst 15 Gi im PVC (requests.storage: 15Gi). K8s sucht in seinem Pool an ungebundenen PVs nach dem Kriterium Capacity >= 15Gi und passenden "AccessModes" (zb. ReadWriteOnce).
Gibt es kein exaktes 15 Gi PV, sondern nur eines mit 100 Gi freiem Platz, bindet K8s dein PVC mitleidlos an das 100 Gi PV. K8s unterstützt von sich aus keine "Partitions-Slices". Das Resultat: 85 Gi verschwendeter, nicht nutzbarer Speicher. Dynamic Provisioning via StorageClass verhindert dies, indem es die Disk in Echtzeit passgenau gießt.
StatefulSet VolumeClaimTemplates (Die Pod-Symbiose)
Ein PVC in einem standard Deployment ist suizidal, wenn du 3 Replicas (Pods) hast. Alle 3 Pods greifen den selben PVC und versuchen zeitgleich dasselbe Dateisystem zu crashen (was bei ReadWriteOnce meist schon am Node-Scheduler scheitert).
Verwendet man StatefulSets, gibt es keinen isolierten PVC mehr im manifest. Stattdessen schreibst du volumeClaimTemplates in die StatefulSet-Spec. K8s nutzt dieses Cookie-Cutter-Template und stanzt für jeden hochgefahrenen Pod (wie mysql-0, mysql-1) dynamisch einen brandneuen, komplett isolierten PVC aus (data-mysql-0, etc.). Stirbt Pod 0, heftet K8s genau diese ID und den dazugehörigen nummerierten PVC wieder an den neu bootenden Pod 0. Konsistenz ist garantiert.
5. Prüfen
Was ist "Lost"?
Ein PVC Status, wenn das darunterliegende PV gelöscht wurde (Unfall), aber der Claim noch da ist. Datenverlust ist wahrscheinlich passiert. Backups prüfen!StatefulSet & PVC?
Ein Deployment teilt sich einen PVC (alle Replicas schreiben auf dieselbe Disk -> Chaos bei RWO!). Ein StatefulSet nutztvolumeClaimTemplates. Es erstellt für jeden Pod einen eigenen PVC (data-db-0,data-db-1).Ephemere Volumes?
Manchmal brauche ich Scratch-Space nur für den Pod (schnell, lokal), aber größer als RAM (emptyDir). "Generic Ephemeral Volumes" erlauben PVC-Syntax direkt im Pod-Spec, die beim Pod-Ende gelöscht werden.
Zusammenfassung
- Wenn du in ein Restaurant gehst, reservierst du einen "Tisch für 2 Personen". Das ist dein Claim (Anspruch). Der Kellner (Kubernetes) sucht dann einen echten Tisch (PersistentVolume), der passt. Vielleicht einen Ecktisch (SSD) oder einen am Fenster (NFS). Du...
- Standard-YAML: yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mysql-pv-claim spec: storageClassName: standard "Ich will den normalen Speicher" accessModes: - ReadWriteOnce resources: requests: storage: 20Gi Der Status wechselt von Pending -...
Optionale Praxisaufgabe
- Erkläre PersistentVolumeClaim (PVC) in drei Sätzen so, dass ein kompletter Anfänger folgen kann.
- Notiere ein echtes Beispiel aus Alltag, Arbeit oder Projekt, in dem PersistentVolumeClaim (PVC) relevant wird.
- Schreibe eine typische Fehlerannahme auf und daneben, wie du sie prüfen würdest.
- Optional: Lege einen kleinen Nachweis an: Checkliste, Beispiel, Messwert, Screenshot oder kurze Begründung.
Lernauftrag für diesen Schritt
- Formuliere die Kerndefinition in einem eigenen Satz.
- Notiere ein praktisches Beispiel, in dem du diesen Begriff wirklich brauchen würdest.
- Beantworte den Quick-Check ohne Nachschauen und prüfe danach die Antworten.
- Gehe erst weiter, wenn du den Begriff jemandem ohne Fachsprache erklären kannst.