Linux内核提供了两个版本即cgroup v1和cgroup v2
cgroup是Linux内核提供的一种机制,用于限制、记录和隔离进程组的资源使用。它可以控制CPU、内存、IO等系统资源的分配和使用,并且支持动态调整资源限制。
使用cgroup技术可以实现多个应用程序之间的资源隔离和保护,从而避免应用程序之间的互相影响和冲突。同时,cgroup还可以用于限制系统服务的资源使用,以避免某个服务占用过多资源导致系统负载过高或崩溃。
cgroup技术被广泛应用于容器化技术中,如Docker、Kubernetes等,以帮助用户更好地管理和控制容器的资源使用,提高容器的性能和可靠性。当您使用 Kubernetes 中的资源管理功能(例如为 Pod和容器配置requests和limits)时,Kubernetes 使用 cgroups 来强制执行您的资源请求和限制。
cgroup v2是Linux内核提供的一种新版本的cgroup机制,相对于cgroup v1来说有一些重要的改进和优化。与cgroup v1不同,cgroup v2提供了更加灵活的层次结构,可以将多个cgroup嵌套在一个父cgroup中,从而更好地组织和管理资源。同时,cgroup v2也支持更多类型的资源控制,如CPU集合、内存压缩等。
另外,cgroup v2也引入了统一的hierarchy概念,使得cgroup的管理更加简单和统一。此外,cgroup v2还通过文件系统接口,提供了更加易用和直观的命令行工具,方便用户进行资源限制和查询。
cgroup v2 对 cgroup v1 进行了多项改进,例如:
API 中单个统一的层次结构设计
更安全的子树委派给容器
更新的功能特性, 例如压力阻塞信息(Pressure Stall Information,PSI)
跨多个资源的增强资源分配管理和隔离
统一核算不同类型的内存分配(网络内存、内核内存等)
考虑非即时资源变化,例如页面缓存回写
与v1不同,cgroup v2只有单个层级树(single hierarchy)。总之,cgroup v2相对于cgroup v1来说,在性能、可靠性、功能和易用性等方面都有所提高,因此正在逐渐成为Linux内核中的主流cgroup机制。
虽然cgroup v2早已在linux 4.5版本的时候就已经加入内核中了,而centos 8默认也已经用了4.18作为其内核版本,但是系统中仍然默认使用的是cgroup v1。
从Debian 11、Ubuntu 22.04 LTS、Red Hat 9、CentOS 9 stream开始,默认启用cgroups v2。
如果想分辨当前使用的 Linux 操作系统使用的是哪个版本的 cgroups 也很简单,只需要检查 /sys/fs/cgroup 路径下的结构即可。
cgroup v1版本下 /sys/fs/cgroup目录结构如下:
cgroup v2版本下 /sys/fs/cgroup目录结构如下:
在linux 4.5版本中cgroup v2已经作为新特性加入到了内核代码,用户升级系统内核后,可以通过以下命令查看是否支持cgroup v2能力,目前我使用的不支持cgroup v2,所以还需要先升级内核
grep cgroup /proc/filesystems nodev cgroup
如果在K8s集群上启用cgroup v2需要检查Linux内核版本是否为5.8或者更高版本
uname -r 3.10.0-1160.el7.x86_64
除了上述的一些条件要求,如果使用的容器还需要满足以下要求
system 226 和更高版本 containerd v1.4 和更高版本 cri-o v1.20 和更高版本 kubernetes 1.23.0 和更高版本(1.24会有警告,但无影响,建议最低使用1.25版本)
官方文档建议:将cgroupDriver配置为systemd,这样将kubelet可以通过system在 cgroup 的 v1 和 v2 版本之间进行自适应。因此对 kubernetes/cri-runtime 进行 cgroup v2 适配,实际上是将 systemd 从默认的 cgroup v1 切换到 cgroup v2。
后面我们再来介绍下如何切换到cgroup v2。
首先我们升级systemd,注意centos7需要关闭selinux,同时还需要注意升级systemd网卡名会变。
sed -i 's/enforcing/disabled/' /etc/selinux/config setenforce 0 systemctl --version systemd 219 +PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN
下载Facebook维护的第三方yum仓库
wget https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/repo/epel-7/jsynacek-systemd-backports-for-centos-7-epel-7.repo -O /etc/yum.repos.d/jsynacek-systemd-centos-7.repo --no-check-certificate yum update systemd
升级 systemd 后,再次验证systemd版本
systemctl --version systemd 234 +PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN default-hierarchy=hybrid
可以看到已经是234版本了,然后还需要重新升级当前的内核版本,然后启用新版本的 systemd,升级内核可以参考我的这个笔记:https://sulao.cn/post/949.html
升级完内核接着我们启用cgroup2 ,在/etc/default/grub下的GRUB_CMDLINE_LINUX中添加systemd.unified_cgroup_hierarchy=1
GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet systemd.unified_cgroup_hierarchy=1" GRUB_DISABLE_RECOVERY="true"
运行 grub2-mkconfig 命令来重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg
内核升级完以后,我们重启完系统再次检测系统的systemd版本是否切换到了更新的234版本
dmesg | grep 'running in system mode' [ 0.868297] systemd[1]: systemd 234 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBID +ELFUTILS +KMOD -IDN2 +IDN default-hierarchy=hybrid)
检查是否启用cgroup2
stat -fc %T /sys/fs/cgroup/ cgroup2fs
上述命令返回cgroup2fs,说明已经成功切换到cgroup v2了。