(2)Cgroups
7771 ワード
Cgroupsについて
前回のnamespaceは主に環境隔離について、このCgroupsは主に隔離環境を制限し、隔離された空間が互いに資源を奪うことを防止すると述べた.
Cgroupsもlinuxのカーネル技術であり、プロセスとそのサブプロセスのセットに対するリソース制限、制御、統計機能を提供しています.これらのリソースには、cpu、メモリ、ストレージ、ネットワークなどが含まれます.
Cgroupsの3つのコンポーネント、cgroup、subsystem、hierarchy.まずcgroupはプロセスパケット管理のメカニズムであり、1つのCgroupにはプロセスのセットが含まれており、このcgroupに対して様々なsubsystemパラメータを追加して、プロセスのセットとsubsystemのセットを関連付けることができます.次にsubsystemは、リソース管理制御のモジュールのセットです.(例えばblkioはブロックデバイスのIO制御を設定することができ、memoryはプロセスのメモリ占有を制御するために使用される...)最後にhierarchyは、Cgroupのセットを木状の構造に直列に接続する機能で、この構造Cgroupsによって継承することができます.
手動でkernelインタフェースを呼び出してCgroupsを感じます
1 hierarchy(Cgroupツリー)を作成してマウント
2ルートノードに2つのサブCgroupを拡張
Cgroupのディレクトリの下でファイルを作成すると、kernelはこのCgroupのサブCgroupとしてファイルをマークし、Cgroupのプロパティを継承することがわかります.
3 Cgroupに移動プロセスを追加する1つのプロセスCgroupsのhierarchyでは、1つのCgroupノードにのみ存在し、システムのすべてのプロセスはデフォルトでルートノードに存在し、移動したCgroupノードのtasksファイルにプロセスIDを書き込むことでそのCgroupノードに移動できます.
現在のプロセスがcgroup-1に移動していることがわかります.
4 subsystemでCgroupを制限するプロセスのリソース
制限100 Mを使用すると、100 M以上のプロセスが殺されることがわかります.
Cgroupsのdockerでの運用
02613 ec 46397 ee 46 a 6 a 9 bd 7 e 62 f 78 b 1 bd 89 f 15 f 07 b 898 f 3 c 8553 db 4243 b 5346 fはある容器IDである
Cgroupsによるコンテナリソースの制限をgo言語で実現
20%のメモリ(1 G*20%=100 M)が消費されていることがわかり、制限が成功したことを示しています.
前回のnamespaceは主に環境隔離について、このCgroupsは主に隔離環境を制限し、隔離された空間が互いに資源を奪うことを防止すると述べた.
Cgroupsもlinuxのカーネル技術であり、プロセスとそのサブプロセスのセットに対するリソース制限、制御、統計機能を提供しています.これらのリソースには、cpu、メモリ、ストレージ、ネットワークなどが含まれます.
Cgroupsの3つのコンポーネント、cgroup、subsystem、hierarchy.まずcgroupはプロセスパケット管理のメカニズムであり、1つのCgroupにはプロセスのセットが含まれており、このcgroupに対して様々なsubsystemパラメータを追加して、プロセスのセットとsubsystemのセットを関連付けることができます.次にsubsystemは、リソース管理制御のモジュールのセットです.(例えばblkioはブロックデバイスのIO制御を設定することができ、memoryはプロセスのメモリ占有を制御するために使用される...)最後にhierarchyは、Cgroupのセットを木状の構造に直列に接続する機能で、この構造Cgroupsによって継承することができます.
手動でkernelインタフェースを呼び出してCgroupsを感じます
1 hierarchy(Cgroupツリー)を作成してマウント
[root@iZ2zebynirz2ac5eron661Z ~]# mkdir cgroup-test # hierarchy
[root@iZ2zebynirz2ac5eron661Z ~]# mount -t cgroup -o none,name=cgroup-test cgroup-test ./cgroup-test # hierarchy
[root@iZ2zebynirz2ac5eron661Z ~]# ls ./cgroup-test/ #
cgroup.event_control cgroup.procs notify_on_release release_agent tasks
2ルートノードに2つのサブCgroupを拡張
[root@iZ2zebynirz2ac5eron661Z cgroup-test]# mkdir cgroup-1
[root@iZ2zebynirz2ac5eron661Z cgroup-test]# mkdir cgroup-2
[root@iZ2zebynirz2ac5eron661Z cgroup-test]# tree
.
├── cgroup-1
│ ├── cgroup.event_control
│ ├── cgroup.procs
│ ├── notify_on_release
│ └── tasks
├── cgroup-2
│ ├── cgroup.event_control
│ ├── cgroup.procs
│ ├── notify_on_release
│ └── tasks
├── cgroup.event_control
├── cgroup.procs
├── notify_on_release
├── release_agent
└── tasks
Cgroupのディレクトリの下でファイルを作成すると、kernelはこのCgroupのサブCgroupとしてファイルをマークし、Cgroupのプロパティを継承することがわかります.
3 Cgroupに移動プロセスを追加する1つのプロセスCgroupsのhierarchyでは、1つのCgroupノードにのみ存在し、システムのすべてのプロセスはデフォルトでルートノードに存在し、移動したCgroupノードのtasksファイルにプロセスIDを書き込むことでそのCgroupノードに移動できます.
[root@iZ2zebynirz2ac5eron661Z cgroup-1]# echo $$
18091
[root@iZ2zebynirz2ac5eron661Z cgroup-1]# cat /proc/18091/cgroup
1:name=cgroup-test:/
[root@iZ2zebynirz2ac5eron661Z cgroup-1]# sh -c "echo $$ >>tasks"
[root@iZ2zebynirz2ac5eron661Z cgroup-1]# cat /proc/18091/cgroup
1:name=cgroup-test:/cgroup-1
[root@iZ2zebynirz2ac5eron661Z cgroup-1]#
現在のプロセスがcgroup-1に移動していることがわかります.
4 subsystemでCgroupを制限するプロセスのリソース
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7644 bozhon 20 0 211980 205620 748 R 100.0 2.6 1:55.63 stress
bozhon@bozhon:~$ mkdir test-limit-memory && cd test-limit-memory
bozhon@bozhon:~/test-limit-memory$ cd /sys/fs/cgroup/memory
bozhon@bozhon:/sys/fs/cgroup/memory$ sudo mkdir test-limit-memory && cd test-limit-memory
[sudo] password for bozhon:
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ sudo sh -c "echo "100m">memory.limit_in_bytes"
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ sudo sh -c "echo $$ >tasks"
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ stress --vm-bytes 200m --vm-keep -m 1
stress: info: [7674] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ stress --vm-bytes 200m --vm-keep -m 1
stress: info: [7676] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ stress --vm-bytes 100m --vm-keep -m 1
stress: info: [7678] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
bozhon@bozhon:/sys/fs/cgroup/memory/test-limit-memory$ stress --vm-bytes 10m --vm-keep -m 1
stress: info: [7680] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
制限100 Mを使用すると、100 M以上のプロセスが殺されることがわかります.
Cgroupsのdockerでの運用
02613 ec 46397 ee 46 a 6 a 9 bd 7 e 62 f 78 b 1 bd 89 f 15 f 07 b 898 f 3 c 8553 db 4243 b 5346 fはある容器IDである
bozhon@bozhon:~$ cd /sys/fs/cgroup/memory/docker/02613ec46397ee46a6a9bd7e62f78b1bd89f15f07b898f3c8553db4243b5346f/
bozhon@bozhon:/sys/fs/cgroup/memory/docker/02613ec46397ee46a6a9bd7e62f78b1bd89f15f07b898f3c8553db4243b5346f$ ls
cgroup.clone_children memory.kmem.failcnt memory.kmem.tcp.limit_in_bytes memory.max_usage_in_bytes memory.soft_limit_in_bytes notify_on_release
cgroup.event_control memory.kmem.limit_in_bytes memory.kmem.tcp.max_usage_in_bytes memory.move_charge_at_immigrate memory.stat tasks
cgroup.procs memory.kmem.max_usage_in_bytes memory.kmem.tcp.usage_in_bytes memory.numa_stat memory.swappiness
memory.failcnt memory.kmem.slabinfo memory.kmem.usage_in_bytes memory.oom_control memory.usage_in_bytes
memory.force_empty memory.kmem.tcp.failcnt memory.limit_in_bytes memory.pressure_level memory.use_hierarchy
bozhon@bozhon:/sys/fs/cgroup/memory/docker/02613ec46397ee46a6a9bd7e62f78b1bd89f15f07b898f3c8553db4243b5346f$ cat memory.limit_in_bytes
9223372036854771712
Cgroupsによるコンテナリソースの制限をgo言語で実現
package main
import (
"os"
"fmt"
"syscall"
"os/exec"
"path"
"io/ioutil"
"strconv"
)
// memory subsystem hierarchy
const cgroupMemoryHierarchyMount ="/sys/fs/cgroup/memory"
func main() {
if os.Args[0] == "/proc/self/exe"{
//
fmt.Printf("current pid %d",syscall.Getpid())
fmt.Println()
cmd := exec.Command("sh","-c",`stress --vm-bytes 200m --vm-keep -m 1` )
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err:= cmd.Run(); err!=nil{
fmt.Println(err)
os.Exit(1)
}
}
cmd := exec.Command("/proc/self/exe")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWPID|syscall.CLONE_NEWNS,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err:= cmd.Run(); err!=nil{
fmt.Println(err)
os.Exit(1)
}else{
// fork pid
fmt.Printf("%v",cmd.Process.Pid)
// memory subsystem Hierachy cgroup
os.Mkdir(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit"),0755)
// cgroup
ioutil.WriteFile(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit","memory.limit_in_bytes"),
[]byte(strconv.Itoa(cmd.Process.Pid)),0644)
// cgroup
ioutil.WriteFile(path.Join(cgroupMemoryHierarchyMount,"testmemorylimit","memory.limit_in_bytes"),
[]byte("100m"),0644)
}
cmd.Process.Wait()
}
20%のメモリ(1 G*20%=100 M)が消費されていることがわかり、制限が成功したことを示しています.
34192 maojian+ 20 0 41820 3764 3120 R 4.3 0.4 0:00.40 top
1 root 20 0 119744 5844 4012 S 0.0 0.6 0:02.73 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:01.80 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root 20 0 0 0 0 S 0.0 0.0 0:00.70 rcu_sched
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
10 root rt 0 0 0 0 S 0.0 0.0 0:00.03 watchdog/0
11 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs