--- layout: blog title: "Kubernetes 1.25: cgroup v2 升级到 GA" date: 2022-08-31 slug: cgroupv2-ga-1-25 --- **作者**: David Porter (Google), Mrunal Patel (Red Hat) Kubernetes 1.25 将 cgroup v2 正式发布(GA), 让 [kubelet](/zh-cn/docs/concepts/overview/components/#kubelet) 使用最新的容器资源管理能力。 ## 什么是 cgroup? 有效的[资源管理](/zh-cn/docs/concepts/configuration/manage-resources-containers/)是 Kubernetes 的一个关键方面。 这涉及管理节点中的有限资源,例如 CPU、内存和存储。 **cgroups** 是一种可建立资源管理功能的 Linux 内核能力, 例如为正在运行的进程限制 CPU 使用率或设置内存限制。 当你使用 Kubernetes 中的资源管理能力时,例如配置 [Pod 和容器的请求和限制](/zh-cn/docs/concepts/configuration/manage-resources-containers/#requests-and-limits), Kubernetes 会使用 cgroups 来强制执行你的资源请求和限制。 Linux 内核提供了两个版本的 cgroup:cgroup v1 和 cgroup v2。 ## 什么是 cgroup v2? cgroup v2 是 Linux cgroup API 的最新版本, 提供了一个具有增强的资源管理能力的统一控制系统。 自 2016 年以来,cgroup v2 一直在 Linux 内核中进行开发, 近年来在整个容器生态系统中已经成熟。在 Kubernetes 1.25 中, 对 cgroup v2 的支持已升级为正式发布。 默认情况下,许多最新版本的 Linux 发行版已切换到 cgroup v2, 因此 Kubernetes 继续在这些新更新的发行版上正常运行非常重要。 cgroup v2 对 cgroup v1 进行了多项改进,例如: * API 中单个统一的层次结构设计 * 为容器提供更安全的子树委派能力 * [压力阻塞信息](https://www.kernel.org/doc/html/latest/accounting/psi.html)等新功能 * 增强的资源分配管理和跨多个资源的隔离 * 统一核算不同类型的内存分配(网络和内核内存等) * 考虑非即时资源更改,例如页面缓存回写 一些 Kubernetes 特性专门使用 cgroup v2 来增强资源管理和隔离。 例如,[MemoryQoS 特性](/blog/2021/11/26/qos-memory-resources/)提高了内存利用率并依赖 cgroup v2 功能来启用它。kubelet 中的新资源管理特性也将利用新的 cgroup v2 特性向前发展。 ## 如何使用 cgroup v2? 许多 Linux 发行版默认切换到 cgroup v2; 你可能会在下次更新控制平面和节点的 Linux 版本时开始使用它! 推荐使用默认使用 cgroup v2 的 Linux 发行版。 一些使用 cgroup v2 的流行 Linux 发行版包括: * Container-Optimized OS(从 M97 开始) * Ubuntu(从 21.10 开始,推荐 22.04+) * Debian GNU/Linux(从 Debian 11 Bullseye 开始) * Fedora(从 31 开始) * Arch Linux(从 2021 年 4 月开始) * RHEL 和类似 RHEL 的发行版(从 9 开始) 要检查你的发行版是否默认使用 cgroup v2, 请参阅你的发行版文档或遵循[识别 Linux 节点上的 cgroup 版本](/zh-cn/docs/concepts/architecture/cgroups/#check-cgroup-version)。 如果你使用的是托管 Kubernetes 产品,请咨询你的提供商以确定他们如何采用 cgroup v2, 以及你是否需要采取行动。 要将 cgroup v2 与 Kubernetes 一起使用,必须满足以下要求: * 你的 Linux 发行版在内核版本 5.8 或更高版本上启用 cgroup v2 * 你的容器运行时支持 cgroup v2。例如: * [containerd](https://containerd.io/) v1.4 或更高版本 * [cri-o](https://cri-o.io/) v1.20 或更高版本 * kubelet 和容器运行时配置为使用 [systemd cgroup 驱动程序](/zh-cn/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver) kubelet 和容器运行时使用 [cgroup 驱动](/zh-cn/docs/setup/production-environment/container-runtimes#cgroup-drivers) 来设置 cgroup 参数。使用 cgroup v2 时,强烈建议 kubelet 和你的容器运行时都使用 [systemd cgroup 驱动程序](/zh-cn/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver), 以便系统上只有一个 cgroup 管理员。要配置 kubelet 和容器运行时以使用该驱动程序, 请参阅 [systemd cgroup 驱动程序文档](/zh-cn/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver)。 ## 迁移到 cgroup v2 当你使用启用 cgroup v2 的 Linux 发行版运行 Kubernetes 时,只要你满足要求, kubelet 应该会自动适应而无需任何额外的配置。 在大多数情况下,除非你的用户直接访问 cgroup 文件系统, 否则当你切换到使用 cgroup v2 时,不会感知到用户体验有什么不同。 如果你在节点上或从容器内直接访问 cgroup 文件系统的应用程序, 你必须更新应用程序以使用 cgroup v2 API 而不是 cgroup v1 API。 你可能需要更新到 cgroup v2 的场景包括: * 如果你运行依赖于 cgroup 文件系统的第三方监控和安全代理,请将代理更新到支持 cgroup v2 的版本。 * 如果你将 [cAdvisor](https://github.com/google/cadvisor) 作为独立的 DaemonSet 运行以监控 Pod 和容器, 请将其更新到 v0.43.0 或更高版本。 * 如果你使用 JDK 部署 Java 应用程序,首选使用[完全支持 cgroup v2](https://bugs.openjdk.org/browse/JDK-8230305) 的 JDK 11.0.16 及更高版本或 JDK 15 及更高版本。 ## 进一步了解 * 阅读 [Kubernetes cgroup v2 文档](/zh-cn/docs/concepts/architecture/cgroups/) * 阅读增强提案 [KEP 2254](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2254-cgroup-v2/README.md) * 学习更多关于 Linux 手册页上的 [cgroups](https://man7.org/linux/man-pages/man7/cgroups.7.html) 和 Linux 内核文档上的 [cgroup v2](https://docs.kernel.org/admin-guide/cgroup-v2.html) ## 参与其中 随时欢迎你的反馈!SIG Node 定期开会,可在 Kubernetes [Slack](https://slack.k8s.io/)的 `#sig-node` 频道中获得,或使用 SIG [邮件列表](https://github.com/kubernetes/community/tree/master/sig-node#contact)。 cgroup v2 经历了漫长的旅程,是整个行业开源社区协作的一个很好的例子, 因为它需要跨堆栈的工作,从 Linux 内核到 systemd 到各种容器运行时,当然还有 Kubernetes。 ## 致谢 我们要感谢 [Giuseppe Scrivano](https://github.com/giuseppe) 在 Kubernetes 中发起对 cgroup v2 的支持, 还要感谢 SIG Node 社区主席 [Dawn Chen](https://github.com/dchen1107) 和 [Derek Carr](https://github.com/derekwaynecarr) 所作的审查和领导工作。 我们还要感谢 Docker、containerd 和 CRI-O 等容器运行时的维护者, 以及支持多种容器运行时的 [cAdvisor](https://github.com/google/cadvisor) 和 [runc, libcontainer](https://github.com/opencontainers/runc) 等组件的维护者。 最后,如果没有 systemd 和上游 Linux 内核维护者的支持,这将是不可能的。