Prepare a Kubernetes Cluster for v1.37 Before the Upgrade Window

John Burns

Kubernetes v1.37 is planned for 26 August 2026. The release preview is not a final change log, but it is early enough to turn into a controlled readiness check rather than a surprise during an upgrade window. The practical outcome is an evidence pack that identifies nodes still using cgroup v1, confirms the kube-proxy mode, finds static Pod manifests that refer to API objects, and records the workload and storage cases that need a staging test.

This is not an instruction to upgrade a production cluster on the day a preview appears. Run the read-only checks first, keep the output with the change record, and repeat the checks against the final v1.37 release notes. The commands are documentation-verified examples. They need a Kubernetes context with permission to read nodes, kube-system objects, and, where applicable, control-plane host files. Do not paste cluster credentials, Secret values, or complete manifests into a ticket or a public repository.

Start with a version and ownership record

Capture the current server and client versions before looking for release-specific issues. This distinguishes an existing condition from one introduced by a later upgrade and tells reviewers which component owners must sign off.

kubectl version
kubectl get nodes -o wide
kubectl get pods -A
kubectl get csidrivers

Save the commands and their output in the change record, with any internal addresses removed. kubectl get nodes -o wide gives a quick view of the node operating systems, container runtimes, internal addresses, and kubelet versions. The all-namespaces pod list is not proof that applications are healthy, but it gives a baseline for later comparison. The CSIDriver objects identify storage drivers that may need review when a release changes volume handling.

Also identify how the cluster is installed and upgraded. A managed service, kubeadm, a distribution such as k3s, and a cluster built by another lifecycle tool have different control-plane ownership and upgrade procedures. Do not apply kubeadm commands to a managed control plane. For kubeadm clusters, Kubernetes documents a sequential minor-version upgrade path: primary control plane, additional control planes, then workers. It also requires draining a node before a minor kubelet upgrade.

Check cgroup v2 on every Linux node

The v1.37 preview says cgroup v1 support is being phased out. Since Kubernetes v1.35, the kubelet configuration default for failCgroupV1 has been true; a node using cgroup v1 needs an explicit temporary override to start. The preview says that override remains available in v1.37, but it should not become the upgrade plan. Features such as in-place Pod resizing and tiered memory protection depend on cgroup v2.

Start from Kubernetes and find the nodes that need host-level confirmation:

kubectl get nodes -o custom-columns=NAME:.metadata.name,OS:.status.nodeInfo.osImage,KUBELET:.status.nodeInfo.kubeletVersion

On each Linux node, using the approved administrative path for that environment, run:

stat -fc %T /sys/fs/cgroup
cat /proc/cmdline

cgroup2fs from the first command indicates a unified cgroup v2 hierarchy. Record any other result as a blocker for the platform owner to investigate. The kernel command line is useful supporting evidence because boot parameters can affect the hierarchy that systemd and the runtime see.

Do not change failCgroupV1: false merely to make an upgrade proceed. Treat it as a temporary exception with an owner and removal date if the distribution documentation permits it. Validate the operating system, systemd, container runtime, and kubelet combination in a representative staging node before changing the production boot configuration. A cgroup migration changes host resource-control behavior, not just a Kubernetes setting.

Inventory static Pod manifests

A static Pod is read directly by a kubelet from a local manifest rather than created through the API server. The v1.37 preview says static Pods can no longer reference Secrets or ConfigMaps through fields such as secretRef or configMapRef; the feature gate that previously allowed the behavior is being removed.

For a kubeadm control plane, static manifests normally live in /etc/kubernetes/manifests. On every control-plane node, inspect that directory locally with the appropriate privileged access:

sudo find /etc/kubernetes/manifests -maxdepth 1 -type f -name '*.yaml' -print
sudo grep -RInE 'secretRef|configMapRef' /etc/kubernetes/manifests

An empty grep result is the desired result. A match is not a reason to edit a production manifest immediately. First identify the component owner, determine whether the reference is actually part of a static Pod spec, and design a replacement that supplies the required data without asking a static Pod to read an API object. Keep a backup and a tested rollback procedure for every control-plane manifest change. A malformed static manifest can take down a control-plane component on that node.

