Docker Architektur: ein Container ist nur ein Prozess

27.07.2026

Ein Docker Container ist keine kleine VM, sondern ein Linux-Prozess mit Namespaces und cgroups: die Kette hinter docker run, der Beweis in drei Kommandos und der containerd image store.

Inhaltsverzeichnis

„Container sind doch nur schlanke VMs.” Diesen Satz höre ich in fast jeder Schulung, und er ist das hartnäckigste Missverständnis rund um Docker. Er klingt harmlos, führt aber in die Irre: Wer Container für kleine virtuelle Maschinen hält, wundert sich später über geteilte Kernel, über Millisekunden-Starts, über Prozesse, die plötzlich in der Prozessliste des Hosts auftauchen.

Die Wahrheit ist einfacher und schöner: Ein Container ist ein ganz normaler Linux-Prozess. Mit Sichtschutz und Ressourcen-Deckel, aber ein Prozess. Wer das einmal verstanden hat, kann sich fast alles Weitere selbst herleiten, vom Debugging bis zu der Frage, warum Kubernetes gar kein Docker braucht. Genau darum geht es in diesem Beitrag, inklusive Beweis in drei Kommandos.

Container sind Prozesse

Drei Bausteine des Linux-Kernels machen aus einem gewöhnlichen Prozess das, was wir Container nennen.

Namespaces bestimmen, was der Prozess sieht

Linux Namespaces geben dem Prozess eine eigene Sicht auf das System: eine eigene Prozessliste mit eigenen PIDs, ein eigenes Netzwerk-Interface, eigene Mounts, einen eigenen Hostnamen. Der Prozess im Container glaubt, allein auf einer Maschine zu sein. Er ist es nicht, er sieht nur nichts anderes.

cgroups bestimmen, was der Prozess verbrauchen darf

Control Groups deckeln den Verbrauch: CPU, RAM, IO. Ohne cgroups könnte ein einzelner Container den ganzen Host leerfressen. Mit ihnen ist er ein Prozess mit Budget.

Das Wurzeldateisystem liefert die Dateien

Der dritte Baustein ist ein eigenes Wurzeldateisystem, der Nachfolger der alten chroot-Idee: Der Prozess bekommt einen eigenen Dateibaum, und dieser Dateibaum ist der Inhalt des Docker Images. Ein Image ist am Ende nichts anderes als ein gepacktes Dateisystem plus Metadaten.

Sichtschutz, Budget, eigene Dateien: mehr ist ein Container nicht. Es gibt keinen Hypervisor und keinen Gast-Kernel.

Der Unterschied zur virtuellen Maschine

Eine VM emuliert einen kompletten Rechner. Auf einem Hypervisor bootet ein vollständiges Gastsystem mit eigenem Kernel, das dauert Sekunden bis Minuten und kostet dauerhaft Speicher. Ein Container dagegen startet in Millisekunden, denn es bootet nichts: Der Kernel läuft ja schon, es wird nur ein weiterer Prozess gestartet.

Dieselbe Eigenschaft ist auch die Kehrseite: Alle Container teilen sich den Kernel des Hosts. Ein Container isoliert deshalb schwächer als eine VM, und Linux-Container brauchen zwingend einen Linux-Kernel. Docker Desktop auf Windows und macOS löst das, indem es im Hintergrund eine kleine Linux-VM startet, in der die Container dann laufen. Auch das versteht man sofort, wenn man den Merksatz kennt: Container sind Linux-Prozesse, also braucht es irgendwo ein Linux.

Der Beweis in drei Kommandos

Das alles lässt sich auf jedem Rechner mit Docker nachprüfen.

docker container run -d --name beweis nginx:latest

Der nginx-Webserver läuft jetzt „im Container”. Erste Frage an Docker: Wie sieht der Container von außen aus?

docker container top beweis

Die Ausgabe zeigt die nginx-Prozesse aus Sicht des Hosts, mit ganz normalen Host-PIDs. Zweite Frage, diesmal von innen:

docker container exec beweis cat /proc/1/comm

Die Antwort lautet nginx. Im Container hat der Webserver die PID 1, als wäre er der erste und einzige Prozess einer eigenen Maschine. Außen eine beliebige PID, innen die 1: Das ist der PID-Namespace in Aktion, live und ohne Theorie.

Auf einem Linux-Host geht sogar noch mehr: ps aux | grep nginx zeigt dieselben Prozesse direkt in der Prozessliste des Hosts, zwischen all deinen anderen Programmen. Kein Hypervisor, keine Blackbox, ein Prozess. Aufräumen nicht vergessen: docker container rm -f beweis.

Was beim docker run wirklich passiert

