cgroup v1 与 cgroup v2
被弃用的核心功能
cgroup v2 和 cgroup v1 有很大的不同,我们一起来看看在 cgroup v2 中弃用了哪些 cgroup v1 的功能:
不支持包括命名层次在内的多个层次结构;
不支持所有 v1 安装选项;
“tasks” 文件被删除,“cgroup.procs” 没有排序
在 cgroup v1 中线程组 ID 的列表。不保证此列表已排序或没有重复的 TGID,如果需要此属性,用户空间应排序/统一列表。将线程组 ID 写入此文件会将该组中的所有线程移动到此 cgroup 中;
cgroup.clone_children 被删除。clone_children 仅影响 cpuset controller。如果在 cgroup 中启用了 clone_children (设置:1),新的 cpuset cgroup 将在初始化期间从父节点的 cgroup 复制配置;
/proc/cgroups 对于 v2 没有意义。改用根目录下的“cgroup.controllers”文件;
cgroup v1 的问题
cgroup v2 和 v1 中最显著的不同就是 cgroup v1 允许任意数量的层次结构, 但这会带来一些问题的。我们来详细聊聊。
挂载 cgroup 层次结构时,你可以指定要挂载的子系统的逗号分隔列表作为文件系统挂载选项。默认情况下,挂载 cgroup 文件系统会尝试挂载包含所有已注册子系统的层次结构。
如果已经存在具有完全相同子系统集的活动层次结构,它将被重新用于新安装。
如果现有层次结构不匹配,并且任何请求的子系统正在现有层次结构中使用,则挂载将失败并显示 -EBUSY。否则,将激活与请求的子系统相关联的新层次结构。
当前无法将新子系统绑定到活动 cgroup 层次结构,或从活动 cgroup 层次结构中取消绑定子系统。当 cgroup 文件系统被卸载时,如果在顶级 cgroup 之下创建了任何子 cgroup,即使卸载,该层次结构仍将保持活动状态;如果没有子 cgroup,则层次结构将被停用。
这就是 cgroup v1 中的问题,在 cgroup v2 中就很好的进行了解决。
cgroup 和容器的联系
这里我们以 Docker 为例。 创建一个容器,并对其可使用的 CPU 和内存进行限制:
docker run --rm -d --cpus=2 --memory=2g --name=2c2g redis:alpine
e420a97835d9692df5b90b47e7951bc3fad48269eb2c8b1fa782527e0ae91c8e
cat /sys/fs/cgroup/system.slice/docker-`docker ps -lq --no-trunc`.scope/cpu.max
200000 100000
cat /sys/fs/cgroup/system.slice/docker-`docker ps -lq --no-trunc`.scope/memory.max
2147483648
docker run --rm -d --cpus=0.5 --memory=0.5g --name=0.5c0.5g redis:alpine
8b82790fe0da9d00ab07aac7d6e4ef2f5871d5f3d7d06a5cdb56daaf9f5bc48e
cat /sys/fs/cgroup/system.slice/docker-`docker ps -lq --no-trunc`.scope/cpu.max
50000 100000
cat /sys/fs/cgroup/system.slice/docker-`docker ps -lq --no-trunc`.scope/memory.max
536870912
从上面的示例可以看到,当我们使用 Docker 创建出新的容器并且为他指定 CPU 和 内存限制后,其对应的 cgroup 配置文件的 cpu.max 和 memory.max都设置成了相应的值。
如果你想要对一些已经在运行的容器进行资源配额的检查的话,也可以直接去查看其对应的配置文件中的内容。