Was vor dem Upgrade geprüft werden muss#
Kubernetes 1.37 (Codename „Garhwal") ist seit dem 26. August 2026 released. Der Sneak Peek aus dem Juli listet die Punkte, die aus einem Routine-Upgrade einen Incident machen können — am häufigsten sind das genau vier:
- cgroup-Version auf jedem Node — der Kubelet startet sonst nicht mehr.
- containerd-Version — 1.37 ist die letzte Version, die containerd 1.x unterstützt.
- kube-proxy-Modus — ipvs ist deprecated, die Warning kommt ab 1.37.
- Static-Pod-Manifeste — Secrets/ConfigMap-Referenzen sind ab sofort verboten.
Dazu kommt eine Breaking Change, die man schnell übersieht: SELinuxMount geht auf GA und kann auf Enforcing-Clustern Pods am Start hindern.
Check 1: cgroup v1 – der Kubelet startet nicht mehr#
Seit Kubernetes 1.35 ist failCgroupV1 standardmäßig true. Heißt: Auf einem Node mit cgroup v1 verweigert der Kubelet den Start. In 1.37 gibt es noch einen Override — aber der ist ein Countdown, kein Dauerzustand:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failCgroupV1: falseDas ist keine nachhaltige Lösung. Die Entfernung von cgroup v1 ist angekündigt, und die guten neuen Features (In-Place Pod Resizing, Tiered Memory Protection, Memory QoS) funktionieren nur mit v2.
So prüfst du es — auf jedem Node:
stat -fc %T /sys/fs/cgroup/cgroup2fs→ v2, alles in Ordnungtmpfs→ v1, dieser Node blockiert das Upgrade
Wer ist betroffen? Ältere LTS-Installationen, Custom-Kernel und Hosts, die die Migration auf v2 nie gemacht haben. Moderne Distros (Ubuntu 22.04+, RHEL 9+, Flatcar) booten standardmäßig mit v2.
Check 2: containerd 1.x – die letzte Runde#
Dieser Punkt steht im Sneak Peek nicht prominent, ist aber mindestens so wichtig: Kubernetes 1.37 ist die letzte Version, die containerd 1.x unterstützt. Das ist in der Container-Runtimes-Doku explizit: Der Kubelet erfragt den cgroup-Treiber seit Neuerem direkt vom Runtime (RuntimeConfig-RPC). containerd 1.y beherrscht das nicht und der Kubelet fällt auf den eigenen konfigurierten Wert zurück — in 1.38 fällt dieser Fallback weg, dann scheitert der Kubelet mit containerd 1.y (kubeadm Issue #3229).
Der Zeitplan aus der kubeadm-Tracking-Issue:
- 1.35: kubeadm gibt eine Warnung aus, wenn containerd 1.y erkannt wird
- 1.36: containerd 1.7 taucht nicht mehr in der Kubernetes-Support-Matrix auf
- 1.37: letzte unterstützende Version
- 1.38: Error statt Fallback (geplant)
Zum Status von containerd 1.7: Die Version war offiziell LTS bis März 2026, verlängert bis September 2026 — allerdings nur im erweiterten Support mit Fokus auf Kubernetes 1.30–1.32. Wer jetzt auf einem aktuellen Cluster noch 1.7 fährt, steht mit 1.37 vor dem letzten Zug.
So prüfst du es:
kubectl get nodes -o wideDie Spalte CONTAINER-RUNTIME zeigt die Version, z.B. containerd://1.7.20. Alles mit 1.x gehört auf 2.x, bevor 1.38 kommt — je nach Kubernetes-Version sind 2.2 oder neuer die unterstützten Ziele.
Check 3: kube-proxy im ipvs-Modus – die Warning ist da#
Der ipvs-Modus von kube-proxy war schon länger für die Abschaffung vorgesehen: Die Kernel-ipvs-API kann Kubernetes Services nie vollständig abbilden und greift deshalb weiterhin auf iptables zurück — technische Schuld ohne echten Payoff (KEP-5495). Ab 1.37 gibt es dafür eine Deprecation-Warning beim Start. Der Zeitplan:
- 1.37: Warning-Log beim Start
- ~1.40: disabled by default, noch per Feature Gate aktivierbar
- ~1.43: komplett entfernt
So prüfst du es:
kubectl -n kube-system get configmap kube-proxy -o jsonpath='{.data.config\.conf}' | grep 'mode:'Steht dort mode: ipvs, ist noch Zeit — aber die Migration ist nur eine Config-Änderung samt Rollout. Das empfohlene Backend ist nftables; kube-proxy nutzt dafür inzwischen die Kernel-netlink-Schnittstelle statt der nft-CLI (deutlich effizienteres Regel-Management, Release-Notes).
Check 4: Static Pods dürfen keine Secrets mehr referenzieren#
Static Pods laufen aus Manifest-Dateien auf dem Node, nicht über den API-Server — genau für den Bootstrap-Fall, in dem der API-Server noch gar nicht läuft. Dass sie trotzdem configMapRef/secretRef referenzieren konnten, war ein Bug, der in 1.37 behoben wurde: Diese Referenzen sind jetzt strikt verboten, das PreventStaticPodAPIReferences-Feature-Gate wurde entfernt (Sneak Peek).
So prüfst du es:
grep -rlE 'configMapRef|secretRef|configMapKeyRef|secretKeyRef' /etc/kubernetes/manifests/ 2>/dev/nullJeder Treffer ist ein Manifest, das überarbeitet werden muss: Werte direkt einbetten oder den Workload zu einem regulären API-managed Pod machen.
Breaking: SELinuxMount geht auf GA#
SELinuxMount und SELinuxChangePolicy erreichen in 1.37 Stable und sind standardmäßig aktiv — das kann Pods betreffen, auch wenn es keine Deprecation ist.
Was sich ändert: Bisher wurden Volumes rekursiv relabeled. Ab 1.37 mountet die CSI-Integration mit -o context=<label>, sobald ein CSIDriver-Objekt .spec.seLinuxMount: true setzt. Das Problem: Ein Mount kann nur einen SELinux-Context halten. Teilen sich zwei Pods mit unterschiedlichen Labels dasselbe Volume auf demselben Node (bisher dank rekursivem Relabeling kein Problem), startet der zweite Pod nicht mehr (KEP-1710).
Workaround für betroffene Workloads:
spec:
securityContext:
seLinuxChangePolicy: RecursiveDas Verhalten ist erst ab 1.38 gelockt — clusterweites Deaktivieren bleibt also noch einen Release lang möglich.
So prüfst du es: Kein SELinux im Cluster → kein Effekt. Sonst:
getenforce
# Enforcing → prüfen, ob Workloads Volumes über Pods mit unterschiedlichen Labels teilen
# Disabled/Permissive → kein ProblemDie Deprecation, die nicht im Sneak Peek stand: kube-dns#
Erst im finalen Release-Post ist sie aufgetaucht: kube-dns wird eingestellt. CoreDNS ist seit Kubernetes 1.13 der Default, kube-dns hat EndpointSlices und Dual-Stack-Services nie unterstützt. Das Subprojekt ist bereits retired, node-local-dns wurde in ein eigenes Repository ausgelagert und funktioniert mit CoreDNS weiter.
Die Timeline: Nach v1.40 werden keine neuen kube-dns-Packages mehr gebaut (Release-Post). Wer noch kube-dns betreibt, sollte jetzt die Migration zu CoreDNS planen — die Doku beschreibt die Schritte.
So prüfst du es:
kubectl -n kube-system get pods | grep -E 'kube-dns|coredns'kube-dns statt coredns → Migrationsplan erstellen.
Jetzt die guten Nachrichten#
Kubelet in User Namespace (Rootless Mode) → Beta#
Der Kubelet läuft traditionell mit Root-Rechten auf dem Host — ein Kubelet-Exploit bedeutet damit Host-Kompromittierung. In 1.37 geht der Rootless Mode in die Beta: Die Node-Komponenten laufen auf dem Host als unprivilegierter User und verhalten sich nur innerhalb ihres Namespaces wie Root (KEP-2033). Das ist der größte Blast-Radius-Reducer dieses Releases: Ein Kubelet-Exploit landet auf einem Rootless-Node als normaler User — nicht als Root.
Metrics API → GA#
Nach fast neun Jahren Beta ist metrics.k8s.io Stable — die API hinter kubectl top und dem Horizontal Pod Autoscaler. Keine Funktionsänderung, v1 und v1beta1 bleiben beide nutzbar, die Migration ist reine Formsache (Release-Post).
Volume Health Monitor → Alpha (Reset)#
KEP-1432 startet nach einem ersten Anlauf in 1.21 nochmal neu auf Alpha — mit vier neuen CSI-RPCs. CSI-Treiber können Storage-Ausfälle (Inaccessible, Degraded) jetzt maschinenlesbar in PersistentVolumeClaim.status.healthStatus und Pod.status.volumeHealth melden. Noch Alpha, aber die richtige Richtung für Storage-Überwachung.
Gateway API v1.6 – TCPRoute und UDPRoute sind GA#
Nicht direkt Kubernetes-Core, aber zeitgleich: Die Gateway API v1.6.0 holt TCPRoute und UDPRoute aus dem Experimental-Kanal ins v1-API-Release. Datenbanken, DNS, Gaming-Server und IoT-Protokolle routen damit über die Gateway API, ohne Workarounds über normale Services. Gleichzeitig wandern neue experimentelle Ressourcen in eine eigene API-Gruppe (gateway.networking.x-k8s.io) mit X-Prefix — die Grenze zwischen experimenteller und stabiler API ist damit auf Gruppenebene sichtbar.
KYAML – das striktere YAML, jetzt Stable#
SIG CLI hat mit KYAML (KEP-5295) ein striktes YAML-Subset definiert, das die bekannten Fallstricke entschärft:
- Keine stille Typ-Koersion: Strings werden gequotet — der klassische „Norway Bug", bei dem
country: NOals booleanfalsegeparst wird, ist damit ausgeschlossen. - Struktur statt Einrückung: Maps und Listen werden explizit mit
{}und[]geschrieben, keine Whitespace-Fallen mehr. - Besser als JSON: Kommentare und Trailing Commas sind erlaubt — genau das, was JSON nervig macht.
Und das Beste: Alles gültige KYAML ist gültiges YAML. Kein Migrationsaufwand, nur weniger Footguns. kubectl get -o kyaml ist mit den abgeschlossenen Conformance Tests in 1.37 stabil nutzbar (KYAML-Blog).
HPA Scale to Zero – Beta, standardmäßig aktiv#
Der Horizontal Pod Autoscaler kann Workloads auf null Replicas herunterfahren, wenn nichts zu tun ist, und bei Bedarf wieder hochfahren (spec.minReplicas: 0). Klar: Das funktioniert nur mit Object- oder External-Metrics — CPU- und Memory-Werte setzen laufende Pods voraus, die es bei null nicht gibt. Use Cases sind Queue-Consumer, Batch-Jobs und GPU-Workloads. Wer teure GPU-Kapazität für intermittierende Arbeit vorhält, spart hier real Geld.
Die Checks – Zusammenfassung#
Vor dem Upgrade auf 1.37:
# 1. cgroup v2 prüfen – auf JEDEM Node
stat -fc %T /sys/fs/cgroup/
# Erwartet: cgroup2fs
# 2. containerd-Version clusterweit
kubectl get nodes -o wide
# CONTAINER-RUNTIME: containerd://2.x als Ziel, 1.x läuft in 1.37 nur noch mit Warnung
# 3. kube-proxy-Modus
kubectl -n kube-system get configmap kube-proxy -o jsonpath='{.data.config\.conf}' | grep 'mode:'
# ipvs → Migrationsplan erstellen (Entfernung ~1.43, nftables ist das empfohlene Backend)
# 4. Static-Pod-Manifeste auf Secret/ConfigMap-Referenzen
grep -rlE 'configMapRef|secretRef|configMapKeyRef|secretKeyRef' /etc/kubernetes/manifests/ 2>/dev/null
# Keine Treffer erwartetUnd je nach Umgebung:
# 5. SELinux-Status (nur relevant bei Enforcing)
getenforce
# Enforcing → prüfen, ob Pods Volumes über unterschiedliche Labels teilen
# 6. kube-dns im Einsatz?
kubectl -n kube-system get pods | grep -E 'kube-dns|coredns'
# kube-dns statt coredns → ab 1.40 keine Packages mehr, Migration planenFazit#
Kubernetes 1.37 bringt echte Verbesserungen — Rootless Kubelet als Beta, Metrics API GA, KYAML Stable, HPA Scale to Zero. Aber die Deprecations sind das, was ohne vorherige Prüfung zum Incident führt.
Die vier harten Wahrheiten:
- cgroup v1 ist am Ende. Der Override in 1.37 ist ein Countdown, kein Dauerzustand.
- containerd 1.x läuft zum letzten Mal. 1.37 ist die letzte unterstützende Version, ab 1.38 fällt der Fallback weg.
- ipvs ist auf der Abschussliste. Nicht brennend, aber nftables ist besser und die Migration ist nur eine Config-Änderung.
- kube-dns wird eingestellt. Nach 1.40 keine neuen Packages — CoreDNS-Migration jetzt einplanen.
Und die Breaking Change, die keiner erwartet: SELinuxMount GA kann auf Enforcing-Clustern Pods am Start hindern, wenn sie Volumes über unterschiedliche Labels teilen. Erst ab 1.38 ist das Verhalten gelockt.
Erst prüfen, dann upgraden.
Quellen#
- Kubernetes v1.37 Release Announcement (26.08.2026)
- Kubernetes v1.37 Sneak Peek (31.07.2026)
- Kubernetes v1.37 Release Notes (CHANGELOG)
- Kubernetes Docs: Container Runtimes
- Kubernetes Docs: Migrate kube-dns to CoreDNS
- kubeadm Issue #3229: containerd 1.y + Kubernetes 1.37
- containerd RELEASES.md: Support-Matrix und EOL-Daten
- KEP-5495: Deprecate ipvs Mode in kube-proxy
- KEP-5573: Remove cgroup v1 Support
- KEP-2033: Kubelet in UserNS (Rootless Mode)
- KEP-1710: Speed up recursive SELinux label change
- KEP-1432: Volume Health Monitor
- KEP-5295: KYAML
- Blog: How to Pretty-Print Your Kubernetes YAML as KYAML
- Blog: Gateway API v1.6 Release
- StrictYAML: Implicit Typing Removed („Norway Bug")