Jahrelang war die virtuelle Maschine die Standardantwort auf "Wie isoliere ich Anwendungen?". Seit etwa 2013 hat Docker eine Revolution ausgelöst: Container bieten Isolation mit einem Bruchteil des Overheads. Aber was ist der genaue Unterschied – und wann nimmt man was?
Virtuelle Maschine:
┌─────────────────────┐ ┌─────────────────────┐
│ App A │ │ App B │
├─────────────────────┤ ├─────────────────────┤
│ Gast-OS │ │ Gast-OS │
│ (Kernel) │ │ (Kernel) │
├─────────────────────┴──┴─────────────────────┤
│ Hypervisor │
├───────────────────────────────────────────────┤
│ Host-OS (optional bei Typ 2) │
├───────────────────────────────────────────────┤
│ Physische Hardware │
└───────────────────────────────────────────────┘
Container:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ App A │ │ App B │ │ App C │
├──────────┤ ├──────────┤ ├──────────┤
│ Libs/Dep │ │ Libs/Dep │ │ Libs/Dep │
├──────────┴──┴──────────┴──┴──────────┤
│ Container Runtime (Docker) │
├───────────────────────────────────────┤
│ Host-OS + Kernel │
├───────────────────────────────────────┤
│ Physische Hardware │
└───────────────────────────────────────┘
Schlüsselpunkt: Container teilen den Host-Kernel
VMs haben jeweils einen eigenen KernelMerkmal | Virtuelle Maschine | Container |
|---|---|---|
Isolation | Vollständig (eigener Kernel) | Prozess-Isolation (shared Kernel) |
Betriebssystem | Vollständiges Gast-OS | Kein eigener Kernel |
Startzeit | Minuten | Sekunden bis Millisekunden |
Größe | GB (Disk-Image) | MB (Image) |
RAM-Overhead | 100-500 MB (Gast-OS) | Wenige MB |
Performance | Sehr gut (nahe nativ) | Nativ (kein Overhead) |
Portabilität | Eingeschränkt (GB-Dateien) | Sehr hoch (MB-Images) |
Sicherheit | Sehr hoch | Gut (aber shared Kernel) |
OS-Vielfalt | Windows, Linux, BSD etc. | Nur Linux (nativ) |
Persistenz | Persistent (Disk-Image) | Ephemer (Volumes für Daten) |
Anwendungsfall | Empfehlung | Begründung |
|---|---|---|
Windows-Workloads | VM | Container können kein Windows-Kernel teilen (Linux-Host) |
Legacy-Anwendungen | VM | Vollständige OS-Umgebung nötig |
Maximale Isolation (Sicherheit) | VM | Eigener Kernel – kein Kernel-Exploit-Risiko |
Microservices | Container | Leicht, schnell, skalierbar |
CI/CD-Pipelines | Container | Schneller Start, konsistente Umgebung |
Webserver/APIs | Container | Einfache Skalierung, viele Instanzen |
Datenbanken (Produktion) | VM oder bare metal | Persistenz, Performance, Isolation |
Entwicklungsumgebung | Container | "Works on my machine" – konsistente Umgebung |
Namespaces – Isolation verschiedener Ressourcen:
PID Namespace → Prozesse sehen nur ihre eigenen PIDs
Network Namespace → Eigene Netzwerk-Interfaces pro Container
Mount Namespace → Eigenes Dateisystem-Layout
UTS Namespace → Eigener Hostname
User Namespace → Eigene Benutzer-IDs
cgroups (Control Groups) – Ressourcenbegrenzung:
CPU-Limit: Container darf max. 50% einer CPU nutzen
RAM-Limit: Container darf max. 512 MB nutzen
I/O-Limit: Lese/Schreibrate begrenzen
Network: Bandbreite begrenzen
Capabilities – Feinkörnige Berechtigungen:
Statt "root oder nicht root" → spezifische BerechtigungenRisiko: Kernel-Exploit
Wenn ein Angreifer aus dem Container ausbrechen kann
und einen Kernel-Bug ausnutzt → Zugriff auf Host und andere Container
Schutzmaßnahmen:
✓ Rootless Container (Container läuft ohne root-Rechte)
✓ Seccomp-Profile (nur erlaubte Syscalls)
✓ AppArmor/SELinux-Profile
✓ Read-only Dateisystem im Container
✓ Regelmäßige Updates des Host-Kernels
✓ Gvisor (Google) – Kernel-Sandbox für ContainerIn der Praxis schließen sich VMs und Container nicht aus – sie ergänzen sich:
Typische Produktionsarchitektur:
Physische Hardware
└── Hypervisor (VMware/Proxmox/Hyper-V)
└── Linux VM (Ubuntu/RHEL)
└── Docker / Kubernetes
├── Container 1 (Webserver)
├── Container 2 (API)
└── Container 3 (Cache)
Vorteile dieser Kombination:
✓ VM-Isolation zwischen verschiedenen Teams/Projekten
✓ Container-Effizienz innerhalb der VM
✓ Snapshot/Backup der VM sichert alle Container
✓ Live-Migration der VM (mit allen Containern)VMs haben einen eigenen Kernel – vollständige Isolation aber mehr Overhead
Container teilen den Host-Kernel – weniger Overhead, schneller Start, aber geringere Isolation
Namespaces isolieren Prozesse, Netzwerk und Dateisystem der Container
cgroups begrenzen CPU, RAM und I/O der Container
Container können kein Windows nativ auf Linux-Host (nur Linux-Workloads)
VMs eignen sich für Windows, Legacy-Anwendungen und maximale Sicherheit
Container eignen sich für Microservices, CI/CD und skalierbare Webdienste
In der Praxis werden Container oft auf VMs betrieben – beste Kombination aus beiden Welten