cgroup模式检测

欢迎加入本站的kubernetes技术交流群,微信添加:加Blue_L。


cgroup有v1和v2版本,系统上对cgroupfs的挂载支持三种不同的模式:

  1. 统一(Unified) — 最简单的方式,只暴露纯粹的cgroup v2接口。在该模式下,/sys/fs/cgroup 是唯一挂载到主机上的文件系统,所有的控制器都通过它暴露。
  2. 兼容(Legacy) — 传统的cgroup v1模式,该模式下不同的控制器拥有自己挂载目录:/sys/fs/cgroup/<controller>/。在此基础之上,systemd拥有自己的cgroup层级来实现管理功能:/sys/fs/cgroup/systemd/
  3. 混合(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_typeCGROUP2_SUPER_MAGIC,则说明是统一模式。如果.f_typeTMPFS_MAGIC ,则可能是cgroup v1模式或者可能是混合模式,更进一步检查可通过statfs()获取/sys/fs/cgroup/unified/的文件系统类型,如果它的.f_typeCGROUP2_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
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注