Migration von containerd 1.x: Was sich geändert hat und wie du es prüfst
containerd 1.x hat das Ende des Supports erreicht und Kubernetes hat es fallen gelassen – was beim Wechsel auf 2.x tatsächlich kaputtgeht und wie du es vor dem Upgrade herausfindest.
containerd 2.0 erschien Ende 2024, und damals lautete der Rat des Projekts selbst, nichts zu überstürzen: Die 1.x-Zweige blieben noch eine ganze Weile unterstützt. Dieses Zeitfenster ist inzwischen geschlossen. Der erweiterte Support für containerd 1.7 endet im September 2026, und Kubernetes 1.35 ist das letzte Kubernetes-Release, das containerd 1.x überhaupt unterstützt – alles darüber hinaus erfordert 2.x. Läuft ein Cluster noch auf containerd 1.x, ist das kein optionales Upgrade mehr. Diese Anleitung behandelt, was sich tatsächlich geändert hat und wie du deine Betroffenheit vor dem Wechsel prüfst.
containerd hat seine eigene API getrennt vom Daemon versioniert
Seit 2.0 sind die Daemon-Version und die gRPC-API-Version nicht mehr dieselbe Nummer: containerd sprang auf 2.0, aber die API selbst hatte keine Breaking Changes und blieb auf einer 1.x-Linie (verschoben auf 1.8). Auch die Go-Client-Bibliothek zog in einen eigenen Paketpfad um. Praktisch heißt das: Die meisten direkten API- oder Go-Client-Integrationen brauchen nicht mehr als aktualisierte Import-Pfade, keine Neuschreibung – die containerd-Maintainer berichteten, dass die Migration mindestens eines nachgelagerten Werkzeugs genau das war, ein Suchen-und-Ersetzen der Import-Pfade.
Was in 2.0 tatsächlich entfernt wurde
- Unterstützung für Docker-Schema-1-Images, standardmäßig deaktiviert. Schema 1 wurde 2014 von Schema 2 und 2017 vom OCI-Image-Format abgelöst. Ist ein Image mehr als ein paar Jahre alt und wurde nicht neu gebaut, ist es ein Schema-1-Kandidat. containerd konvertiert Schema-1-Images beim Pull, statt sie unverändert zu speichern. Die praktische Lösung für ein Image, das du weiter brauchst, ist daher, es einmal zu pullen und zurück in deine Registry zu pushen, was die Konvertierung für dich erledigt.
- Unterstützung der CRI-v1alpha2-API. Kubernetes selbst wechselte schon im Release 1.23 auf die stabile CRI-v1-API; jeder moderne kubelet nutzt bereits v1. Gefährdet sind eigentlich Drittanbieter-Werkzeuge, Monitoring-Agents, Security-Scanner und alles andere, was direkt mit dem CRI-Socket spricht und womöglich nicht aktualisiert wurde. Alles, was den containerd-Socket per Bind-Mount einbindet oder privilegiert läuft, solltest du zuerst prüfen.
- Die zwei ältesten Shim-Implementierungen (
io.containerd.runtime.v1.linuxundio.containerd.runc.v1), sodassio.containerd.runc.v2die einzige bleibt. Das war schon seit Jahren der Standard, die meisten Cluster sehen also keine Verhaltensänderung, nur den Wegfall von Codepfaden, die niemand nutzte. - Der
aufs-Snapshotter, der von einem nicht im Upstream-Kernel enthaltenen Dateisystem abhing.overlayfs, der langjährige Standard, ist der Ersatz und erfordert keine Aktion, wenn du nicht bewusst auf aufs konfiguriert warst. - io_uring-basierte Syscalls, nach mit ihnen verbundenen Kernel-CVEs standardmäßig verweigert. Betroffene Workloads sollten für dieselbe Funktionalität auf ältere Syscall-Pfade zurückfallen statt komplett zu scheitern, allerdings kann containerd das nicht vorab erkennen, wie es das bei den anderen Änderungen hier kann.
Separat wurden der alte Go-Plugin-Mechanismus im dlopen-Stil und die alten CRI-Registry-Mirror-/Config-Optionen in 2.0 als veraltet markiert und in späteren 2.x-Releases entfernt, mit ähnlicher Begründung: geringe reale Nutzung bei klarem Ersatz (Registry-Konfiguration im Stil von hosts.toml für Letzteres).
Herausfinden, wofür du tatsächlich anfällig bist
containerd enthält einen Deprecation-Service, der beim ersten Mal, wenn irgendetwas auf einem Knoten tatsächlich ein zur Entfernung vorgesehenes Feature nutzt, eine Warnung mit Zeitstempel loggt. Er feuert nur bei echter Nutzung, nicht spekulativ, ein sauberer Bericht bedeutet also ein sauberes Upgrade:
ctr deprecations list
ctr deprecations list --format json # zur Weitergabe an andere Werkzeuge
Das ist ein 1.x-Feature (zurückportiert in die Patch-Releases 1.6 und 1.7), kein 2.0-Feature, und genau das macht es nützlich: Prüfe es auf deinem aktuellen Cluster, auf der Runtime, die du verlassen willst, bevor du irgendetwas upgradest. containerd löscht diesen Zustand beim Neustart des Daemons. Wenn du containerd also kürzlich neu gestartet oder Knoten neu gebaut hast, lass zuerst eine Weile Workloads laufen, damit echte Nutzungsmuster wieder auftauchen.
Eine praktische Upgrade-Reihenfolge
- Gehe zuerst auf das neueste 1.7.x-Patch-Release, damit der Deprecation-Service korrekt ist und du ein Upgrade nicht mit unabhängigen Bugfixes vermischst.
- Lass Produktions-Traffic lange genug laufen, damit echte Nutzungsmuster sichtbar werden, und prüfe dann
ctr deprecations listüber deine Flotte. - Behebe alles, was auftaucht: Schema-1-Images konvertieren oder ersetzen, Werkzeuge aktualisieren, die noch CRI v1alpha2 aufrufen, die Konfiguration auf veraltete Registry-Syntax prüfen (das meiste migriert automatisch; die alte Syntax funktioniert während des Übergangs unter einem 2.x-Daemon weiter).
- Führe es erneut aus und bestätige, dass die Deprecation-Liste sauber ist.
- Upgrade zuerst einen Testcluster oder eine Teilmenge von Knoten auf 2.x und rolle erst dann breit aus.
Wenn du bei einem verwalteten Kubernetes-Anbieter läufst, prüfe, ob er diese Deprecation-Warnungen selbst sichtbar macht – manche Anbieter reichen sie in Knotenbedingungen oder die eigene Konsole durch und berücksichtigen sie bei automatisiertem Upgrade-Gating, wodurch du nicht per SSH auf jeden Knoten musst.
Wo du nachsiehst, wenn etwas hier nicht passt
Das containerd-Projekt veröffentlicht eine vollständige Tabelle jeder 2.0-Änderung und ihres Ersatzes samt detaillierten Release Notes auf containerd.io und im GitHub-Repository des Projekts. Für alles, was diese Anleitung nicht abdeckt, ist das die maßgebliche Quelle, zusammen mit dem Kanal #containerd im CNCF-Slack für direkte Hilfe.
Beliebte Anleitungen
-
Von Docker zu containerd: Eine kurze Geschichte der Kubernetes-Runtimes Warum Kubernetes aufgehört hat, direkt mit Docker zu sprechen, und was containerd im Verhältnis dazu eigentlich ist. -
Runtime-Interna: cgroups, runc und wo containerd hineinpasst Was einen Container tatsächlich isoliert und begrenzt – vom Kernel-Feature bis zum Daemon, mit dem Kubernetes spricht. -
Die CLI-Werkzeuge von containerd: ctr, nerdctl und crictl Drei Kommandozeilenwerkzeuge, drei unterschiedliche Aufgaben – welches du wann nehmen solltest.