Docker: Unterschied zwischen den Versionen
| Zeile 211: | Zeile 211: | ||
Bei richtiger Konfiguration sind selbst ''root''-Rechte innerhalb eines Docker-Containers nicht dazu geeignet, um den Host anzugreifen | Bei richtiger Konfiguration sind selbst ''root''-Rechte innerhalb eines Docker-Containers nicht dazu geeignet, um den Host anzugreifen | ||
* Insbesondere sollte dazu ein neuer ''User Namespace'' erzeugt und der ''root''-Benutzer des Containers auf einen unprivilegierten Benutzer des Hosts abgebildet werden | * Insbesondere sollte dazu ein neuer ''User Namespace'' erzeugt und der ''root''-Benutzer des Containers auf einen unprivilegierten Benutzer des Hosts abgebildet werden | ||
Version vom 31. Juli 2025, 09:50 Uhr
Docker - Beschreibung
Beschreibung
Docker ist freie Software
- Container sind eine schlanke Virtualisierungslösung
Prozesse laufen direkt im Kernel des Host-Betriebssystems
- abgeschottet von den anderen Prozessen durch Linux-Techniken wie
- cgroups
- namespaces
- unter Windows kommt dafür der WSL2 zum Einsatz
- unter macOS wird eine kleine Virtualisierung genutzt
- Vorteile
Container sind nützlich, wenn an mehreren Stellen eine identische Arbeitsumgebung benötigt wird
- Man kann dabei entweder die Images (fertige Dateien) oder die Dockerfiles (Anweisungen zum Erzeugen eines Images) im Projekt verteilen
- Tatsächlich ist es nicht unüblich, ein Dockerfile in das Projekt-Repo mit einzuchecken
- Kein Sicherheitsgewinn
Durch Container hat man allerdings im Gegensatz zu herkömmlichen VMs keinen Sicherheitsgewinn, da die im Container laufende Software ja direkt auf dem Host-Betriebssystem ausgeführt wird
- Fertige Images
Es gibt auf DockerHub fertige Images, die man sich ziehen und starten kann
- Ein solches gestartetes Image nennt sich dann Container und enthält beispielsweise Dateien, die in den Container gemountet oder kopiert werden
- Man kann auch eigene Images bauen, indem man eine entsprechende Konfiguration (Dockerfile) schreibt
- Jeder Befehl bei der Erstellung eines Images erzeugt einen neuen Layer, die sich dadurch mehrere Images teilen können
In der Konfiguration einer Gitlab-CI-Pipeline kann man mit image ein Docker-Image angeben, welches dann in der Pipeline genutzt wird
- VSCode
VSCode kann über das Remote-Plugin sich (u.a.) mit Containern verbinden und dann im Container arbeiten (editieren, compilieren, debuggen, testen, ...)
In dieser kurzen Einheit kann ich Ihnen nur einen ersten Einstieg in das Thema geben
- Wir haben uns beispielsweise nicht Docker Compose oder Kubernetes angeschaut, und auch die Themen Netzwerk (zwischen Containern oder zwischen Containern und anderen Rechnern) und Volumnes habe ich außen vor gelassen
- Dennoch kommt man in der Praxis bereits mit den hier vermittelten Basiskenntnissen erstaunlich weit
- Videos (YouTube)
- VL Einführung in Docker
- Demo Container in der Konsole
- Demo GitLab CI/CD und Docker
- Demo GitHub Actions und Docker
- Demo VSCode und Docker
- Videos (HSBI-Medienportal)
- VL Einführung in Docker
- Lernziele
- (K2) Unterschied zwischen Containern und VMs
- (K2) Einsatzgebiete für Container
- (K2) Container laufen als abgeschottete Prozesse auf dem Host - kein Sandbox-Effekt
- (K3) Container von DockerHub ziehen
- (K3) Container starten
- (K3) Eigene Container definieren und bauen
- (K3) Einsatz von Containern in GitLab CI/CD und GitHub Actions
- (K3) Einsatz von VSCode und Containern
Motivation
- Motivation CI/CD: WFM (''Works For Me'')
Auf dem CI-Server muss man eine Arbeitsumgebung konfigurieren und bereitstellen, für Java-basierte Projekte muss beispielsweise ein JDK existieren und man benötigt Tools wie Maven oder Gradle, um die Buildskripte auszuführen
- Je nach Projekt braucht man dann noch weitere Tools und Bibliotheken
- Diese Konfigurationen sind unabhängig vom CI-Server und werden üblicherweise nicht direkt installiert, sondern über eine Virtualisierung bereitgestellt
Selbst wenn man keine CI-Pipelines einsetzt, hat man in Projekten mit mehreren beteiligten Personen häufig das Problem "WFM" ("works for me")
- Jeder Entwickler hat sich auf ihrem Rechner eine Entwicklungsumgebung aufgesetzt und nutzt in der Regel seine bevorzugte IDE oder sogar unterschiedliche JDK-Versionen
- Dadurch kann es schnell passieren, dass Probleme oder Fehler auftreten, die sich nicht von allen Beteiligten immer nachvollziehen lassen
- Hier wäre eine einheitliche Entwicklungsumgebung sinnvoll, die in einer "schlanken" Virtualisierung bereitgestellt wird
Als Entwickler kann man zeitgleich in verschiedenen Projekten beteiligt sein, die unterschiedliche Anforderungen an die Entwicklungstools mit sich bringen
- Es könnte beispielsweise passieren, dass man zeitgleich drei bestimmte Python-Versionen benötigt
- In den meisten Fällen schafft man es (mit ein wenig Aufwand), diese Tools nebeneinander zu installieren
- Oft ist das in der Praxis aber schwierig und fehleranfällig
In diesen Fällen kann eine Virtualisierung helfen
Container vs. VM
Wenn man über Virtualisierung auf dem Desktop spricht, kann man grob zwei Varianten unterscheiden
- In beiden Fällen ist die Basis die Hardware (Laptop, Desktop-Rechner) und das darauf laufende (Host-) Betriebssystem (Linux, FreeBSD, macOS, Windows, ...)
- Darauf läuft dann wiederum die Virtualisierung
Im rechten Bild wird eine herkömmliche Virtualisierung mit virtuellen Maschinen (VM) dargestellt
- Dabei wird in der VM ein komplettes Betriebssystem (das "Gast-Betriebssystem") installiert und darin läuft dann die gewünschte Anwendung
- Die Virtualisierung (VirtualBox, VMware, ...) läuft dabei als Anwendung auf dem Host-Betriebssystem und stellt dem Gast-Betriebssystem in der VM einen Rechner mit CPU, RAM,
- zur Verfügung und übersetzt die Systemaufrufe in der VM in die entsprechenden Aufrufe im Host-Betriebssystem
- Dies benötigt in der Regel entsprechende Ressourcen: Durch das komplette Betriebssystem in der VM ist eine VM (die als Datei im Filesystem des Host-Betriebssystems liegt) oft mehrere 10GB groß
- Für die Übersetzung werden zusätzlich Hardwareressourcen benötigt, d.h
- hier gehen CPU-Zyklen und RAM "verloren"
- Das Starten einer VM dauert entsprechend lange, da hier ein komplettes Betriebssystem hochgefahren werden muss
- Dafür sind die Prozesse in einer VM relativ stark vom Host-Betriebssystem abgekapselt, so dass man hier von einer "Sandbox" sprechen kann: Viren o.ä
- können nicht so leicht aus einer VM "ausbrechen" und auf das Host-Betriebssystem zugreifen (quasi nur über Lücken im Gast-Betriebssystem kombiniert mit Lücken in der Virtualisierungssoftware)
Im linken Bild ist eine schlanke Virtualisierung auf Containerbasis dargestellt
- Die Anwendungen laufen direkt als Prozesse im Host-Betriebssystem, ein Gast-Betriebssystem ist nicht notwendig
- Durch den geschickten Einsatz von
namespacesundcgroupsund anderen in Linux und FreeBSD verfügbaren Techniken werden die Prozesse abgeschottet, d.h - der im Container laufende Prozess "sieht" die anderen Prozesse des Hosts nicht
- Die Erstellung und Steuerung der Container übernimmt hier beispielsweise Docker
- Die Container sind dabei auch wieder Dateien im Host-Filesystem
- Dadurch benötigen Container wesentlich weniger Platz als herkömmliche VMs, der Start einer Anwendung geht deutlich schneller und die Hardwareressourcen (CPU, RAM, ...) werden effizient genutzt
- Nachteilig ist, dass hier in der Regel ein Linux-Host benötigt wird (für Windows wird mittlerweile der Linux-Layer (WSL) genutzt; für macOS wurde bisher eine Linux-VM im Hintergrund hochgefahren, mittlerweile wird aber eine eigene schlanke Virtualisierung eingesetzt)
- Außerdem steht im Container üblicherweise kein graphisches Benutzerinterface zur Verfügung
- Da die Prozesse direkt im Host-Betriebssystem laufen, stellen Container keine Sicherheitsschicht ("Sandboxen") dar!
In allen Fällen muss die Hardwarearchitektur beachtet werden: Auf einer Intel-Maschine können normalerweise keine VMs/Container basierend auf ARM-Architektur ausgeführt werden und umgekehrt
Anhang
Siehe auch
- Docker/Ausblick
- Docker/Befehl
- Docker/Befehle
- Docker/Compose
- Docker/Container
- Docker/Container und Virtuelle Maschinen
- Docker/Containerisieren
- Docker/Datenbank
- Docker/Dockerfile
- Docker/Engine
- Docker/Freigeben
- Docker/Funktionen
- Docker/Getting started
- Docker/Hosting
- Docker/Hub
- Docker/Image
- Docker/Image/Aktualisieren
- Docker/Installation
- Docker/Installation/Manuell
- Docker/Mounts
- Docker/Multi-Container
- Docker/Namespaces
- Docker/Sicherheit
- Docker/Userns-remap
- Docker/Vorteile
- Docker/Workshop
- Docker/pull
- Docker/tmp
Links
Weblinks
TMP
Docker - Isolierung von Anwendungen durch Containervirtualisierung
Bereitstellung von Anwendungen
- Vereinfachung weil sich
- Container, die alle nötigen Pakete enthalten
- leicht als Dateien transportieren und installieren lassen
Container gewährleisten die Trennung und Verwaltung der auf einem Rechner genutzten Ressourcen
- Code
- Laufzeitmodul
- Systemwerkzeuge
- Systembibliotheken
- alles was auf einem Rechner installiert werden kann
Virtualisierung mit Linux
Prinzipiell ist Docker auf die Virtualisierung mit Linux ausgerichtet
- Da die Docker-Technologie einen Linux-Kernel benötigt, muss für die Nutzung unter Microsoft Windows die Virtualisierung genutzt werden
- Docker kann dort mittels WSL 2 (Standard) oder VirtualBox verwendet werden
- Auf macOS lässt sich HyperKit oder VirtualBox nutzen
Ressourcentrennung
Da die Ressourcentrennung alleine mit den Docker zugrunde liegenden Techniken wie Namespaces und Cgroups nicht völlig sicher ist
- hat das Unternehmen Red Hat Unterstützung für die sicherheitsrelevante Kernel-Erweiterung SELinux implementiert
- welche die Container auf der Ebene des Host-Systems zusätzlich absichert
Realisierung von Containern

