如何修改Golang容器代码的cg()函数适配Cgroups V2?
适配Cgroups V2修改
cg()函数的解决方案 问题背景
我正在跟随某教程构建简易容器,教程中使用Cgroups V1实现控制组,但我的Ubuntu 24.04系统采用Cgroups V2(cgroup2fs)。我已了解Cgroups V2的工作机制,但难以将教程中的实现进行适配。Cgroups V1与V2的核心差异在于文件结构变化和限制设置方式不同,但我不确定如何在此场景中应用这些差异。请问如何修改cg()函数以适配Cgroups V2?
当前针对Cgroups V1的cg()函数代码:
func cg() { cgroups := "/sys/fs/cgroup/" pids := filepath.Join(cgroups, "pids") os.Mkdir(filepath.Join(pids, "liz"), 0755) must(ioutil.WriteFile(filepath.Join(pids, "liz/pids.max"), []byte("20"), 0700)) // Removes the new cgroup in place after the container exits must(ioutil.WriteFile(filepath.Join(pids, "liz/notify_on_release"), []byte("1"), 0700)) must(ioutil.WriteFile(filepath.Join(pids, "liz/cgroup.procs"), []byte(strconv.Itoa(os.Getpid())), 0700)) }
适配Cgroups V2的修改方案
Cgroups V2采用单层级统一结构,无需按控制器(如pids)拆分目录,所有控制参数直接在目标cgroup目录下配置。以下是修改后的cg()函数:
func cg() { // Cgroups V2的根目录,Ubuntu 24.04默认挂载点为/sys/fs/cgroup cgroupRoot := "/sys/fs/cgroup" // 自定义cgroup路径 cgroupPath := filepath.Join(cgroupRoot, "liz") // 创建cgroup目录,使用MkdirAll避免目录已存在的错误 must(os.MkdirAll(cgroupPath, 0755)) // 设置进程数量限制:最多20个进程 must(os.WriteFile(filepath.Join(cgroupPath, "pids.max"), []byte("20"), 0700)) // 启用容器退出后自动删除cgroup的机制 must(os.WriteFile(filepath.Join(cgroupPath, "notify_on_release"), []byte("1"), 0700)) // 将当前进程加入该cgroup must(os.WriteFile(filepath.Join(cgroupPath, "cgroup.procs"), []byte(strconv.Itoa(os.Getpid())), 0700)) }
关键差异说明
- 目录结构变化:Cgroups V1需要在
/sys/fs/cgroup/pids下创建子cgroup,而V2直接在根目录/sys/fs/cgroup下创建自定义cgroup,所有控制器参数都放在这个目录下。 - API兼容性:
pids.max、notify_on_release、cgroup.procs这些核心文件的功能在V2中保持一致,只是路径不再嵌套控制器子目录。 - 错误处理优化:使用
os.MkdirAll替代os.Mkdir,避免因cgroup目录已存在导致的 panic(比如重复运行容器时);同时用os.WriteFile替代ioutil.WriteFile,后者在Go 1.16+已被标记为废弃。
另外,Ubuntu 24.04默认已启用Cgroups V2,无需额外配置挂载点。若需验证系统是否使用V2,可执行mount | grep cgroup2查看挂载信息。
内容的提问来源于stack exchange,提问作者MnglaGesh
相关产品推荐
相关产品推荐

