在Linux上,控制组(control groups)限制了分配给进程的资源。

kubelet和底层容器运行时需要与控制组(cgroups)进行接口交互,以实施对Pod和容器的资源管理,包括为容器化工作负载设置CPU和内存的请求和限制。

Linux中存在两个版本的控制组:cgroup v1和cgroup v2。cgroup v2是cgroup API的新一代版本。

cgroup v1是最早版本的控制组API,它提供了一种层次化的组织结构来管理进程组的资源。
它通过在/proc目录下创建一系列的虚拟文件和目录来实现资源隔离和限制。这些文件和目录包含了诸如cpu、memory、io等资源的配置和统计信息。

cgroup v2是对cgroup v1的重大改进和扩展。它提供了更灵活的资源控制机制和更强大的层次结构管理。cgroup v2通过在/sys/fs/cgroup目录下使用文件系统来组织和管理控制组。它提供了以层次结构方式组织控制组的能力,并支持更细粒度的资源控制和配置

与cgroup v1相比,cgroup v2提供了更多的功能和灵活性,包括更细粒度的资源控制、更丰富的统计信息、更强大的层次管理等。由于其改进和扩展的特性,cgroup v2被视为当前和未来的控制组解决方案。

什么是cgroup v2

cgroup v2是Linux cgroup API的下一个版本。cgroup v2提供了一个统一的控制系统,具有增强的资源管理能力。

与cgroup v1相比,cgroup v2具有以下几个改进:

  • 单一统一的层次结构设计
  • 更安全的子树委派给容器
  • 支持新特性,如Pressure Stall Information(压力停顿信息)
  • 提供跨多个资源的增强资源分配管理和隔离
  • 对不同类型的内存分配(网络内存、内核内存等)进行统一的记账
  • 记账非即时资源变化,例如页面缓存写回

某些Kubernetes特性专门使用cgroup v2来增强资源管理和隔离。例如,MemoryQoS特性改进了内存的QoS,并依赖于cgroup v2的基本功能。

总而言之,cgroup v2是Linux cgroup API的下一代版本,它提供了统一的控制系统和增强的资源管理功能。这些功能的改进包括设计上的改进、资源隔离和分配的增强以及支持更多类型和特性的记账。在Kubernetes中,一些特性依赖于cgroup v2以实现增强的资源管理和隔离。

“Identify cgroup version on Linux nodes” 这句话的意思是要确定Linux节点上使用的是哪个版本的cgroup(控制组)。

cgroup是Linux内核提供的一种资源管理机制,它可以用来限制和分配系统资源,如CPU、内存、磁盘等。cgroup v2 是 cgroup 的第二个版本,在功能上有一些改进和增强。

使用cgroup v2

要确定你的Linux发行版是否使用cgroup v2,默认方法是查看系统中的相关配置文件。不同发行版可能有不同的配置文件路径,一般来说,你可以尝试查找以下文件:

  • /proc/cgroups
  • /sys/fs/cgroup/unified/cgroup.controllers

这些文件会显示系统中使用的cgroup版本信息。如果这些文件存在,并且显示的是cgroup v2 的相关信息,那么你的系统就使用的是cgroup v2。

另外,建议你使用默认启用和使用cgroup v2 的Linux发行版,以获得更好的支持和兼容性。

kubelet和容器运行时配置为使用systemd cgroup驱动程序

在使用cgroup v2时,要确保kubelet和容器运行时(如Docker、containerd、cri-o等)都配置为使用systemd cgroup驱动程序。

systemd cgroup驱动程序

systemd cgroup驱动程序是一种与systemd集成的cgroup管理器
它可以使kubelet和容器运行时在管理cgroup资源时与系统的systemd服务进行协同。为了启用systemd cgroup驱动程序,你需要在kubelet和容器运行时的配置文件中进行相应的设置。

在kubelet的配置文件(一般位于/etc/kubernetes/目录下)中,你需要设置--cgroup-driver=systemd来配置kubelet使用systemd cgroup驱动程序。

在容器运行时的配置文件中,具体设置的方法可能会因不同的容器运行时而有所不同。以Docker为例,在Docker的配置文件(一般位于/etc/docker/目录下)中,你需要设置--exec-opt native.cgroupdriver=systemd来配置Docker使用systemd cgroup驱动程序。

确保kubelet和容器运行时都通过上述配置使用了systemd cgroup驱动程序,可以确保它们在使用cgroup v2时能够正确地与系统的cgroup资源管理进行交互。

支持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及类似的发行版(自9版本开始)

要确定你的发行版是否使用cgroup v2,你可以参考该发行版的文档或按照”Identify the cgroup version on Linux nodes”中的说明进行检查。

你也可以通过手动修改内核的cmdline引导参数来启用cgroup v2。如果你的发行版使用GRUB引导器,可以在/etc/default/grub文件中的GRUB_CMDLINE_LINUX行中添加systemd.unified_cgroup_hierarchy=1,然后运行sudo update-grub命令。不过,推荐的做法是使用已经默认启用cgroup v2的发行版。

迁移到cgroup v2

要迁移到cgroup v2,需要确保满足以下要求,然后升级到默认启用cgroup v2的内核版本。

kubelet会自动检测操作系统是否正在运行cgroup v2,并根据情况进行相应的操作,无需额外配置。

除非用户直接访问cgroup文件系统(无论是在节点还是容器内部),否则在切换到cgroup v2时不应该有任何明显的用户体验差异。

cgroup v2使用与cgroup v1不同的API,因此如果有任何直接访问cgroup文件系统的应用程序,它们需要更新到支持cgroup v2的新版本。

识别Linux节点上的cgroup版本

cgroup版本取决于使用的Linux发行版和操作系统上配置的默认cgroup版本。要检查你的发行版使用的cgroup版本,可以在节点上运行以下命令:stat -fc %T /sys/fs/cgroup/

  • 如果输出是cgroup2fs,则表示使用的是cgroup v2。
  • 如果输出是tmpfs,则表示使用的是cgroup v1。
    官网地址