KEP-5714: Allow specifying whether to unshare cgroup namespaces

Implementation History
ALPHA Implementable
Created 2025-12-03
Latest v1.38
Milestones
Alpha v1.38
Ownership
Owning SIG
SIG Node
Primary Authors

KEP-5714: Allow specifying whether to unshare cgroup namespaces

Release Signoff Checklist

Items marked with (R) are required prior to targeting to a milestone / release.

  • (R) Enhancement issue in release milestone, which links to KEP dir in kubernetes/enhancements (not the initial KEP PR)
  • (R) KEP approvers have approved the KEP status as implementable
  • (R) Design details are appropriately documented
  • (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors)
    • e2e Tests for all Beta API Operations (endpoints)
    • (R) Ensure GA e2e tests meet requirements for Conformance Tests
    • (R) Minimum Two Week Window for GA e2e tests to prove flake free
  • (R) Graduation criteria is in place
  • (R) Production readiness review completed
  • (R) Production readiness review approved
  • “Implementation History” section is up-to-date for milestone
  • User-facing documentation has been created in kubernetes/website, for publication to kubernetes.io
  • Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes

Summary

Allow specifying whether to unshare cgroup namespaces.

So far, cgroup namespaces have been unshared only for non-privileged pods on cgroup v2 nodes.

See the cgroup namespace paragraph in KEP-2254: Cgroups v2 for the reason:

cgroup namespace

A cgroup namespace restricts the view on the cgroups. When unshare(CLONE_NEWCGROUP) is done, the current cgroup the process resides in becomes the root. Other cgroups won’t be visible from the new namespace. It was not enabled by default on a cgroup v1 system as older kernel lacked support for it.

Privileged pods will still use the host cgroup namespace so to have visibility on all the other cgroups.

Motivation

The motivation is to allow privileged pods to unshare cgroup namespaces. This will make resource accounting and enforcements accurate, especially when running nested containers.

See Story 1: BuildKit in User Stories.

Goals

Allow specifying whether to unshare cgroup namespaces.

Non-Goals

Changing the default configuration.

Proposal

Core API

  • Add HostCgroupNamespace *bool to PodSpec. On cgroup v2 nodes, the default value is true for privileged pods, and false for non-privileged pods. On cgroup v1 (deprecated) nodes, the default value is always true. This field could be alternatively named HostCgroups (HostCgroup?) for consistency with HostNetwork, HostUsers, etc., however, it might be confusing as the field actually relates to cgroup namespaces, not to cgroups per se.

  • Add CgroupNamespaces *bool to NodeRuntimeHandlerFeatures for indicating the presence of the feature.

CRI API

pod-security-admission

https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/pod-security-admission/policy/check_hostNamespaces.go will have to be updated to recognize HostCgroupNamespace.

User Stories (Optional)

Story 1: BuildKit

See https://github.com/moby/buildkit/pull/6368:

When buildkitd is run in a managed environment like Kubernetes without its own cgroup namespace (the default behavior of privileged pods in Kubernetes where cgroup v2 is in use; see cgroup v2 KEP), the OCI worker will spawn processes in cgroups that are outside of the cgroup hierarchy that was created for the buildkitd container, leading to incorrect resource accounting and enforcement which in turn can cause OOM errors and CPU contention on the node.

Notes/Constraints/Caveats (Optional)

N/A

Risks and Mitigations

Setting HostCgroupNamespace to true will make other cgroups visible to the pod, however, they are not modifiable unless the pod is running with privileged mode.

Design Details

Test Plan

[X] I/we understand the owners of the involved components may require updates to existing tests to make this code solid enough prior to committing the changes necessary to implement this enhancement.

Prerequisite testing updates
Unit tests
  • k8s.io/kubernetes/pkg/securitycontext: 2025-12-03 - 71.1%

https://github.com/kubernetes/kubernetes/blob/master/pkg/securitycontext/accessors_test.go will be updated to test the default value for privileged and non-privileged pods. In the default mode, kubelet will just pass CgroupnsOptions = nil to the CRI. CRI runtimes will have unit tests for resolving the default cgroup namespace mode.

Integration tests

N/A (other namespace options are not covered in integration tests too)

e2e tests

