Kubernetes 1.37 is not a release to discover that two Pods have been sharing a volume in a way your node security model cannot represent. It shipped on August 26 with a change that makes a good optimization the default: eligible volumes can be mounted with the Pod's SELinux context instead of having a runtime walk and relabel every file. That turns a slow startup path into an immediate mount—but it also makes one old shared-volume pattern fail visibly instead of continuing by accident.
For a self-hosted PaaS, that is useful pressure. A platform should know exactly which workload owns a volume, which context sees it, and whether a privileged operational Pod shares it with a tenant workload. The upgrade is not a blanket security win by itself; its value is that it makes incompatible label sharing a deterministic condition that an operator can find and handle before it becomes a deployment outage.
The answer first: what changes between 1.36 and 1.37
Here is the operator-facing difference. Kubernetes 1.36 is the audit release; 1.37 is the default-behavior release.
| Release | What is stable or enabled | What happens to an eligible volume | Action for a PaaS operator |
|---|---|---|---|
| 1.36 | SELinuxMountReadWriteOncePod and SELinuxChangePolicy are GA. The broader SELinuxMount gate remains Beta and off by default. | A ReadWriteOncePod volume can use the mount option. Other eligible volumes retain recursive relabeling unless the broader gate is deliberately enabled. | Turn on the warning controller, inventory CSI support, and find label conflicts while the safe fallback is still the default. |
| 1.37 | SELinuxMount is GA and enabled by default for eligible volumes. | Kubelet supplies -o context=<label>; two different contexts cannot occupy the same mount on one node. A conflicting Pod can remain ContainerCreating. | Fix the storage topology or apply the narrow Recursive opt-out before upgrading node pools. |
This is not a change for every cluster. Kubernetes skips this logic when SELinux is absent or disabled on the Linux node. It also does not apply just because a cluster has a securityContext: the Pod, its PVC, and the storage driver must meet the eligibility rules. The upstream 1.36 guidance and 1.37 release page are worth reading together because they explain the staging and the final default separately.
Why a mount label changes both startup time and compatibility
SELinux is a mandatory access-control system: processes and objects carry labels, and policy decides whether one label may access another. Historically, Kubernetes passed a Pod's context to the container runtime, which then recursively relabeled the files visible in the Pod's volumes. On a large or remote filesystem, walking every directory and inode can delay startup substantially.
The newer path is different. Kubelet asks the volume implementation to mount with -o context=<label>, so the kernel presents the needed context through that mount without a recursive traversal. The upstream project describes that as constant-time setup for qualifying mounts—not a universal speed claim for every storage class or filesystem. Kubernetes' feature-gate reference calls out the same distinction: the new path widens the optimization from ReadWriteOncePod volumes to eligible volumes more generally.
Before assuming a workload takes that path, confirm all of these conditions:
- The node runs Linux with SELinux available and enforcing.
- The workload uses a PVC. Secret, ConfigMap, and projected volumes do not use this mount optimization.
- The access mode and feature-gate state make the PVC eligible.
ReadWriteOncePodis the low-risk case; the broader path is the 1.37 default. - Kubernetes knows an SELinux label—at minimum, the Pod or its relevant containers specify
seLinuxOptions.level. - The CSI driver explicitly opts in with
spec.seLinuxMount: true. A driver that represents a directory inside a larger shared filesystem normally should not claim that capability.
That last condition belongs in the platform's storage acceptance criteria. The CSIDriver API says a driver that advertises seLinuxMount: true must be able to mount its volumes separately with different context options. Kubelet verifies the result; a driver that advertises support but cannot honor it leaves affected Pods unable to start. “Set the field everywhere” is therefore not a migration plan.
The compatibility trap: one shared volume, two labels
The important break is not “a Pod has SELinux.” It is “two Pods need one eligible mounted volume on the same node, but need different SELinux contexts.” Recursive relabeling historically allowed two patterns that the mount-option model deliberately cannot preserve:
- Two Pods use different
subPathvalues from the same volume and have different labels. - A privileged operations Pod and an unprivileged application Pod share a volume.
Consider a platform-managed application that writes import files to a shared PVC while a privileged repair or migration job mounts the same claim. The app has a container label; the repair job has the privileged spc_t type. With the old recursive path, that arrangement could run. With an SELinux context mount, one mount has one context. If both Pods land on the same node, kubelet must refuse one rather than present the shared mount as both labels. The blocked Pod stays in ContainerCreating until the conflict is removed.
That is the multi-tenant hardening step in practical terms: the platform no longer quietly proceeds with a shared mount arrangement whose access contexts conflict. It is not a substitute for per-tenant volume ownership, namespace isolation, admission control, or a careful privileged-access design. It is a fail-closed boundary that makes a bad sharing shape visible.
When an application genuinely requires the old pattern, make the exception explicit and local to that Pod instead of disabling the new behavior fleet-wide:
apiVersion: v1
kind: Pod
metadata:
name: legacy-volume-maintenance
spec:
securityContext:
seLinuxChangePolicy: Recursive
seLinuxOptions:
level: "s0:c42,c77"
containers:
- name: maintenance
image: example/maintenance:1.0
securityContext:
privileged: true
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: tenant-importsRecursive is a compatibility escape hatch, not a default policy to stamp into every generated manifest. It gives an operator a reviewable exception with an owner and an expiry path. A platform should also ask whether a privileged repair job needs to share a tenant volume at all; a one-shot job scheduled after the app releases the claim is often a cleaner design.
Run this audit before a node-pool upgrade
The audit has four parts. Do it per node pool and storage class, not once for a whole fleet, because mixed operating systems and CSI drivers produce different answers.
| Finding | Meaning | Next move |
|---|---|---|
| SELinux disabled or unavailable on the node image | This feature has no effect for that pool. | Record the exemption; do not report it as a completed SELinux audit. |
CSI driver does not advertise seLinuxMount: true | Kubernetes retains recursive relabeling for that driver. | Validate driver roadmap before expecting the startup optimization. |
| Warning controller sees no conflicts | Eligible workloads are ready for the default mount path. | Stage 1.37 in a canary pool and watch kubelet events. |
| Controller finds a conflict | A scheduler placement can create a blocked Pod after the default changes. | Split the volume use, align labels, serialize access, or add a narrowly scoped Recursive policy. |
First, inventory node operating-system policy. Kubernetes does not infer “SELinux enforcing” from a namespace label; inspect the immutable image and node-pool configuration, then confirm it on a representative node with your approved host-debug procedure. Pools based on a non-SELinux image should be documented as unaffected, while enforcing pools go through the rest of the checklist.
Second, list the storage drivers and their declaration:
kubectl get csidriver -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.seLinuxMount}{"\n"}{end}'An empty or false value is meaningful: it says Kubernetes must not pass the context mount option to that driver. Match the true entries to the StorageClasses and PVCs tenants actually use; a capability on an unused driver does not make an application eligible.
Third, enable the opt-in selinux-warning-controller in kube-controller-manager on clusters that use SELinux. The upstream configuration is --controllers=*,selinux-warning-controller. It emits Events for potentially incompatible Pods and exposes the selinux_warning_controller_selinux_volume_conflict metric. Scrape the controller-manager metrics through the same authenticated monitoring path used for your control plane, alert on a nonzero value, and inspect the associated Pods and claims. The Kubernetes security-context documentation specifically recommends reaching zero conflicts before moving to 1.37 or later.
Finally, test the remediation on a non-production copy of each identified topology. An event is deliberately conservative: it can warn about Pods scheduled on different nodes because a later reschedule could co-locate them. Treat that as an upgrade test case, not noise to suppress.
Make the PaaS contract clearer, not broader
For a git-push platform, the safest default is usually simple: each deployed service gets its own claim, and platform maintenance never shares a writable tenant mount while the service is live. That design makes SELinux context mounting a startup improvement and a useful guardrail, not a compatibility gamble.
The tricky cases deserve an explicit contract: which system jobs may mount tenant data, whether they are privileged, whether the mount is exclusive, and which StorageClasses permit multi-Pod sharing. Put seLinuxChangePolicy: Recursive behind the same review path as any other privileged storage exception. Do not use it to hide a controller alert and assume the security story is complete.
A staged rollout also keeps the operational lesson small. Enable the warning controller on 1.36-capable control planes; resolve or document each conflict; upgrade a canary node pool; then watch for ContainerCreating Pods and volume-mount errors before advancing the fleet. Kubernetes' KEP recorded warning-controller conflicts in only a small minority of observed OpenShift clusters, but “rare” is not the same as “safe to skip”—a single shared volume can block a production deploy. The SELinux relabeling KEP is especially helpful for the precise phases, telemetry, and rollback behavior.
Kubernetes 1.37 makes the fast, context-mounted path the normal one for eligible storage. Audit it as a storage-design change, use Recursive only as a named compatibility decision, and let the warning controller find the ambiguous mounts while you still have time to fix them.
Bex.co is the open-source, AI-native Render alternative: push a git repo and get a running HTTPS service on machines you own. Its Cluster-API foundation makes node-pool and storage behavior something operators can inspect and control, rather than an opaque platform assumption. Star the project on GitHub or explore the deployment model at Bex.co.
Sources
- Kubernetes: SELinux Volume Label Changes goes GA (and likely implications in v1.37)
- Kubernetes: Configure a Security Context for a Pod or Container
- Kubernetes: CSIDriver API reference
- Kubernetes: v1.37 release series
- Kubernetes Enhancement Proposal 1710: Speed up SELinux volume relabeling using mounts



