实验环境 ubuntu 18.10
操作系统已经默认把各种controller都挂载到/sys/fs/cgroup/目录下了。
ls /sys/fs/cgroup/ 可以查看有哪些controller
mount |grep cgroup 可以查看挂载信息 (可以看到有一个是cgroup2,其它都是cgroup1,显示为cgroup)
1、先写一个占用内存的普通程序。
手工运行这个程序,用top -p pid可以看到这个程序最终使用1000MB内存(34%)
package main
import "time"
import "os"
func main() {
println(os.Getpid())
s := "1234567890"
for i := 0; i < 26; i++ {
s = s + s
println("gaofeng:", len(s)/1000/1000)
time.Sleep(1 * time.Second)
}
time.Sleep(30 * time.Second)
}
2、写一个测试程序,调用上面的程序cmd2. 然后创建一个cgroup,名字为gfmemory。写入cmd2的pid到tasks文件,写入内存门限到 memory.limit_in_bytes 文件。
切换到root用户,执行这个测试程序。通过top -p pid可以看到cmd2的内存被限制在100MB左右。(3.3%)
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strconv"
// "syscall"
)
// UTS Namespace 主要用来隔离 nodename 和 domainname 两个系统标识。在 UTS Namespace
// 里面 , 每个 Namespace 允许有自己的 hostname 。
// IPC Namespace 用来隔离 System V IPC 和 POSIX message queues 。ipcs -q ; ipcmk -Q ; ipcrm -q 0
// PID Namespace 是用来隔离进程 ID 的 。
// Mount Namespace 用来隔 离各个进程看到 的挂载点视图。
func main() {
cmd := exec.Command("/home/gaofeng/goworkspace/project1/src/cmd2/cmd2")
// cmd.SysProcAttr = &syscall.SysProcAttr{
// Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER | syscall.CLONE_NEWNET,
// }
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if merr := cmd.Start(); merr != nil {
log.Fatal(merr)
}
path := "/sys/fs/cgroup/memory/gfmemory"
println(path)
if err := os.Mkdir(path, 0755); err != nil {
fmt.Println(err)
}
println("write tasks:", cmd.Process.Pid)
ioutil.WriteFile(path+"/tasks", []byte(strconv.Itoa(cmd.Process.Pid)), 0644)
ioutil.WriteFile(path+"/memory.limit_in_bytes", []byte("100m"), 0644)
cmd.Process.Wait()
}