linux-kernel-advanced container runtime oci runc crun shim advanced

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:

  1. Image Spec: Wie muss ein Image-Archiv aufgebaut sein? (Layers, Config).
  2. 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)