使用cgroup控制资源的时候,为什么不可以使用挂载的文件系统内部的/sys/fs/cgroup/pids

yagamil · 2022-01-07 01:01:37 · 746 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2022-01-07 01:01:37 的主题,其中的信息可能已经有所发展或是发生改变。

如题,主机是centos 目录结构如下:

-rw-r--r-- 1 root root 1.8K Jan 7 00:54 cgroupDemo.go -rwxr-xr-x 1 root root 2.2M Jan 6 16:19 dockers -rw-r--r-- 1 root root 58 Jan 6 13:31 Makefile drwxr-xr-x 21 root root 4.0K Jan 6 15:17 ubuntu-fs

ubuntu-fs是代码里面挂载的文件系统。 如果在挂载前就做cgroup的相关文件写入,实际是写入到宿主机里面的,也就是centos的/sys/fs/cgroup 里面的。 这样可以起到限制资源的作用

而把cgroup相关文件写入映射的ubuntu-fs,却不能生效。

代码如下:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "os/exec"
    "path/filepath"
    "strconv"
    "syscall"
)

func main() {
    log.SetOutput(os.Stdout)
    log.SetFlags(log.Ltime)
    defer log.Println("End of main\n")

    if len(os.Args) <= 1 {
        panic("not enough argument")
    }

    switch os.Args[1] {
    case "run":
        run()
    case "child":
        child()
    default:
        panic("argument error")
    }
}

func must(err error) {
    if err != nil {
        panic("argument error")
    }
}

func cgroup() {
    fmt.Println("in cgroup")
    cgpath := "/sys/fs/cgroup"
    pids := filepath.Join(cgpath, "pids")
    if _, err := os.Stat(filepath.Join(pids, "container")); os.IsNotExist(err) {

        must(os.Mkdir(filepath.Join(pids, "container"), 0700))
    }
    must(ioutil.WriteFile(filepath.Join(pids, "container/pids.max"), []byte("20"), 0700))
    must(ioutil.WriteFile(filepath.Join(pids, "container/notify_on_release"), []byte("1"), 0700))
    must(ioutil.WriteFile(filepath.Join(pids, "container/cgroup.procs"), []byte(strconv.Itoa(os.Getpid())), 0700))

}

func run() {

    fmt.Printf("Run pid:%d\n", os.Getpid())
    args := append([]string{"child"}, os.Args[2:]...)
    cmd := exec.Command("/proc/self/exe", args...)

    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID |
            syscall.CLONE_NEWNS,
        Unshareflags: syscall.CLONE_NEWNS,
    }
    must(cmd.Run())
}

func child() {
    fmt.Printf("child pid: %d\n", os.Getpid())
    must(syscall.Sethostname([]byte("contains")))
    must(syscall.Chroot("./ubuntu-fs"))
    must(syscall.Chdir("/"))
    must(syscall.Mount("proc", "proc", "proc", 0, ""))

    cgroup()
    cmd := exec.Command(os.Args[2], os.Args[3:]...)

    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    must(cmd.Run())
    must(syscall.Unmount("/proc", 0))
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

746 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传