https://github.com/kubernetes/kubernetes/blob/master/test/e2e/common/node/security_context.go will be updated to test the following configurations:

  • privileged: false, hostCgroupNamespace: false
  • privileged: false, hostCgroupNamespace: true
  • privileged: true, hostCgroupNamespace: false
  • privileged: true, hostCgroupNamespace: true

Similar tests will be added to https://github.com/kubernetes-sigs/cri-tools/blob/master/pkg/validate/security_context_linux.go too.

Graduation Criteria

Alpha

  • Feature implemented behind a feature flag
  • Initial e2e tests completed and enabled

Beta

  • Feature implemented in containerd, CRI-O, and cri-tools

GA

  • Two releases after Beta

Upgrade / Downgrade Strategy

N/A

Version Skew Strategy

N/A

Production Readiness Review Questionnaire

Feature Enablement and Rollback

How can this feature be enabled / disabled in a live cluster?
  • Feature gate (also fill in values in kep.yaml)
    • Feature gate name: CgroupNamespacesSupport
    • Components depending on the feature gate: kubelet and kube-apiserver
  • Other
    • Describe the mechanism:
    • Will enabling / disabling the feature require downtime of the control plane?
    • Will enabling / disabling the feature require downtime or reprovisioning of a node?
Does enabling the feature change any default behavior?

No

Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?

Yes

What happens if we reenable the feature if it was previously rolled back?

If the feature is re-enabled after being previously disabled, any new pods will again have the specified cgroup namespace configuration.

Pods that are already running with the cgroup namespace configuration will continue running with the configuration at the time of execution.

Are there any tests for feature enablement/disablement?

Unit tests:

  • pkg/api/pod
    • With the gate disabled: On dropDisabledFields, the HostCgroupNamespace field is cleared on creating but preserved on updating
    • With the gate enabled: The field is preserved on creating/updating
  • pkg/kubelet/kuberuntime:
    • With the gate disabled: kubelet sends CgroupnsOptions = nil to the CRI runtime regardless to the HostCgroupNamespace configuration
    • With the gate enabled: kubelet sends non-nil CgroupnsOptions to the CRI runtime

Rollout, Upgrade and Rollback Planning

How can a rollout or rollback fail? Can it impact already running workloads?

TODO (beta)

What specific metrics should inform a rollback?

TODO (beta)

Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested?

TODO (beta)

Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.?

TODO (beta)

Monitoring Requirements

TODO (beta)

How can an operator determine if the feature is in use by workloads?

TODO (beta)

How can someone using this feature know that it is working for their instance?

TODO (beta)

  • Events
    • Event Reason:
  • API .status
    • Condition name:
    • Other field:
  • Other (treat as last resort)
    • Details:
What are the reasonable SLOs (Service Level Objectives) for the enhancement?

TODO (beta)

What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?

TODO (beta)

  • Metrics
    • Metric name:
    • [Optional] Aggregation method:
    • Components exposing the metric:
  • Other (treat as last resort)
    • Details:
Are there any missing metrics that would be useful to have to improve observability of this feature?

TODO (beta)

Dependencies

Does this feature depend on any specific services running in the cluster?

A specific version of CRI, with CgroupNamespaces present in RuntimeHandlerFeatures.

Scalability

Will enabling / using this feature result in any new API calls?

No

Will enabling / using this feature result in introducing new API types?

No

Will enabling / using this feature result in any new calls to the cloud provider?

No

Will enabling / using this feature result in increasing size or count of the existing API objects?

Yes, but negligible. Just a single boolean for each of pods and nodes.

Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs?

No

Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, …) in any components?

No

Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)?

No.

If any pod is facing the limit of the number of the cgroup namespaces, it should have been already failing due to the limit of the number of the other namespaces (e.g., mount namespaces).

Troubleshooting

How does this feature react if the API server and/or etcd is unavailable?

Continues to work normally.

What are other known failure modes?

N/A

What steps should be taken if SLOs are not being met to determine the problem?

Implementation History

  • 2026-12-XX: Kubernetes v1.38 (Alpha)

Drawbacks

N/A

Alternatives

A user-provided entrypoint script may execute unshare --cgroup and mount -t cgroup2 none /sys/fs/cgroup, but it can be complicated. See https://github.com/moby/buildkit/pull/6368.

Infrastructure Needed (Optional)

N/A