Hinter dem einen Befehl steckt eine Kette von Komponenten, und die Rollenverteilung zu kennen lohnt sich spätestens beim ersten Debugging:

  1. Die docker-CLI ist nur ein Client. Jedes Kommando geht als REST-Aufruf an den Docker Daemon dockerd. Die CLI selbst startet keinen einzigen Container.
  2. dockerd ist der Koordinator: Er stellt die Docker API bereit und verwaltet Netzwerke und Volumes.
  3. containerd verwaltet in aktuellen Docker-Versionen die Images und lädt fehlende Images aus einer Registry wie Docker Hub herunter.
  4. Das eigentliche Starten übernimmt runc: Es erzeugt den isolierten Prozess mit Namespaces, cgroups und dem Dateisystem aus dem Image.

Am Ende der Kette steht also genau das, was der Merksatz verspricht: kein Hypervisor, sondern ein Prozess. Interessant ist die Kette auch aus einem zweiten Grund: containerd und runc sind eigenständige Open-Source-Projekte, und Kubernetes spricht mit containerd direkt, ganz ohne dockerd. Wer die Kette kennt, versteht ohne weitere Erklärung, warum „Kubernetes hat Docker entfernt” nie bedeutete, dass deine Docker Images nicht mehr funktionieren.

Wer verwaltet die Images

An dieser Kette hat sich zuletzt etwas Grundsätzliches verschoben, das viele Teams noch nicht auf dem Schirm haben.

Historisch hat dockerd die Images selbst gespeichert, mit einem eigenen Storage-Backend, sichtbar als Storage Driver overlay2. containerd war nur fürs Ausführen zuständig. Der modernere Weg ist der containerd image store: containerd übernimmt auch Pull und Speicherung der Images. Das vereinheitlicht Docker mit dem Rest des Container-Ökosystems und kann mehr als das alte Backend, zum Beispiel Multi-Platform-Images.

Die Zeitleiste:

  1. Docker Engine unter Linux: zuschaltbar seit Version 24, Standard bei Neuinstallationen seit Version 29. Wer von früher upgradet, bleibt auf overlay2, bis er aktiv umschaltet.
  2. Docker Desktop: Standard seit Version 4.34.

In Docker Desktop schaltet man unter Settings → General die Option „Use containerd for pulling and storing images” um. Bei der Docker Engine aktiviert man das Feature in der /etc/docker/daemon.json und startet den Daemon neu:

{
  "features": {
    "containerd-snapshotter": true
  }
}

Eine Warnung gehört dazu: Die beiden Backends haben getrennte Image-Stores. Beim Umschalten bleiben bestehende Images auf der Platte, sind im jeweils anderen Backend aber unsichtbar, bis man zurückschaltet. Wer nach dem Umschalten eine leere Image-Liste sieht, hat nichts verloren, er schaut nur in den anderen Store.

Welcher Store bei dir aktiv ist, verrät docker info im Abschnitt Storage Driver: overlay2 heißt klassisch, driver-type: io.containerd.snapshotter.v1 heißt containerd image store.

Fazit

  1. Ein Container ist ein normaler Linux-Prozess: Namespaces bestimmen, was er sieht, cgroups, was er verbrauchen darf, das Wurzeldateisystem aus dem Image liefert seine Dateien.
  2. Es gibt keinen Hypervisor und keinen Gast-Kernel. Deshalb starten Container in Millisekunden, isolieren aber schwächer als VMs, und alle teilen sich den Kernel des Hosts.
  3. Der Beweis passt in drei Kommandos: docker container top außen, cat /proc/1/comm innen, ps aux auf dem Host.
  4. Beim docker run arbeitet eine Kette: CLI → dockerd → containerd → runc. Kubernetes steigt bei containerd ein, deshalb braucht es kein Docker.
  5. Die Image-Verwaltung wandert zu containerd: Standard bei Docker Desktop seit 4.34, bei neuen Docker Engines seit Version 29. Beim Umschalten gilt: getrennte Stores, nichts ist weg.

Dieses Fundament trägt weiter als jede Kommando-Liste: Verstehen, was da läuft, ist der erste Schritt zu einer Plattform, die dir gehört. In der Schulung ist dieses Kapitel bewusst das allererste, noch bevor Docker überhaupt installiert wird.

Newsletter

Erhalte praxisnahe Tutorials, Best Practices und echte Lösungen für die häufigsten DevOps-Probleme direkt in Dein Postfach.

Datenschutz: Deine E-Mail-Adresse wird DSGVO-konform in Deutschland gespeichert. Keine Spam, nur relevante Inhalte. Eine E-Mail alle 1 bis 2 Wochen.