cgroups, control groups(控制群組)的簡寫,是linux內核的一個功能,用來限制、控制與分離一個進程資源(如cpu、內存、磁盤等)。
那么linux又是如何讓用戶態的進程使用到cgroup(內核態)的功能呢?
答:Linux通過文件系統,將cgroups的功能和配置暴露給用戶,cgroup是一組通過cgroup文件系統限制的進程集合。
可以通過mount命令查看cgroup掛載信息
$ mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
涉及到cpu調度的參數主要有3個
- 
cpu.cfs_period_us,一個調度周期。默認值是100000,也就 100us。一般我們不會去修改這個參數的值。 
- 
cpu.cfs_quota_us,在一個調度周期里被允許的運行時間,比如這個值為 50000 時,就是 50us。默認值是-1,即沒有限制。cpu.cfs_quota_us / cpu.cfs_period_us = 50000 / 100000 = 0.5, 即這個控制組被允許使用的 CPU 最大配額就是 0.5 個 CPU。top上看到的就是50%。 下文我們可以看到僅僅就通過修改cpu.cfs_quota_us的值就修改了進程的cpu使用率。 
- 
cpu.shares。這個值是 CPU Cgroup 對于控制組之間的 CPU 分配比例,默認值是 1024如果組1的cpu.shares值是1024,組2的cpu.shares值是3072。那么組1和組2各自的分配比例就是1:3 
創建cpu控制組
mkdir -p /sys/fs/cgroup/cpu/test-group/group1
mkdir -p /sys/fs/cgroup/cpu/test-group/group2
創建好后,目錄下自動就有下面這些文件
注:test-group目錄下同樣有這些文件
$ ls -l /sys/fs/cgroup/cpu/test-group
total 0
-rw-r--r-- 1 root root 0 Mar 20 22:17 cgroup.clone_children
--w--w--w- 1 root root 0 Mar 20 22:17 cgroup.event_control
-rw-r--r-- 1 root root 0 Mar 20 22:17 cgroup.procs
-r--r--r-- 1 root root 0 Mar 20 22:17 cpuacct.stat
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpuacct.usage
-r--r--r-- 1 root root 0 Mar 20 22:17 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.shares
-r--r--r-- 1 root root 0 Mar 20 22:17 cpu.stat
drwxr-x--- 2 root root 0 Mar 20 22:17 group1
-rw-r--r-- 1 root root 0 Mar 20 22:17 notify_on_release
-rw-r--r-- 1 root root 0 Mar 20 22:17 tasks
?
$ ls -l /sys/fs/cgroup/cpu/test-group/group1/
total 0
-rw-r--r-- 1 root root 0 Mar 20 22:17 cgroup.clone_children
--w--w--w- 1 root root 0 Mar 20 22:17 cgroup.event_control
-rw-r--r-- 1 root root 0 Mar 20 22:17 cgroup.procs
-r--r--r-- 1 root root 0 Mar 20 22:17 cpuacct.stat
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpuacct.usage
-r--r--r-- 1 root root 0 Mar 20 22:17 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 Mar 20 22:17 cpu.shares
-r--r--r-- 1 root root 0 Mar 20 22:17 cpu.stat
-rw-r--r-- 1 root root 0 Mar 20 22:17 notify_on_release
-rw-r--r-- 1 root root 0 Mar 20 22:17 tasks
說明
- 
tasks:當前 cgroup 包含的任務(task)pid 列表,把某個進程的 pid 添加到這個文件中就等于把進程交由到該cgroup控制。 
- 
cgroup.procs:使用邏輯和tasks相同。 
- 
notify_on_release:0或者1,該文件的內容為1時,當cgroup退出時(不再包含任何進程和子cgroup),將調用release_agent里面配置的命令。 
- 
release_agent:需要執行的命令。 
配置示例
限制使用2個CPU(內核)(每500ms能使用1000ms的CPU時間,即使用兩個內核)
# echo 1000000 > cpu.cfs_quota_us
# echo 500000 > cpu.cfs_period_us
添加任務進程到cgroup
echo PID > tasks
一次只能添加一個任務進程ID。如果有多個任務ID,需分多次添加。
cgroup各個子系統初始化時,默認把系統中所有進程都納管了,將一個進程的pid添加到新建的cgroup tasks文件的操作,實際是從一個cgroup移入到另一個cgroup的操作。所以要將進程從某個cgroup中刪除,只能通過將其移出到另一個cgroup來實現,或者將進程終止。