---
title: "The Shift to cgroup v2 in Kubernetes: What You Need to Know - Angryecho"
description: "In Linux, cgroups (control groups) are a kernel feature used for managing system resources."
canonical_url: "https://www.angryecho.com/c/DevOps/p/P2TBBk0tWIPQGoaNuNiGy"
meta:
  "og:description": "In Linux, cgroups (control groups) are a kernel feature used for managing system resources."
  "og:image": "https://www.angryecho.com/_og/d/c_Post%2Ctitle_~5ZCQ5qe9572R%2Cdescription_~5ZCQ5qe95LiA5LiL77yM5bCx5LiK5ZCQ5qe9572R44CC%2CpostId_P2TBBk0tWIPQGoaNuNiGy%2Crevision_~MjAyNi0xMC0yNVQwMjo1Nzo1MC4xODM3Nzla%2Cp_Ii9jL0Rldk9wcy9wL1AyVEJCazB0V0lQUUdvYU51TmlHeSI%2Cs_er0oNgIEDL9vE_pL.png"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "The Shift to cgroup v2 in Kubernetes: What You Need to Know"
---

> Index of every page on this site: [llms.txt](https://www.angryecho.com/llms.txt)

# **The Shift to cgroup v2 in Kubernetes: What You Need to Know**

In Linux, *cgroups* (control groups) are a kernel feature used for managing system resources. Kubernetes uses cgroups to allocate resources like CPU and memory to containers, ensuring that applications run smoothly without interfering with each other. With the release of Kubernetes v1.31, support for v1 cgroup management moved into [maintenance mode](https://kubernetes.io/blog/2024/08/14/kubernetes-1-31-moving-cgroup-v1-support-maintenance-mode/). Support for v2 cgroup management has been stable since Kubernetes v1.25.

Compared with cgroup v1, cgroup v2 provides a single unified hierarchy, a more consistent interface, and a stronger foundation for resource isolation and modern resource-management features.

## Deprecation of cgroup v1

Kubernetes has [deprecated cgroup v1](https://kubernetes.io/docs/concepts/architecture/cgroups/#deprecation-of-cgroup-v1). Starting with Kubernetes v1.35, `failCgroupV1` defaults to `true`, so the kubelet does not start on a cgroup v1 node by default. Administrators can temporarily set `failCgroupV1: false` in the [kubelet configuration file](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/), but removal will follow the [Kubernetes deprecation policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/). Further removal work is tracked in [KEP-5573: Remove cgroup v1 support](https://www.kubernetes.dev/resources/keps/5573).

If you are still on a release older than v1.35, migrate every Linux node to cgroup v2 before upgrading, or plan to set the temporary `failCgroupV1: false` override. If you are already on v1.35 or later, confirm that every Linux node runs cgroup v2 (or that you intentionally keep the override). Under the default configuration, a remaining cgroup v1 node fails during kubelet startup.

For kubeadm-managed clusters, Kubernetes v1.35 also makes this an earlier, stricter check. The `SystemVerification` preflight check, provided by `k8s.io/system-validators`, returns an error during `kubeadm init`, `kubeadm join`, and `kubeadm upgrade` when it detects cgroup v1 with kubelet v1.35 or later; with an older kubelet, the check remains a warning. See [kubernetes/system-validators#1.12.1 release notes](https://github.com/kubernetes/system-validators/releases/tag/v1.12.1) for details.

The top FAQs cover three main areas: why to migrate, the benefits and drawbacks, and key points to keep in mind when using cgroup v2.

## Limitations of cgroup v1 and Improvements with cgroup v2

The Linux kernel documentation describes both interfaces:

- [cgroup v1 documentation](https://www.kernel.org/doc/Documentation/cgroup-v1/)
- [cgroup v2 documentation](https://docs.kernel.org/admin-guide/cgroup-v2.html)

Let's enumerate some known issues.

### `active_file` memory is not considered available memory

The kubelet treats `active_file` memory as not reclaimable. For I/O-intensive workloads, a large page cache can therefore make the kubelet report memory pressure and evict Pods. This is a [known kubelet issue](https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#active-file-memory-is-not-considered-as-available-memory) ([kubernetes/kubernetes#43916](https://github.com/kubernetes/kubernetes/issues/43916)); migrating to cgroup v2 does not by itself change that calculation. The documented workaround is to set equal memory requests and limits for containers that perform intensive I/O, after measuring an appropriate value.

### Memory QoS updates in Kubernetes v1.36

[Memory QoS](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#memory-qos-with-cgroup-v2) was introduced as an alpha feature in Kubernetes v1.22 and updated in v1.27. It remains alpha in v1.36, but now separates memory throttling from memory reservation and adds [tiered memory protection](https://kubernetes.io/blog/2026/04/29/kubernetes-v1-36-memory-qos-tiered-protection/):

Memory QoS is available **only** on Linux nodes that use cgroup v2. It relies on the cgroup v2 memory controller: `memory.high` provides throttling, while `memory.min` and `memory.low` provide hard and soft protection when tiered reservation is enabled. cgroup v1 cannot provide this protection model.

- Enabling the `MemoryQoS` feature gate applies `memory.high` throttling to Burstable containers. The threshold is derived from the request, limit, and `memoryThrottlingFactor` (default `0.9`).
- `memoryReservationPolicy: None` is the default. It does not write `memory.min` or `memory.low`.
- `memoryReservationPolicy: TieredReservation` maps Guaranteed Pod memory requests to `memory.min` (hard protection) and Burstable Pod requests to `memory.low` (soft protection). BestEffort Pods receive neither protection.
- The kubelet exposes Alpha metrics for the total `memory.min` and `memory.low` reservations on a node.
- Kernel 5.9 or later is recommended. On older kernels, `memory.high` reclaim can trigger a known livelock; from v1.36 the kubelet logs a warning when Memory QoS is enabled on an affected kernel.

For example, to opt in to tiered protection:

```
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
MemoryQoS: true
memoryReservationPolicy: TieredReservation
memoryThrottlingFactor: 0.9
```

The overall Kubernetes recommendation is not to enable Alpha features in production; however, if you judge that memory QoS with tiered reservations is useful for your platform in production, make sure to test the configuration **and** account for hard-reserved memory before you enable the `TieredReservation` feature gate. See the [Pod QoS](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#memory-qos-with-cgroup-v2) documentation for the current mapping of Kubernetes QoS classes to cgroup v2 controls.

### Container-aware OOM handling

On cgroup v2 nodes, the kubelet defaults `singleProcessOOMKill` to `false`. It therefore sets `memory.oom.group` for each container cgroup so that an OOM event kills all processes in that container together, rather than leaving a partially functioning multi-process container. Set `singleProcessOOMKill: true` only if you need the cgroup v1-compatible behavior where the kernel may kill one process at a time. See the `[KubeletConfiguration](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)`[ reference](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration) for this setting.

This behavior is scoped to a container cgroup, not the whole Pod. Also, `cgroup.kill` is a separate administrative interface: writing `1` to it sends `SIGKILL` to every process in that cgroup and its descendants; it does not configure OOM behavior. The cgroup v2 memory controller additionally provides `memory.events` counters that monitoring systems and userspace OOM managers can observe.

### Rootless support

In cgroup v1, delegating controllers to less privileged containers may be dangerous.

Unlike cgroup v1, cgroup v2 officially supports delegation. Most implementations of rootless containers rely on systemd for delegating v2 controllers to non-root users.

This delegation mechanism is separate from Kubernetes Pod user namespaces, which map container users to unprivileged host users. [Pod user namespace support](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/) graduated to stable in Kubernetes v1.36; check its filesystem, kernel, CRI runtime, and OCI runtime prerequisites before enabling it.

### What else?

1. eBPF stories:

- In cgroup v1, device access controls are exposed through interface files.
- The cgroup v2 device controller has no interface files, and is implemented on top of cgroup BPF.
- Cilium attaches BPF cgroup programs for socket-based load balancing. Its [default cgroup root](https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/#validate-bpf-cgroup-programs-attachment) is `/run/cilium/cgroupv2`.

2. [Pressure Stall Information (PSI)](https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/) reports CPU, memory, and I/O contention at node, Pod, and container level. On supported clusters, the kubelet exposes PSI by default ( `KubeletPSI` is stable and locked on). PSI requires cgroup v2, Linux 4.20 or later, `CONFIG_PSI=y`, and a kernel not booted with `psi=0`. The kubelet surfaces the data through the [Summary API](https://kubernetes.io/docs/reference/instrumentation/node-metrics/#summary-api-source) and `/metrics/cadvisor`.
3. When migrating, update software that reads the cgroup filesystem directly. The [migration guidance](https://kubernetes.io/docs/concepts/architecture/cgroups/#migrating-cgroupv2) recommends cAdvisor v0.43.0 or later and lists compatible Java, Node.js, and `automaxprocs` versions.

### CPU weight conversion in newer OCI runtimes

cgroup v1 uses `cpu.shares`, whereas cgroup v2 uses `cpu.weight`. Newer OCI runtimes use an improved non-linear conversion that preserves the default priority and gives small CPU requests more usable granularity. The change is implemented in the OCI runtime rather than Kubernetes: it is available in crun v1.23 and runc v1.3.2. After upgrading a runtime, monitoring or policy tools that predict exact `cpu.weight` values may need updates. Read [New Conversion from cgroup v1 CPU Shares to v2 CPU Weight](https://kubernetes.io/blog/2026/01/30/new-cgroup-v1-to-v2-cpu-conversion-formula/) for the formula, examples, and compatibility considerations.

### In-place resource updates

[In-place Pod vertical scaling](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-resize-inplace) graduated to stable in Kubernetes v1.35. Kubernetes v1.36 then [enabled](https://kubernetes.io/blog/2026/04/30/kubernetes-v1-36-inplace-pod-level-resources-beta/) in-place vertical scaling for Pod-level resources by default, as a Beta feature. The kubelet coordinates changes between the Pod-level and container cgroups so that increases create headroom before container limits grow, while decreases constrain containers before shrinking the Pod-level boundary. Accurate aggregate enforcement for this v1.36 feature requires cgroup v2.

（节选）

> 原文： [Kubernetes Blog｜The Shift to cgroup v2 in Kubernetes: What You Need to Know](https://kubernetes.io/blog/2026/10/06/kubernetes-cgroups-v2-shift/)，2026-10-07

排序方式 :

### **成为第一条评论！**

Nobody's responded to this post yet. Add your thoughts and get the conversation going.

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://www.angryecho.com/c/DevOps/p/P2TBBk0tWIPQGoaNuNiGy#post","@type":"DiscussionForumPosting","commentCount":0,"dateModified":"2026-10-25T02:57:50.183Z","datePublished":"2026-10-06T18:00:00.000Z","description":"In Linux, cgroups (control groups) are a kernel feature used for managing system resources.","headline":"The Shift to cgroup v2 in Kubernetes: What You Need to Know","isPartOf":"https://www.angryecho.com/c/DevOps","mainEntityOfPage":"https://www.angryecho.com/c/DevOps/p/P2TBBk0tWIPQGoaNuNiGy","text":"In Linux, cgroups (control groups) are a kernel feature used for managing system resources.\nKubernetes uses cgroups to allocate resources like CPU and memory to containers,\nensuring that applications run smoothly without interfering with each other.\nWith the release of Kubernetes v1.31, support for v1 cgroup management moved into\nmaintenance mode.\nSupport for v2 cgroup management has been stable since Kubernetes v1.25.\n\nCompared with cgroup v1, cgroup v2 provides a single unified hierarchy,\na more consistent interface, and a stronger foundation for resource isolation\nand modern resource-management features.\n\nDeprecation of cgroup v1\n\nKubernetes has deprecated cgroup v1.\nStarting with Kubernetes v1.35, failCgroupV1 defaults to true, so the kubelet does not start\non a cgroup v1 node by default. Administrators can temporarily set failCgroupV1: false in the\nkubelet configuration file, but removal will\nfollow the Kubernetes deprecation policy.\nFurther removal work is tracked in KEP-5573: Remove cgroup v1 support.\n\nIf you are still on a release older than v1.35, migrate every Linux node to\ncgroup v2 before upgrading, or plan to set the temporary failCgroupV1: false\noverride. If you are already on v1.35 or later, confirm that every Linux node\nruns cgroup v2 (or that you intentionally keep the override). Under the default\nconfiguration, a remaining cgroup v1 node fails during kubelet startup.\n\nFor kubeadm-managed clusters, Kubernetes v1.35 also makes this an earlier, stricter check. The\nSystemVerification preflight check, provided by k8s.io/system-validators, returns an error during\nkubeadm init, kubeadm join, and kubeadm upgrade when it detects cgroup v1 with kubelet v1.35 or\nlater; with an older kubelet, the check remains a warning. See\nkubernetes/system-validators#1.12.1 release notes for details.\n\nThe top FAQs cover three main areas: why to migrate, the benefits and drawbacks,\nand key points to keep in mind when using cgroup v2.\n\nLimitations of cgroup v1 and Improvements with cgroup v2\n\nThe Linux kernel documentation describes both interfaces:\n\n\n\n\n\ncgroup v1 documentation\n\n\n\ncgroup v2 documentation\n\nLet's enumerate some known issues.\n\nactive_file memory is not considered available memory\n\nThe kubelet treats active_file memory as not reclaimable. For I/O-intensive workloads, a large\npage cache can therefore make the kubelet report memory pressure and evict Pods. This is a\nknown kubelet issue\n(kubernetes/kubernetes#43916); migrating to\ncgroup v2 does not by itself change that calculation. The documented workaround is to set equal\nmemory requests and limits for containers that perform intensive I/O, after measuring an appropriate\nvalue.\n\nMemory QoS updates in Kubernetes v1.36\n\nMemory QoS was introduced as an alpha feature in Kubernetes v1.22 and\nupdated in v1.27. It remains alpha in v1.36, but now separates memory throttling from memory\nreservation and adds tiered memory protection:\n\nMemory QoS is available only on Linux nodes that use cgroup v2. It relies on the cgroup v2 memory\ncontroller: memory.high provides throttling, while memory.min and memory.low provide hard and\nsoft protection when tiered reservation is enabled. cgroup v1 cannot provide this protection model.\n\n\n\n\n\nEnabling the MemoryQoS feature gate applies memory.high throttling to Burstable containers.\nThe threshold is derived from the request, limit, and memoryThrottlingFactor (default 0.9).\n\n\n\nmemoryReservationPolicy: None is the default. It does not write memory.min or memory.low.\n\n\n\nmemoryReservationPolicy: TieredReservation maps Guaranteed Pod memory requests to memory.min\n(hard protection) and Burstable Pod requests to memory.low (soft protection). BestEffort Pods\nreceive neither protection.\n\n\n\nThe kubelet exposes Alpha metrics for the total memory.min and memory.low reservations on a node.\n\n\n\nKernel 5.9 or later is recommended. On older kernels, memory.high reclaim can trigger a known\nlivelock; from v1.36 the kubelet logs a warning when Memory QoS is enabled on an affected kernel.\n\nFor example, to opt in to tiered protection:\n\napiVersion: kubelet.config.k8s.io/v1beta1\nkind: KubeletConfiguration\nfeatureGates:\nMemoryQoS: true\nmemoryReservationPolicy: TieredReservation\nmemoryThrottlingFactor: 0.9\n\nThe overall Kubernetes recommendation is not to enable Alpha features in production; however, if you\njudge that memory QoS with tiered reservations is useful for your platform in production, make sure\nto test the configuration and account for hard-reserved memory before you enable\nthe TieredReservation feature gate.\nSee the\nPod QoS documentation\nfor the current mapping of Kubernetes QoS classes to cgroup v2 controls.\n\nContainer-aware OOM handling\n\nOn cgroup v2 nodes, the kubelet defaults singleProcessOOMKill to false. It therefore sets\nmemory.oom.group for each container cgroup so that an OOM event kills all processes in that\ncontainer together, rather than leaving a partially functioning multi-process container. Set\nsingleProcessOOMKill: true only if you need the cgroup v1-compatible behavior where the kernel\nmay kill one process at a time. See the\nKubeletConfiguration reference\nfor this setting.\n\nThis behavior is scoped to a container cgroup, not the whole Pod. Also, cgroup.kill is a separate\nadministrative interface: writing 1 to it sends SIGKILL to every process in that cgroup and its\ndescendants; it does not configure OOM behavior. The cgroup v2 memory controller additionally\nprovides memory.events counters that monitoring systems and userspace OOM managers can observe.\n\nRootless support\n\nIn cgroup v1, delegating controllers to less privileged containers may be dangerous.\n\nUnlike cgroup v1, cgroup v2 officially supports delegation.\nMost implementations of rootless containers rely on systemd for\ndelegating v2 controllers to non-root users.\n\nThis delegation mechanism is separate from Kubernetes Pod user namespaces, which map container\nusers to unprivileged host users. Pod user namespace support\ngraduated to stable in Kubernetes v1.36; check its filesystem, kernel, CRI runtime, and OCI runtime\nprerequisites before enabling it.\n\nWhat else?\n\n\n\n\n\neBPF stories:\n\n\n\n\n\nIn cgroup v1, device access controls are exposed through interface files.\n\n\n\nThe cgroup v2 device controller has no interface files, and is implemented on top of cgroup BPF.\n\n\n\nCilium attaches BPF cgroup programs for socket-based load balancing. Its\ndefault cgroup root\nis /run/cilium/cgroupv2.\n\n\n\n\n\nPressure Stall Information (PSI)\nreports CPU, memory, and I/O contention at node, Pod, and container level. On supported\nclusters, the kubelet exposes PSI by default (KubeletPSI is stable and locked on). PSI\nrequires cgroup v2, Linux 4.20 or later, CONFIG_PSI=y, and a kernel not booted with\npsi=0. The kubelet surfaces the data through the\nSummary API and\n/metrics/cadvisor.\n\n\n\nWhen migrating, update software that reads the cgroup filesystem directly. The\nmigration guidance recommends\ncAdvisor v0.43.0 or later and lists compatible Java, Node.js, and automaxprocs versions.\n\nCPU weight conversion in newer OCI runtimes\n\ncgroup v1 uses cpu.shares, whereas cgroup v2 uses cpu.weight. Newer OCI runtimes use an improved\nnon-linear conversion that preserves the default priority and gives small CPU requests more usable\ngranularity. The change is implemented in the OCI runtime rather than Kubernetes: it is available\nin crun v1.23 and runc v1.3.2. After upgrading a runtime, monitoring or policy tools that predict\nexact cpu.weight values may need updates. Read\nNew Conversion from cgroup v1 CPU Shares to v2 CPU Weight\nfor the formula, examples, and compatibility considerations.\n\nIn-place resource updates\n\nIn-place Pod vertical scaling\ngraduated to stable in Kubernetes v1.35. Kubernetes v1.36 then enabled\nin-place vertical scaling for Pod-level resources\nby default, as a Beta feature. The kubelet coordinates changes between the Pod-level and container\ncgroups so that increases create headroom before container limits grow, while decreases constrain\ncontainers before shrinking the Pod-level boundary. Accurate aggregate enforcement for this\nv1.36 feature requires cgroup v2.\n\n（节选）\n\n\n\n原文：Kubernetes Blog｜The Shift to cgroup v2 in Kubernetes: What You Need to Know，2026-10-07","url":"https://www.angryecho.com/c/DevOps/p/P2TBBk0tWIPQGoaNuNiGy","author":{"@type":"Person","name":"prng2021","url":"https://www.angryecho.com/u/H8Sprng2021"},"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/DislikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":0}]}]}
```

## Sitemap

See the full [sitemap](https://www.angryecho.com/sitemap.md) for all pages.