Other installers may store manifests elsewhere or generate them from a lifecycle tool. In that case, inspect the tool’s source of truth and the rendered node files. Editing a generated file only proves that the generator will overwrite it later.

Record kube-proxy mode before it becomes urgent

The v1.37 preview deprecates kube-proxy ipvs mode. The published timeline says it is expected to be disabled by default by v1.40 and removed by v1.43, so this is a planning item rather than a v1.37 outage. It still deserves an inventory now because Service behavior, load balancers, NetworkPolicy enforcement, and observability often depend on the chosen dataplane.

For clusters where kube-proxy is configured through the usual kube-system ConfigMap, use the command supplied by the Kubernetes release preview:

kubectl -n kube-system get configmap kube-proxy \
  -o jsonpath='{.data.config\.conf}' | grep 'mode:'

Record ipvs, iptables, or nftables exactly as reported. Do not assume that the absence of ipvs means a migration is complete: some distributions manage kube-proxy outside that ConfigMap, and some replace kube-proxy with an eBPF dataplane. Check the distribution or CNI documentation before changing the mode.

If the result is ipvs, create a staged migration plan rather than changing production configuration in place. The test should cover ClusterIP and headless Services, NodePort or LoadBalancer traffic where used, DNS, hairpin traffic, source-IP expectations, and NetworkPolicy behavior. Capture the expected paths before the test so that a successful TCP connection does not hide a broken health check or affinity rule.

Test SELinux volume-label behavior in staging

The preview also says the SELinuxMount behavior is expected to reach general availability and become enabled by default in v1.37, but only for CSI drivers that opt in through .spec.seLinuxMount: true. The important case is a volume shared on the same node by Pods that use different SELinux labels. A single mount can have only one context, so a workload that previously relied on recursive relabeling may fail to start.

First check whether SELinux and an opting-in driver are present. The exact host command depends on the operating system, but this Kubernetes query is safe to run from an administrative workstation:

kubectl get csidriver -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.seLinuxMount}{"\n"}{end}'

For an affected driver, reproduce the application’s real volume-sharing pattern in a non-production namespace. Use a copy of the Pod security context and storage class with non-sensitive test data. Test scheduling the Pods onto the same node, mounting the same volume, reading and writing a harmless file, then deleting and recreating the Pods. Inspect events and kubelet logs if a mount or startup fails. The preview documents seLinuxChangePolicy: Recursive as a workload-specific way to retain prior behavior; use it only after confirming that recursive relabeling is acceptable for that workload and storage backend.

Define the exit criteria before scheduling the upgrade

The readiness review is complete when every Linux node has a recorded cgroup hierarchy, static Pod manifest references have been resolved or accepted with a documented exception, the kube-proxy mode has an owner and migration decision, and any affected CSI driver has a staging result. Add the final v1.37 release notes to the review when they are published because the sneak peek explicitly says its contents can change before release.

Only then schedule the ordinary platform upgrade process. For a kubeadm cluster, that includes checking the release notes, taking required application backups, reviewing kubeadm upgrade plan, upgrading control-plane nodes sequentially, draining each node before its minor kubelet upgrade, and verifying every node returns to Ready. After the maintenance window, compare the post-upgrade node versions and workload state with the baseline. The goal is not simply a control plane that reports a new version; it is a cluster whose documented dependencies still behave as expected.

Verification checklist

Before approving an upgrade window, confirm the following:

  • Every Linux node reports cgroup2fs, or has a documented, time-bounded exception owned by the platform team.
  • Static Pod manifests contain no unsupported API references, or their replacement is tested.
  • The kube-proxy mode is recorded and any ipvs migration has a staged test plan.
  • SELinux-enabled workloads using an opting-in CSI driver have been tested with their real volume-sharing pattern.
  • Final v1.37 release notes have been reviewed immediately before the change window.
  • Post-upgrade checks show every node Ready and the expected workload health.

Sources