欢迎加入本站的kubernetes技术交流群,微信添加:加Blue_L。
cgroup有v1和v2版本,系统上对cgroupfs的挂载支持三种不同的模式:
- 统一(Unified) — 最简单的方式,只暴露纯粹的cgroup v2接口。在该模式下,
/sys/fs/cgroup
是唯一挂载到主机上的文件系统,所有的控制器都通过它暴露。 - 兼容(Legacy) — 传统的cgroup v1模式,该模式下不同的控制器拥有自己挂载目录:
/sys/fs/cgroup/<controller>/
。在此基础之上,systemd拥有自己的cgroup层级来实现管理功能:/sys/fs/cgroup/systemd/
。 - 混合(Hybrid) — 这是上面两种模式的结合形式。这种模式和兼容模式非常相似,但是会多挂载一个层级目录
/sys/fs/cgroup/unified/
,该目录下包含cgoup v2的接口(但是该目录下只是暴露cgroupfs层级树,不包含控制器功能,控制器都挂载到了兼容模式的单独目录下,/sys/fs/cgroup/unified/
仅仅是纯粹的cgroupfs的v2的功能能力,无关资源管控)。在此种模式下,既能够兼容cgroup v1的功能,又能使用一些cgroup v2的特性。
对于不同的操作系统发行版,或者相同发行版的不同版本,挂载模式可能都不一样,因此要使用cgroup功能,需要使用者(如runc,新版jvm)能够检测当前的系统上使用的是何种模式,对于检测何种模式可以使用下列简单的方式: 在根命名空间中,可以使用statfs()
获取/sys/fs/cgroup/
这个文件系统的类型,如果.f_type
是 CGROUP2_SUPER_MAGIC
,则说明是统一模式。如果.f_type
是TMPFS_MAGIC
,则可能是cgroup v1模式或者可能是混合模式,更进一步检查可通过statfs()
获取/sys/fs/cgroup/unified/
的文件系统类型,如果它的.f_type
是CGROUP2_SUPER_MAGIC
,则说明使用的是混合模式,否则就是cgroup v1模式。
下面是containerd中的实现:
// github.com/containerd/cgroups/utils.go
// Mode returns the cgroups mode running on the host
func Mode() CGMode {
checkMode.Do(func() {
var st unix.Statfs_t
if err := unix.Statfs(unifiedMountpoint, &st); err != nil {
cgMode = Unavailable
return
}
switch st.Type {
case unix.CGROUP2_SUPER_MAGIC:
cgMode = Unified
default:
cgMode = Legacy
if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil {
return
}
if st.Type == unix.CGROUP2_SUPER_MAGIC {
cgMode = Hybrid
}
}
})
return cgMode
}