Linux-Techniken
- Cgroups
- Namespaces
- Anfänglich LXC-Schnittstelle des Linux-Kernels
- Mittlerweile eine eigene Programmierschnittstelle namens libcontainer
- Als Speicher-Backend verwendet Docker das Overlay-Dateisystem aufs
- seit Version 0.8 wird auch btrfs unterstützt
Begriffe
| Begriff | Beschreibung |
|---|---|
| Image | Speicherabbild eines Containers
|
| Container | Aktive Instanz eines Images
|
| Layer | Teil eines Images und enthält einen Befehl oder eine Datei, die dem Image hinzugefügt wurde
|
| Dockerfile | Textdatei, die mit verschiedenen Befehlen ein Image beschreibt
|
| Repository | Satz gleichnamiger Images mit verschiedenen Tags, zumeist Versionen |
| Registry | Verwaltung von Repositories (Docker Hub, Artifactory, ...) |
| libcontainer | eine Schnittstelle zu den Grundfunktionen von Docker |
| libswarm | eine Schnittstelle, um Docker-Container zu steuern |
| libchan | ermöglicht eine einfache („light weighted“) Kommunikation zwischen Prozessteilen und Prozessen |
Sicherheitsaspekte
- Root-Rechte
Docker-Container werden durch einen Daemon erzeugt, der in der Vergangenheit zwingend root-Rechte haben musste, ab Version 19.03 unter bestimmten Umständen aber auch unprivilegiert sein kann
- Läuft der Daemon mit root-Rechten, bedient man sich oft einer eigenen Nutzergruppe, um auch unprivilegierten Nutzern die Erzeugung neuer Docker-Container zu erlauben
- Unprivilegierten Nutzer
Ein möglicher Fallstrick besteht darin, dass alle unprivilegierten Nutzer, die Mitglied einer solchen Nutzergruppe sind, indirekt über volle root-Rechte auf dem Host-System verfügen
- Die alternative Software für Containervirtualisierung Podman verzichtet auf dieses Sicherheitsrisiko, ist zu Docker kompatibel und angepasst auf Kubernetes
- Format
Die Open Container Initiative spezifiziert ein Format zur Containervirtualisierung
- Da es sich um eine internationale und offene Spezifikation handelt, kann prinzipiell jeder diese implementieren
- So sind sicherere Alternativen zu Docker entstanden, zu denen man vorhandene Images oder Container migrieren kann – etwa containerd oder Podman
- Trotz Standardisierung gibt es kleinere Unterschiede, etwa im Speicherort von Container und Images
- Unterschiede zu Virtuellen Maschinen
Im Unterschied zu einer Virtuellen Maschine teilen sich Container und Host einen gemeinsamen Betriebssystem-Kernel
- Dies verbessert einerseits die Leistung erheblich, vergrößert andererseits aber auch das Risiko, dass erfolgreiche Angriffe gegen den Kernel auch den Host kompromittieren
Bei richtiger Konfiguration sind selbst root-Rechte innerhalb eines Docker-Containers nicht dazu geeignet, um den Host anzugreifen
- Insbesondere sollte dazu ein neuer User Namespace erzeugt und der root-Benutzer des Containers auf einen unprivilegierten Benutzer des Hosts abgebildet werden