CGROUPS VERSION 2
之前写过一篇文章对cgroup v1进行了介绍,但是由于当前k8s使用cephfs进行数据存储,当多租户使用时,需要对IO进行限制,当前cgroup v1
由于memcg与blkio没有协作,导致buffer io的throttle一直没有实现。并且cgroup v1
在内核的实现一直比较混乱,其中主要的原因在于,cgroup为了提供灵活性,允许进程可以属于多个hierarchy
的不同的group。但实际上,多个hierarchy
并没有太大的用处,因为控制器(controller)只能属于一个hierarchy
。 所以在实际使用中,通常是每个hierarchy
一个控制器。
这种多hierarchy
除了增加代码的复杂度和理解困难外,并没有太大的用处。一方面,跟踪进程所有controller变得复杂;另外,各个controller之间也很难协同工作(因为controller可能属于不同的hierarchy, 所以从3.16开始,内核开始转向单一层次(unified hierarchy)。并且实现了对buffer io的限制。
注意:(cgroup v2在kernel 4.5版本已经release)
关于更多关于cgroup v2的背景:https://lwn.net/Articles/679786/
Cgroups v2 介绍
由于cgroup v1存在的种种问题,cgroup v2将多hierarchy
的方式变成了unified hierarchy
。并将所有的controller挂载到一个unified hierarchy
。并且当前kernel没有移除从GROUP v1版本,允许cgroup v1和v2两个版本共存。但是相同的controller不能同时mount到这两个不同的cgroup版本中。
对cgroup v2的变化,总结如下:
- cgroup v2 中所有的controller都会被挂载到一个
unified hierarchy
下,不在存在像v1中允许不同的controller挂载到不同的hierarchy
的情况。 - Proess只能绑定到cgroup的根(“/“)目录和cgroup目录树中的叶子节点。
- 通过
cgroup.controllers
和cgroup.subtree_control
指定哪些controller可以被使用。 - v1版本中的
task
文件和cpuset controller中的cgroup.clone_children
文件被移除。 - 当cgroup为空时的通知机制得到改进,通过
cgroup.events
文件通知。
更多关于cgroup v2的介绍请查看文档cgroup v2
Cgroups v2 unified hierarchy
在cgroup v1允许将不同的controller挂载到不同的hierarchies
,这种方式很灵活,但是实际上这种方式基本对于使用者来说是没有必要的。因此, 在cgroup v2版本中,将所有的controller都挂载到一个hierarchies
。
使用下面命令将cgroup v2挂载到文件系统,并且所有可用的controller会自动被挂载进去。
1 | mount -t cgroup2 none $MOUNT_POINT |
cgroup v2可以使用的controller必须没有被cgroup v1使用。如果想在cgroup v2使用已经被cgroup v1使用的controller,则需要将cgroup v1已经挂载的controller umount掉之后,才能在v2中使用。
还有值得关注的是,系统boot时,systemd默认使用cgroup v1,并将可以使用的controller mount到/sys/fs/cgroup
。如果想在系统boot时,把cgroup v1关掉,可以在/etc/default/grub
文件下修改kernel参数,增加GRUB_CMDLINE_LINUX_DEFAULT="cgroup_no_v1=all"
。(注意: all表示关闭所有的controller,如果想关闭指定的controller,则将all替换成你需要的controller名称,并已逗号分隔即可)。这样就可以在cgroup v2中使用你想要的controller了。
Cgroups v2 controllers
当前cgroup v2支持的controller:
- io (since Linux 4.5)
- memory (since Linux 4.5)
- pids (since Linux 4.5)
- perf_event (since Linux 4.11)
- rdma (since Linux 4.11)
- cpu (since Linux 4.15)
Cgroups v2 subtree control
在hierarchy
下的每一个group中逗都会包含如下两个文件:
cgroup.controllers
这是一个read-only文件。包含了该cgroup下所有可用的controllers.
cgroup.subtree_control
这个文件中包含了该cgroup下已经被开启的controllers。 并且
cgroup.subtree_control
中包含的controllers是cgroup.controllers
文件controller的子集。
cgroup.subtree_control文件内容格式如下,controller之间使用空格间隔,前面用”+”表示启用,使用”-“表示停用。比如下面的例子:
1 | echo '+pids -memory' > x/y/cgroup.subtree_control |
cgroup v2的具体组织结构如下图所示:
Cgroups v2 “no internal processes” rule
与cgrop v1不同, cgroup v2只能attach process到叶子节点。因此你不能attach process到任何一个已开启controller的任何subgroup中。这么做原因是:
1 | The reason behind this rule is that processes in a given subgroup competing for resources with threads attached to its parent group create significant implementation difficulties. |
Cgroups v2 cgroup.events file
在cgroup v2的实现中,也对获取group empty时获取通知的机制进行了优化。
cgroup v1使用release_agent
和notify_on_release
在v2中被移除。替代的是使用了cgroup.events
文件。这是一个只读的文件,每行一个key value对,key和value之间通过空格分割。
当前在这个文件中只含有一个key就是populated对应的value是0. 0表示cgroup中没有process。1表示cgroup中包含process。
Cgroups v2 cgroup.stat file
在cgroup v2 hierarchy下的每个group都会包含一个只读文件cgroup.stat
。它的内容也是key-value
的形式。当前这个文件中包含如下两个key;
nr_descendants
表示cgroup中存活的subgroup的数量
nr_dying_descendants
表示cgroup中已经死亡的cgroup的数量
Limiting the number of descendant cgroups
在cgroup v2 hierarchy还包含了两个用于查看和设置该cgroup下的后代cgroup数量的限制文件:
cgroup.max.depth (since Linux 4.14)
这个文件定义子cgroup的最大深度。
0
意味着不能创建cgroup. 如果尝试创建cgroup,会报EAGAIN
错误max
表示没有限制,默认值是max
。cgroup.max.descendants (since Linux 4.14)
当前可以创建的活跃cgroup目录的最大数量,默认值”max”表示不限制。超过限制,返回EAGAIN。
CGROUPS VERSION 2 THREAD MODE
请参考:http://man7.org/linux/man-pages/man7/cgroups.7.html
当前存在的问题
当前docker只支持cgroup v1,由于种种原因导致社区一直没有对cgroup v2版本的支持,详细内容请看:
https://github.com/opencontainers/runc/issues/654
比较好的资料
http://man7.org/linux/man-pages/man7/cgroups.7.html
https://facebookmicrosites.github.io/cgroup2/docs/create-cgroups.html
https://events.static.linuxfound.org/sites/events/files/slides/cgroup_and_namespaces.pdf
https://lwn.net/Articles/679786/
https://www.lijiaocn.com/%E6%8A%80%E5%B7%A7/2019/01/28/linux-tool-cgroup-detail.html
Happy Children’s Day, hahahaha :)