VM vs. Container

Der Paradigmenwechsel

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?

Technischer Unterschied

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 Kernel

VM vs. Container – Direkter Vergleich

Merkmal

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)

Wann VM, wann Container?

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

Linux-Kernel-Features die Container ermöglichen

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 Berechtigungen

Container-Sicherheit

Risiko: 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 Container

Container auf VMs – Die Kombination

In 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)

Zusammenfassung

  • 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