Container Runtimes: OCI, runc & crun (Artikel 378)
Tiefgehende Analyse der Container-Runtimes unter Linux. Erfahren Sie den Unterschied zwischen High-Level Orchestratoren und Low-Level Runtimes wie runc und crun.
# Container Runtimes: Das Bindeglied zwischen Paket und Kernel
TL;DR / Management Summary Ein Container ist keine Magie, sondern das Ergebnis einer präzisen Kette von Werkzeugen. Während wir meist mit High-Level Tools wie Docker oder Podman arbeiten, erledigen im Hintergrund Low-Level Runtimes wie runc oder crun die harte Arbeit. Sie setzen die OCI-Spezifikation (Open Container Initiative) um, erstellen Namespaces und wenden Cgroup-Limits an. Wer diese Schichten versteht, kann Container-Hänger und Startup-Probleme auf Kernel-Ebene diagnostizieren.
# 1. Einführung & Architektur
Die Schichten der Abstraktion.
Der Container-Stack ist modular. Wir unterscheiden zwischen dem Verwalter (Manager) und dem Ausführer (Runtime).
# Der Runtime-Stack (Mermaid)
graph TD
A[Orchestrator: Kubernetes / Swarm] --> B[High-Level: Containerd / CRI-O]
B --> C[The Shim: containerd-shim]
C --> D[Low-Level Runtime: runc / crun]
D --> E[Kernel: Namespaces, Cgroups, LSM]
subgraph "OCI Standard"
D
end
- runc: Der Standard-Referenz-Implementierung (in Go geschrieben).
- crun: Eine moderne Alternative von Red Hat (in C geschrieben). Schneller, braucht weniger RAM, unterstützt Cgroups v2 nativ.
# 2. Die OCI Spezifikation
Ein Standard für alle.
Die OCI (Open Container Initiative) definiert zwei wichtige Dinge:
- Image Spec: Wie muss ein Image-Archiv aufgebaut sein? (Layers, Config).
- Runtime Spec: Wie muss ein Verzeichnis aussehen (
bundle), damit eine Runtime daraus einen Container starten kann?
# Ein Bundle ansehen
Wenn Sie einen Container starten, erstellt Docker/Podman temporär ein Verzeichnis mit einer config.json.
# Export einer OCI Config
podman spec --name myweb > config.json
# 3. Die Rolle des Shims
Prozess-Wächter.
Warum beendet sich ein Container nicht, wenn wir den Docker-Dämon neustarten? Dank des Shims.
- Der Shim bleibt als kleiner Prozess offen, während die Low-Level Runtime (runc) den Container startet und sich dann beendet.
- Er hält die Dateideskriptoren (stdout/stderr) offen und meldet den Exit-Code zurück.
# 4. Day-2 Operations: Runtime wechseln
Performance-Tuning.
In RHEL/SLES können Sie oft zwischen runc und crun wählen.
# crun aktivieren (Podman)
# In /etc/containers/containers.conf
[engine]
runtime = "crun"
Vorteil: crun ist bis zu 2x schneller beim Starten von Containern und ideal für Serverless-Workloads (Knative), wo Millisekunden zählen.
# 5. Troubleshooting & “War Stories”
Wenn die Kette bricht.
# Story 1: “Der hängende Shim”
Symptom: Ein Container lässt sich nicht löschen (docker rm -f hängt). In der Prozessliste (ps) ist der Container-Prozess weg, aber ein containerd-shim Prozess mit der ID hakt.
Ursache: Der Shim kann den I/O-Stream nicht schließen, weil ein Mount-Point auf dem Host blockiert oder ein NFS-Volume nicht antwortet.
Lösung: Finden Sie die hängende Pipe oder den Mount. Killen Sie den Shim-Prozess erst als letzten Ausweg mit -9.
# Story 2: “OCI Runtime Create Failed”
Symptom: podman run bricht sofort ab mit OCI runtime create failed: container_linux.go:380: starting container process caused "process_linux.go:545: ... permission denied".
Ursache: Die Low-Level Runtime konnte einen Kernel-Namespace nicht erstellen oder das SELinux-Label (Artikel 108) verbot den Zugriff auf das Binary im Container.
Lösung: Prüfen Sie das Audit-Log (ausearch -m AVC). Oft ist ein inkompatibler Mount-Typ oder ein fehlendes Kernel-Feature (z.B. User-Namespaces in alten Kernels) die Ursache.
# 6. Fazit & Empfehlung
- Wahl: Nutzen Sie crun, wenn Sie viele kurzlebige Container haben oder Speicher sparen müssen.
- Debugging: Nutzen Sie
strace -f -p <shim_pid>, um zu sehen, warum ein Container beim Starten hängt. - Wissen: Denken Sie daran: Docker/Podman sind nur die “Benutzeroberflächen”. Die echte Arbeit passiert im OCI-Layer.
# Anhang: Cheatsheet
| Aufgabe | Tool / Pfad |
|---|---|
| Low-Level Runtime (Go) | /usr/bin/runc |
| Low-Level Runtime © | /usr/bin/crun |
| Runtime Config (JSON) | config.json (im bundle) |
| Container Manager | containerd / cri-o |
| Shim Prozess | containerd-shim |
| Runtime via CLI testen | runc list |
| OCI Spec Info | opencontainers.org |
| Paket suchen (Arch) | sudo pacman -S runc crun |
| Paket suchen (Alpine) | apk add runc crun |
| Plugin-Schnittstelle | CRI (Container Runtime Interface) |