zdq0394.github.com

Tech study and research.

Follow me on GitHub

Linux Control Group

Linux Namespace提供了一种对系统资源进行隔离的方法;Linux Control Group(CGroup)提供了一种对系统资源进行限制的方法。 Linux CGroup不但可以限制系统资源,还可以对系统资源进行计量优先级控制

Cgroup子系统

针对不同的资源,Cgroup提供了不同的子系统: 可以通过命令/proc/cgroups查看系统支持的cgroup子系统。

cat /proc/cgroups
#subsys_name	hierarchy	num_cgroups	enabled
cpuset	11	38	1
cpu	2	160	1
cpuacct	2	160	1
blkio	10	160	1
memory	9	447	1
devices	5	160	1
freezer	7	38	1
net_cls	4	38	1
perf_event	12	38	1
net_prio	4	38	1
hugetlb	3	38	1
pids	8	160	1
rdma	6	1	1

在Centos系统中,cgroup文件系统默认mount到/sys/fs/cgroup

ll /sys/fs/cgroup/
total 0
dr-xr-xr-x 2 root root  0 Jul 11 13:44 blkio
lrwxrwxrwx 1 root root 11 Jul  9 09:53 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jul  9 09:53 cpuacct -> cpu,cpuacct
dr-xr-xr-x 2 root root  0 Jul 11 13:44 cpu,cpuacct
dr-xr-xr-x 2 root root  0 Jul 11 13:44 cpuset
dr-xr-xr-x 4 root root  0 Jul 11 13:44 devices
dr-xr-xr-x 2 root root  0 Jul 11 13:44 freezer
dr-xr-xr-x 2 root root  0 Jul 11 13:44 hugetlb
dr-xr-xr-x 2 root root  0 Jul 11 13:44 memory
lrwxrwxrwx 1 root root 16 Jul  9 09:53 net_cls -> net_cls,net_prio
dr-xr-xr-x 2 root root  0 Jul 11 13:44 net_cls,net_prio
lrwxrwxrwx 1 root root 16 Jul  9 09:53 net_prio -> net_cls,net_prio
dr-xr-xr-x 2 root root  0 Jul 11 13:44 perf_event
dr-xr-xr-x 2 root root  0 Jul 11 13:44 pids
dr-xr-xr-x 2 root root  0 Jul 11 13:44 rdma
dr-xr-xr-x 4 root root  0 Jul 11 13:44 systemd

其中,各个子系统是相对独立,分别控制不同种类的资源。

如下示例中,cpu和memory控制组分别从CPU和memory两个方面对容器pod87c850db-76cc-11e9-b277-5254000aaae3/41675c9ebd96e64d40f67b85c4d80cbc8006d3de6f5d3b91f3c8785c5a3de9bd进行资源限制。

# ll /sys/fs/cgroup/cpu/kubepods/besteffort/pod87c850db-76cc-11e9-b277-5254000aaae3/41675c9ebd96e64d40f67b85c4d80cbc8006d3de6f5d3b91f3c8785c5a3de9bd
total 0
-rw-r--r-- 1 root root 0 Jul  8 16:40 cgroup.clone_children
-rw-r--r-- 1 root root 0 May 20 14:19 cgroup.procs
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.stat
-rw-r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_all
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_percpu
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_percpu_sys
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_percpu_user
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_sys
-r--r--r-- 1 root root 0 Jul  8 16:40 cpuacct.usage_user
-rw-r--r-- 1 root root 0 Jul  8 16:40 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Jul  8 16:40 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Jul  8 16:40 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Jul  8 16:40 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 May 20 14:19 cpu.shares
-r--r--r-- 1 root root 0 Jul  8 16:40 cpu.stat
-rw-r--r-- 1 root root 0 Jul  8 16:40 notify_on_release
-rw-r--r-- 1 root root 0 Jul  8 16:40 tasks

# ll /sys/fs/cgroup/memory/kubepods/besteffort/pod87c850db-76cc-11e9-b277-5254000aaae3/41675c9ebd96e64d40f67b85c4d80cbc8006d3de6f5d3b91f3c8785c5a3de9bd
total 0
-rw-r--r-- 1 root root 0 Jul  8 16:40 cgroup.clone_children
--w--w--w- 1 root root 0 Jul  8 16:40 cgroup.event_control
-rw-r--r-- 1 root root 0 May 20 14:19 cgroup.procs
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.failcnt
--w------- 1 root root 0 Jul  8 16:40 memory.force_empty
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.numa_stat
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.oom_control
---------- 1 root root 0 Jul  8 16:40 memory.pressure_level
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.stat
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.swappiness
-r--r--r-- 1 root root 0 Jul  8 16:40 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Jul  8 16:40 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Jul  8 16:40 notify_on_release
-rw-r--r-- 1 root root 0 Jul  8 16:40 tasks

Cgroup使用

创建group并对资源进行限制

  • 在任何subsystem下创建子目录,比如在/sys/fs/cgroup/cpu下创建mytest;然后将需要进行限制的进程ID加入到mytest/tasks中,并对资源进行一定的限制。
    # mkdir mytest
    # cd mytest/
    # ll
    total 0
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cgroup.clone_children
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cgroup.procs
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.stat
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_all
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_percpu
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_percpu_sys
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_percpu_user
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_sys
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpuacct.usage_user
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpu.cfs_period_us
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpu.cfs_quota_us
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpu.rt_period_us
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpu.rt_runtime_us
    -rw-r--r-- 1 root root 0 Jul 11 13:53 cpu.shares
    -r--r--r-- 1 root root 0 Jul 11 13:53 cpu.stat
    -rw-r--r-- 1 root root 0 Jul 11 13:53 notify_on_release
    -rw-r--r-- 1 root root 0 Jul 11 13:53 tasks
    

    示例

  • 准备工作 如下脚本将往设备/dev/tty持续性的写如数据:
#!/bin/bash
while :
do
    echo "print line" > /dev/tty
    sleep 3
done

将脚本保存为mytest.sh。

  • 创建devices资源的cgroup mytest 在/sys/fs/cgroup/devices/目录下创建croup——mytest(名字不重要)。
[/sys/fs/cgroup/devices/mytest]# ll
total 0
-rw-r--r-- 1 root root 0 Jul 11 13:58 cgroup.clone_children
-rw-r--r-- 1 root root 0 Jul 11 13:58 cgroup.procs
--w------- 1 root root 0 Jul 11 13:58 devices.allow
--w------- 1 root root 0 Jul 11 14:02 devices.deny
-r--r--r-- 1 root root 0 Jul 11 13:58 devices.list
-rw-r--r-- 1 root root 0 Jul 11 13:58 notify_on_release
-rw-r--r-- 1 root root 0 Jul 11 13:59 tasks
  • 查看/dev/tty的设备号
ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jul 11 14:00 /dev/tty

然后将该设备加入devices.deny

echo "c 5:0 w" > devices.deny
  • 执行1中保存的脚本 程序正常执行
    # ./mytest.sh 
    print line
    print line
    print line
    print line
    print line
    print line
    print line
    print line
    
  • 查看程序的pid,并将pid加入到mytest/tasks中
    echo "8439" > mytest/tasks
    

    此时观察程序输出,发现访问/dev/tty设备失败(Operation not permitted):

# ./mytest.sh 
print line
print line
print line
./mytest.sh: line 5: /dev/tty: Operation not permitted
./mytest.sh: line 5: /dev/tty: Operation not permitted