Kubernetes 1.37: DRA Device Management Lands, and the containerd Deadline Slips Again
— kubernetes, k8s-1.37, release-notes, dra, security, cloud-native — 9 min read
Kubernetes 1.37, named after the Garhwal Himalaya, is a housekeeping release with one clear specialty: device management. Dynamic Resource Allocation (DRA) graduates the pieces a real hardware fleet needs, KYAML and pod certificates reach stable, and a default SELinux mount change may need action on secured clusters. The cleanup is broad too: kube-dns, the ipvs kube-proxy mode, and kubectl run --filename are deprecated, several cAdvisor kubelet flags and scheduling.k8s.io/v1alpha2 are gone, and static Pods can no longer read Secrets or ConfigMaps. The upgrade-planning headline is a repeat: the containerd 1.x removal announced for 1.36, then moved to 1.37, moved again to 1.38, while cgroup v1 stays deprecated rather than removed. This post covers what shipped and what to check.
Previous release: Kubernetes 1.36. This is the latest release in this series.
Devices and scheduling caught up with real fleets
DRA's device story has been landing in stages. The core API went GA in 1.34 and admin access in 1.36. What a real GPU and accelerator fleet still needed was a way to drain a bad device, report device health in a standard way, and place workloads by NUMA (Non-Uniform Memory Access) locality. 1.37 graduates those pieces, and rounds them out with beta scheduling and runtime controls.
DRA device management goes GA GA
DRA (Dynamic Resource Allocation) adds the operational features a real device fleet needs, all at GA in 1.37:
- Device taints and tolerations let an operator mark a device unusable so the scheduler drains it, the same pattern as node taints (KEP #5055).
- ResourceClaim status reports standardized device data, including network interface details, in
.status.devices(KEP #4817). - Extended resource requests via a DRA driver let a driver satisfy classic extended-resource requests (KEP #5004).
- A standard
resource.kubernetes.io/numaNodeattribute gives consistent NUMA-aware placement (KEP #6072).
Adopt if you run DRA for GPUs or accelerators; device taints in particular make maintenance safer. If you do not use DRA yet, nothing changes.
DRA's device-management wave is the substantive story of this release. With device taints, standardized status, and NUMA attributes at GA, DRA is now usable for day-two operations on real accelerator fleets, not just initial allocation. If you run GPUs, 1.37 is the release where DRA becomes operationally complete enough to standardize on.
Gang scheduling is beta Beta
Gang scheduling, all-or-nothing placement for a group of Pods, reaches beta (KEP #4671), with workload-aware preemption alongside it. Note that the GangScheduling and WorkloadAwarePreemption feature gates were removed in favour of a single GenericWorkload gate (changelog). Adopt on test clusters for distributed training.
HPA can scale to zero Beta
The Horizontal Pod Autoscaler (HPA) can now scale a workload to zero Pods when idle, driven by object or external metrics, with spec.minReplicas: 0 (KEP #2021); it is beta and on by default.
spec: minReplicas: 0 # HPA can now scale this workload to zero when idle maxReplicas: 10Notice scale-to-zero suits event-driven or bursty workloads; do not use it for services that must always have a warm Pod.
Memory QoS with cgroup v2 is beta Beta
Memory QoS (Quality of Service) programs cgroup v2 controls (memory.min, memory.low, memory.high) so a Pod's requests protect memory from reclaim and its limits throttle before a hard OOM (KEP #2570). The MemoryQoS gate is enabled by default in 1.37. This needs cgroup v2, which is another reason to finish that migration.
Workload identity landed, and mounts got stricter
The other current in 1.37 is workload identity and node security. Services inside a cluster have leaned on ServiceAccount tokens, which are awkward for mutual TLS (mTLS). Pod certificates give each Pod a real X.509 identity with rotation. Alongside that, SELinux volume handling changes to be faster and safer, admission policy can be enforced from disk at startup, and static Pods lose a bug that let them read API objects.
KYAML is GA GA
KYAML, the safer YAML subset that avoids ambiguous quoting and type coercion, is GA in 1.37 (KEP #5295). kubectl get -o kyaml is now stable output. Every KYAML file is valid YAML, so it is safe to adopt anywhere you generate manifests.
kubectl get deployment myapp -o kyamlNotice this is now the recommended safe output when a tool consumes kubectl YAML, because it removes the class of parsing surprises plain YAML has.
Pod certificates and ClusterTrustBundles are GA GA
Native workload identity reaches stable. The kubelet can generate a key, request a certificate through a PodCertificateRequest, and mount the bundle into the Pod, with automated rotation (KEP #4317). ClusterTrustBundle, the cluster-scoped resource holding trust anchors, is GA too (KEP #3257). Together they give Pods certificate-based identity without a sidecar.
Adopt if you run service-to-service mTLS and want per-Pod certificates managed by Kubernetes.
SELinux mount behaviour changed GA Behaviour change
This is the item most likely to need action on secured clusters. Previously, giving a volume an SELinux label meant recursively relabeling every file, which is slow on large volumes. In 1.37, SELinuxMount and SELinuxChangePolicy are GA and on by default: a volume is mounted with -o context=<label> instead, when its CSI driver sets .spec.seLinuxMount: true (KEP #1710).
Before: attach volume ──▶ recursively relabel every file (slow)After: attach volume ──▶ mount -o context=<label> (instant, one context)Caption: SELinux volumes now carry a single mount context instead of a recursive relabel.
The catch: a mount can carry only one SELinux context. Pods with different SELinux labels that share a volume on the same node behave differently than before. Audit clusters that use SELinux volume labels; the changelog flags this as ACTION REQUIRED.
Admission config from manifest files Beta
Admission configuration can be loaded from manifest files on disk so critical policies are enforced from API server startup, closing a bootstrap gap (KEP #5793).
Removals, and a deadline that keeps slipping
Read this before upgrading. 1.37 removes a batch of old flags and APIs and deprecates two widely used components.
Removed in 1.37
| Item | Replacement | Action | Source |
|---|---|---|---|
cAdvisor kubelet flags (--containerd, --containerd-namespace, --boot-id-file, --machine-id-file, --storage-driver-*, and more) | None; only --housekeeping-interval kept | Remove these from kubelet config or it fails to start | changelog |
scheduling.k8s.io/v1alpha2 (DisruptionMode change) | scheduling.k8s.io/v1alpha3 | Delete v1alpha2 objects before upgrading | changelog |
PreventStaticPodAPIReferences gate | None; behaviour is now enforced | Static Pods must not reference Secrets/ConfigMaps | changelog |
SidecarContainers gate (on since 1.33), AnyVolumeDataSource, RelaxedDNSSearchValidation, OrderedNamespaceDeletion, APIServerTracing and other locked GA gates | Behaviour is permanent | Remove gate overrides | changelog |
kube-controller-manager flag --concurrent-service-syncs (no-op since 1.31) | None | Remove the flag | changelog |
kubeadm v1beta3 config API | v1beta4 | Migrate kubeadm config | changelog |
Deprecated in 1.37 (removed later)
| Item | Target removal | Replacement | Action | Source |
|---|---|---|---|---|
| kube-dns | Not stated | CoreDNS | Migrate to CoreDNS | release blog |
kube-proxy ipvs mode | Disabled by default 1.40, removed 1.43 | nftables | Migrate the backend | KEP #5495 |
kubectl run --filename / -f | Not stated | CLI args (--image, NAME) | Stop using -f with kubectl run | changelog |
cgroup v1 (kubelet failCgroupV1: true) | Future release | cgroup v2 | Migrate nodes to cgroup v2 | KEP #5573 |
Behaviour changes to test first
From the changelog's Urgent Upgrade Notes:
- SELinux mount is GA and default on. On SELinux-enabled clusters this changes how volumes are labeled and can break workloads that share a volume with different contexts. Test before upgrading.
scheduling.k8s.io/v1alpha2dropped. Remove anyv1alpha2scheduling objects first.- kubelet
eventRecordQPS: 0now means unlimited. If you relied on the old behaviour, set an explicit value such as50. - kubelet logs its effective config at startup. Restrict the
nodes/logsClusterRole to trusted users, since config can contain sensitive values. - Static Pods cannot reference API objects. The opt-out gate is gone. A static Pod using
configMapReforsecretRefwill be rejected.
The containerd deadline, again
The single most important planning fact: the containerd 1.x removal and the deprecated kubelet configuration flag cleanup, announced for 1.36 and then moved to 1.37, moved again to 1.38 to align with containerd 1.7 support (changelog #139121).
1.34/1.35 announced: remove containerd 1.x in 1.361.36 changelog: deferred to 1.371.37 changelog: deferred to 1.38Caption: the containerd 1.x removal has slipped twice; plan for 1.38, verify at 1.38.
The recurring deferral is worth a moment. Removing support for a widely deployed runtime is a coordination problem, not a code problem: the project times it to containerd 1.7's own end of support so operators are not stranded. The practical rule this series has shown across four releases is simple. Treat "removed in version N" as a plan until the release notes for version N confirm it. Build your migration on the metric (kubelet_cri_losing_support) and your own inventory, not on a date in an older blog.
Do the containerd 2.0 migration now regardless. The deadline keeps moving, but it is coming, and the modern node features (memory QoS, cgroup v2 resize) need the modern stack anyway.
Before you upgrade
1. remove cAdvisor kubelet flags and --concurrent-service-syncs2. delete scheduling.k8s.io/v1alpha2 objects; migrate kubeadm to v1beta43. test SELinux workloads with the new mount behaviour4. audit static Pods for Secret/ConfigMap references5. upgrade control plane, then nodes6. finish containerd 2.0 + cgroup v2 migration (needed for 1.38 and node features)7. keep 1.36 control-plane images for rollbackCaption: recommended 1.36 to 1.37 upgrade order.
Specifics:
- The removed cAdvisor flags cause a hard kubelet startup failure, so scrub kubelet config first.
- SELinux is the most likely functional break; validate on a canary node.
- Rollback: keep 1.36 control-plane images.
Where to point your next canary
1.37 is a finish-the-job release: DRA's device management is complete, KYAML and pod certificates are stable, and the SELinux mount change is the one default that can surprise a secured cluster. The must-do list before you move: scrub the removed kubelet flags, clear v1alpha2 scheduling objects, and test SELinux workloads on a canary. The containerd deadline moved to 1.38, so finish that migration this cycle rather than waiting for the next date to slip.
A short list to run on a canary before you commit:
- Taint a DRA device and watch the scheduler drain workloads off it.
- Generate KYAML for a manifest:
kubectl get deploy -o kyaml. - Enable a Pod certificate and inspect the mounted bundle.
- Test one SELinux workload under the new mount behaviour on a canary node.
- Confirm your containerd 2.0 and cgroup v2 migration is on track for 1.38.
This concludes the 1.34 through 1.37 series. Start at Kubernetes 1.34 for the DRA GA foundation.
References
Release and dates:
Features:
- DRA device taints: KEP #5055; status: KEP #4817; extended resources: KEP #5004; numaNode: KEP #6072
- KYAML: KEP #5295
- Pod certificates: KEP #4317; ClusterTrustBundles: KEP #3257
- SELinux mount: KEP #1710
- HPA scale to zero: KEP #2021; manifest admission: KEP #5793
- Memory QoS: KEP #2570; gang scheduling: KEP #4671
Deprecations: