Linux上的Docker Engine也依賴於另一種稱爲CGroup的技術。CGroups 最初叫Process Container,顧名思義就是將進程放到一個組裏進行統一控制。後來改名叫Control Groups。CGroups 是 Control Groups 的縮寫,它爲資源管理提供了一個統一框架,可以把系統任務及其子任務整合到按資源等級劃分的不同任務組內。並且對這些任務組實施不同的資源分配方案。CGroups可以限制、記錄、隔離進程組所使用的物理資源(包括CPU、memory、I/O等)。
cgroups有如下四個有趣的特點:
- cgroups的API以一個僞文件系統的方式實現,即用戶可以通過文件操作實現cgroups的組織管理。
- cgroups的組織管理操作單元可以細粒度到線程級別,用戶態代碼也可以針對系統分配的資源創建和銷燬cgroups,從而實現資源再分配和管理。
- 所有資源管理的功能都以“subsystem(子系統)”的方式實現,接口統一。
- 子進程創建之初與其父進程處於同一個cgroups的控制組。
相關概念
任務(task)。在 cgroups 中,任務就是系統的一個進程;
控制族羣(control group)。控制族羣就是一組按照某種標準劃分的進程。Cgroups 中的資源控制都是以控制族羣爲單位實現。一個進程可以加入到某個控制族羣,也從一個進程組遷移到另一個控制族羣。一個進程組的進程可以使用 cgroups 以控制族羣爲單位分配的資源,同時受到 cgroups 以控制族羣爲單位設定的限制;
層級(hierarchy)。控制族羣可以組織成 hierarchical 的形式,既一顆控制族羣樹。控制族羣樹上的子節點控制族羣是父節點控制族羣的孩子,繼承父控制族羣的特定的屬性;
子系統(subsystem)。一個子系統就是一個資源控制器,比如 cpu 子系統就是控制 cpu 時間分配的一個控制器。子系統必須附加(attach)到一個層級上才能起作用,一個子系統附加到某個層級以後,這個層級上的所有控制族羣都受到這個子系統的控制。
子系統
cgroups提供了subsystem(resource controllers)作爲資源的控制器
- cpu (since Linux 2.6.24; CONFIG_CGROUP_SCHED)
用來限制cgroup的CPU使用率。 - cpuacct (since Linux 2.6.24; CONFIG_CGROUP_CPUACCT)
統計cgroup的CPU的使用率。 - cpuset (since Linux 2.6.24; CONFIG_CPUSETS)
綁定cgroup到指定CPUs和NUMA節點。 - memory (since Linux 2.6.25; CONFIG_MEMCG)
統計和限制cgroup的內存的使用率,包括process memory, kernel memory, 和swap。 - devices (since Linux 2.6.26; CONFIG_CGROUP_DEVICE)
限制cgroup創建(mknod)和訪問設備的權限。 - freezer (since Linux 2.6.28; CONFIG_CGROUP_FREEZER)
suspend和restore一個cgroup中的所有進程。 - net_cls (since Linux 2.6.29; CONFIG_CGROUP_NET_CLASSID)
將一個cgroup中進程創建的所有網絡包加上一個classid標記,用於tc和iptables。 只對發出去的網絡包生效,對收到的網絡包不起作用。 - blkio (since Linux 2.6.33; CONFIG_BLK_CGROUP)
限制cgroup訪問塊設備的IO速度。 - perf_event (since Linux 2.6.39; CONFIG_CGROUP_PERF)
對cgroup進行性能監控 - net_prio (since Linux 3.3; CONFIG_CGROUP_NET_PRIO)
針對每個網絡接口設置cgroup的訪問優先級。 - hugetlb (since Linux 3.5; CONFIG_CGROUP_HUGETLB)
限制cgroup的huge pages的使用量。 - pids (since Linux 4.3; CONFIG_CGROUP_PIDS)
限制一個cgroup及其子孫cgroup中的總進程數。
概念相互關係及基本規則
傳統的Unix進程管理,實際上是先啓動init進程作爲根節點,再由init節點創建子進程作爲子節點,而每個子節點由可以創建新的子節點,如此往復,形成一個樹狀結構。
Cgroup 與進程在以下方面類似:
- 它們是分級的,且
- 子 cgroup 會繼承父 cgroup 的某些屬性。
根本的不同是在某個系統中可同時存在不同的分級 cgroup。如果 Linux 進程模式是進程的單一樹模式,那麼 cgroup 模式是一個或者更多任務的獨立、未連接樹(例如:進程)。
需要多個獨立 cgroup 分級,因爲每個分級都會附加到一個或者多個子系統中。子系統代表單一資源,比如 CPU 時間或者內存。
基於虛擬文件系統的CGroup管理
Linux 使用了多種數據結構在內核中實現了 cgroups 的配置,關聯了進程和 cgroups 節點,那麼 Linux 又是如何讓用戶態的進程使用到 cgroups 的功能呢? Linux內核有一個很強大的模塊叫 VFS (Virtual File System)。 VFS 能夠把具體文件系統的細節隱藏起來,給用戶態進程提供一個統一的文件系統 API 接口。 cgroups 也是通過 VFS 把功能暴露給用戶態的,cgroups 與 VFS 之間的銜接部分稱之爲 cgroups 虛擬文件系統。使用cgroup很簡單,掛載這個文件系統就可以了。這時通過掛載選項指定使用哪個子系統。
默認情況都是掛載到/sys/fs/cgroup目錄下,當然掛載到其它任何目錄都沒關係。
//掛載一顆和所有subsystem關聯的cgroup樹到/sys/fs/cgroup
mount -t cgroup <cgroup name> /sys/fs/cgroup
//掛載一顆和cpuset subsystem關聯的cgroup樹到/sys/fs/cgroup/cpuset
mkdir /sys/fs/cgroup/cpuset
mount -t cgroup -o cpuset <cgroup name> /sys/fs/cgroup/cpuset
//掛載一顆與cpu和cpuacct subsystem關聯的cgroup樹到/sys/fs/cgroup/cpu,cpuacct
mkdir /sys/fs/cgroup/cpu,cpuacct
mount -t cgroup -o cpu,cpuacct <cgroup name> /sys/fs/cgroup/cpu,cpuacct
//掛載一棵cgroup樹,但不關聯任何subsystem,下面就是systemd所用到的方式
mkdir /sys/fs/cgroup/systemd
mount -t cgroup -o none,name=systemd <cgroup name> /sys/fs/cgroup/systemd
規則 1: 多個subsystem可附着到同一個hierarchy
例如在ubuntu中,systemd就是將和cpu,cpuacct兩個subsystem掛載到了/sys/fs/cgroup/cpu,cpuacct 這個hierarchy
# mount |grep cpu,cpuacct
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
規則2: 一個subsystem不能同時附加到多個hierarchy,除非那個hierarchy不包含其他subsystem。
//嘗試將cpu subsystem重新關聯cpu_cg hierarchy 並且將這棵樹mount到./cpu目錄
# mkdir -p /mnt/cgroup/cpu_cg
# mount -t cgroup -o cpu cpu_cg /mnt/cgroup/cpu_cg
mount: cpu_cg is already mounted or /mnt/cgroup/cpu_cg busy
//但是將memory subsystem 關聯到另一個Cgroup hierarchy是可以的
# mkdir -p /mnt/cgroup/mem_cg
# mount -t cgroup -o memory mem_cg /mnt/cgroup/mem_cg
# mount|grep memory
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
mem_cg on /mnt/cgroup/mem_cg type cgroup (rw,relatime,memory)
//實際上,用同樣的參數掛載時,會重用現有的cgroup hierarchy,也即兩個掛載點看到的內容是一樣的
# mkdir -p /mnt/cgroup/cpu,cpuacct && cd /mnt/cgroup
# mount -t cgroup -o cpu,cpuacct new-cpu-cpuacct ./cpu,cpuacct
# mount |grep cpu,cpuacct
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
new-cpu-cpuacct on /mnt/cgroup/cpu,cpuacct type cgroup (rw,relatime,cpu,cpuacct)
# mkdir -p /sys/fs/cgroup/cpu,cpuacct/test; ls -l /mnt/cgroup/cpu,cpuacct|grep test
drwxr-xr-x 2 root root 0 1月 23 18:18 test
//clean
# umount new-cpu-cpuacct
# umount mem_cg
# cgdelete cpu,cpuacct:test
本質上將,一個subsystem只能關聯到一顆cgroup hierarchy ,一旦關聯並在這個hierarchy上創建了子cgroup,subsystems和這棵cgroup hierarchy就成了一個整體,不能再重新組合。
規則3:同一個task不能同時作爲同一個hierarchy的不同cgroup的成員
每次在系統中創建新hierarchy時,該系統中的所有task都是那個hierarchy的默認 cgroup(我們稱之爲 root cgroup)的初始成員。
這樣,單一task可以是在多個 cgroup 中。前提是這些cgroup不能同時位於同一個hierarchy。
首先我們嘗試創建一個root cgroup, 在系統中可以創建任意多個不和任何subsystem關聯的cgroup樹,name是這棵樹的唯一標記,當name指定的是一個新的名字時,將創建一顆新的cgroup樹,但如果內核中已經存在一顆一樣name的cgroup樹,那麼將mount已存在的這顆cgroup樹
// 由於name=test的cgroup樹在系統中不存在,所以這裏會創建一顆新的name=test的cgroup樹
# mkdir -p /mnt/cgroup/test && cd /mnt/cgroup
# mount -t cgroup -o none,name=test test ./test
// 系統爲新創建的cgroup樹的root cgroup生成了默認文件
# ls /mnt/cgroup/test
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks
// 新創建的cgroup樹的root cgroup裏包含系統中的所有進程
# wc -l ./test/cgroup.procs
188 ./test/cgroup.procs
// 創建子cgroup
# cd test && mkdir subcg
// 系統已經爲新的子cgroup生成了默認文件
# ls subcg
cgroup.clone_children cgroup.procs notify_on_release tasks
//新創建的子cgroup中沒有任何進程
# wc -l subcg/cgroup.procs
0 subcg/cgroup.procs
//重新掛載這棵樹到test1,由於mount的時候指定的name=test,所以和上面掛載的是同一顆cgroup樹,於是test1目錄下的內容和test目錄下的內容一樣
# mkdir -p /mnt/cgroup/test1 && cd /mnt/cgroup
# mount -t cgroup -o none,name=test test ./test1
# ls ./test1
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent subcg tasks
#清理
# umount /mnt/cgroup/test1
# umount /mnt/cgroup/test
# rm -rf /mnt/cgroup/test /mnt/cgroup/test1
再試一個例子:
// 換一個console 啓動一個bash
$ ps -ef|grep $$
chic 1944 1939 0 09:56 pts/1 00:00:00 -bash
//查看這個bash所屬的cgroup
$ cat /proc/1944/cgroup
11:blkio:/user.slice
10:freezer:/
9:memory:/user.slice
8:cpuset:/
7:devices:/user.slice
6:net_cls,net_prio:/
5:hugetlb:/
4:pids:/user.slice/user-1000.slice
3:perf_event:/
2:cpu,cpuacct:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
每一行包含用冒號隔開的三列,他們的意思分別是
- cgroup樹的ID, 和/proc/cgroups文件中的ID一一對應。
- 和cgroup樹綁定的所有subsystem,多個subsystem之間用逗號隔開。這裏name=systemd表示沒有和任何subsystem綁定,只是給他起了個名字叫systemd。
- 進程在cgroup樹中的路徑,即進程所屬的cgroup,這個路徑是相對於掛載點的相對路徑。
# mount -t cgroup -o none,name=cgroup cgroup /mnt/cgroup
# mkdir -p /mnt/cgroup/child1
# mkdir -p /mnt/cgroup/child2
//檢查之前的bash現在也屬於這個cgroup
/mnt/cgroup# cat cgroup.procs |grep 1944
1944
//將bash移入 child1 cgroup
# cd child1
# echo 1944 > cgroup.procs
# cat /proc/1944/cgroup
13:name=cgroup:/child1
11:blkio:/user.slice
10:freezer:/
9:memory:/user.slice
8:cpuset:/
7:devices:/user.slice
6:net_cls,net_prio:/
5:hugetlb:/
4:pids:/user.slice/user-1000.slice
3:perf_event:/
2:cpu,cpuacct:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
//再試着將bash放入 child2 cgroup
# echo 1944 > /mnt/cgroup/child2/cgroup.procs
# cat /proc/1944/cgroup
13:name=cgroup:/child2
11:blkio:/user.slice
10:freezer:/
9:memory:/user.slice
8:cpuset:/
7:devices:/user.slice
6:net_cls,net_prio:/
5:hugetlb:/
4:pids:/user.slice/user-1000.slice
3:perf_event:/
2:cpu,cpuacct:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
//可以看見bash現在屬於child2 而從child1 移除了,一個task不會同時屬於同一hierarchy的不同cgroup
規則4:子進程(task)總是自動成爲父進程所在的cgroup的成員,然後可以移動到不同的cgroup中去。
接着之前的例子:
//在新的bash(1944)中在啓動一個bash(12110)
$ pstree -p 1944
bash(1944)───bash(12110)───pstree(12142)
$ cat /proc/12110/cgroup
13:name=cgroup:/child2
11:blkio:/user.slice
10:freezer:/
9:memory:/user.slice
8:cpuset:/
7:devices:/user.slice
6:net_cls,net_prio:/
5:hugetlb:/
4:pids:/user.slice/user-1000.slice
3:perf_event:/
2:cpu,cpuacct:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
使用libcgroup工具包
libcgroup工具安裝
- redhat系統:
yum install libcgroup - ubuntu系統:
sudo apt-get install cgroup-bin cgroup-lite cgroup-tools cgroupfs-mount libcgroup1
cgroup服務的啓動和停止:
- redhat系統(Sys V init):
service cgconfig start|stop - ubuntu系統(Systemd):
systemctl start cgmanager.service
systemctl start run-cgmanager-fs.mount
systemctl start cgroupfs-mount.service
CGroups功能測試(基於Ubuntu)
在Ubuntu上安裝完成cgroup工具包後,系統會創建以下文件:
- /sys/fs/cgroup; 該文件夾包含一堆cgroup類型掛在的虛擬文件用來代表特定的cgroup層級.
- /etc/init/cgroup-lite.conf. cgroup-lite.conf creates the /sys/fs/cgroup directory, based on the contents of
- /proc/cgroups, 這個文件指定了cgroup-lite 應該創建哪些Control group.
安裝cgroup-bin後,unbuntu的systemd已經幫我們將各個subsystem和cgroup樹關聯並掛載好了
# mount |grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (rw,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids,release_agent=/run/cgmanager/agents/cgm-release-agent.pids)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event,release_agent=/run/cgmanager/agents/cgm-release-agent.perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb,release_agent=/run/cgmanager/agents/cgm-release-agent.hugetlb)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset,clone_children)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
# ls /sys/fs/cgroup/
blkio cgmanager cpu cpuacct cpu,cpuacct cpuset devices freezer hugetlb memory net_cls net_cls,net_prio net_prio perf_event pids systemd
cgroup-bin 包含的基本命令
- /usr/bin/cgclassify – cgclassify命令是用來將運行的任務移動到一個或者多個cgroup。
- /usr/bin/cgcreate – cgcreate在層級中創建新cgroup。
- /usr/bin/cgdelete – cgdelete命令刪除指定的cgroup。
- /usr/bin/cgexec – cgexec命令在指定的cgroup中運行任務。
- /usr/bin/cgget – cgget命令顯示cgroup參數。
- /usr/bin/cgset – cgset 命令爲 cgroup 設定參數。
- /usr/bin/lscgroup – lscgroup 命令列出層級中的 cgroup。
- /usr/bin/lssubsys – lssubsys 命令列出包含指定子系統的層級
- /usr/sbin/cgclear – cgclear 命令是用來刪除層級中的所有cgroup。
- /usr/sbin/cgconfigparser – cgconfigparser命令解析cgconfig.conf文件和並掛載層級。
- /usr/sbin/cgrulesengd – cgrulesengd 在 cgroup 中發佈任務。
相關配置文件:
- cgred.conf – cgred.conf是cgred服務的配置文件。
- cgrules.conf – cgrules.conf 包含用來決定何時任務術語某些 cgroup的規則。
- cgconfig.conf – 在cgconfig.conf文件中定義cgroup。
cgconfig.conf
cgconfig.conf是libcgroup用於定義控制組及其參數和掛載點的配置文件。 該文件由mount,group和default部分組成。 這些部分可以是任意的順序,所有這些部分都是可選的。 (refer to “man cgconfig.conf”)
- mount section
mount {
<controller> = <path>;
...
}
//controller : kernel subsystem 名稱
//path : 與給controller關聯的hierarichy的目錄路徑。
- group section
group <name> {
[permissions]
<controller> {
<param name> = <param value>;
...
}
...
}
//name: Name of the control group
//permissions: 可選項,指定cgroup對應的掛載點文件系統的權限,root用戶擁有所有權限
//param name 和 param value:子系統的屬性及其屬性值
- default section
default {
perm {
task {
uid = <task user>;
gid = <task group>;
fperm = <file permissions>
}
admin {
uid = <admin name>;
gid = <admin group>;
dperm = <directory permissions>
fperm = <file permissions>
}
}
}
例如:
mount {
cpu = /sys/fs/cgroup/cpu;
cpuacct = /sys/fs/cgroup/cpu;
}
group daemons/www {
perm {
task {
uid = root;
gid = webmaster;
fperm = 770;
}
admin {
uid = root;
gid = root;
dperm = 775;
fperm = 744;
}
}
cpu {
cpu.shares = "1000";
}
}
group daemons/ftp {
perm {
task {
uid = root;
gid = ftpmaster;
fperm = 774;
}
admin {
uid = root;
gid = root;
dperm = 755;
fperm = 700;
}
}
cpu {
cpu.shares = "500";
}
}
相當於:
mkdir /sys/fs/cgroup/cpu
mount -t cgroup -o cpu,cpuacct cpu /sys/fs/cgroup/cpu
mkdir /sys/fs/cgroup/cpu/daemons
mkdir /sys/fs/cgroup/cpu/daemons/www
chown root:root /sys/fs/cgroup/cpu/daemons/www/*
chown root:webmaster /sys/fs/cgroup/cpu/daemons/www/tasks
echo 1000 > /sys/fs/cgroup/cpu/daemons/www/cpu.shares
mkdir /sys/fs/cgroup/cpu/daemons/ftp
chown root:root /sys/fs/cgroup/cpu/daemons/ftp/*
chown root:ftpmaster /sys/fs/cgroup/cpu/daemons/ftp/tasks
echo 500 > /sys/fs/cgroup/cpu/daemons/ftp/cpu.shares
cgroup manager
cgroup manager(cgmanager)提供了一個D-Bus服務,允許程序和用戶管理cgroup,而不需要直接瞭解或訪問cgroup文件系統。 對於來自與管理者相同名稱空間任務的請求,管理者可以直接執行所需的安全檢查,以確保請求是合法的。 對於其他請求(例如來自容器中任務的請求),必須進行增強的D-Bus請求,其中將進程,用戶和組ID作爲SCM_CREDENTIALS傳遞,以便內核將標識符映射到其全局主機值。
爲了便利所有用戶使用簡單的D-Bus呼叫,一個“cgroup管理器代理”(cgproxy)在容器中自動啓動。 代理服務器接受來自相同命名空間中任務的標準D-Bus請求,並將它們轉換爲SCM傳遞給cgmanager的D-Bus請求。
創建一個運行cpu密集編譯的新cgroup的簡單例子如下所示:
cgm create cpuset build1
cgm movepid cpuset build1 $$
cgm setvalue cpuset build1 cpuset.cpus 1
make
cgm
cgm是一個簡化cgroup manager請求的客戶端腳本。 它只是調用dbus-send向運行中的cgmanager或cgproxy發送請求。
下面的例子中,首先創建一個名爲foo的cgroup然後將當前shell移入其中:
sudo cgm create all foo
sudo cgm chown all foo $(id -u) $(id -g)
cgm movepid all foo $$
//then to freeze the cgroup
cgm setvalue freezer foo freezer.state FROZEN
cgproxy
cgproxy是cgmanager的D-Bus代理。 由於非初始pid或user namespace中的進程將引用任務,用戶ID或組ID 在初始名稱空間中是錯亂的。cgproxy將依據內核將它們作爲SCM憑證發送給cgmanager 翻譯標識符。 通過這種方式,容器中的程序和用戶可以使用相同的簡單D-Bus調用通過代理服務器進行cgroup管理請求,就像它們在基本主機上直接與cgmanager交互一樣。
example
創建一個耗CPU的腳本:
$ cat cpu.sh
#!/bin/bash
tmp=1
while [ True ];do
tmp=$tmp
done;
運行一下:
#top -p `pidof -x cpu.sh`
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26855 chic 20 0 14264 912 808 R 100.0 0.0 0:08.70 cpu.sh
創建一個cpu受限的cgroup
# cgcreate -a root -t chic -g cpu:mycpulimitgrp
# ls -l /sys/fs/cgroup/cpu/mycpulimitgrp/
total 0
-rw-r--r-- 1 root root 0 1月 24 17:32 cgroup.clone_children
-rw-r--r-- 1 root root 0 1月 24 17:32 cgroup.procs
-r--r--r-- 1 root root 0 1月 24 17:32 cpuacct.stat
-rw-r--r-- 1 root root 0 1月 24 17:32 cpuacct.usage
-r--r--r-- 1 root root 0 1月 24 17:32 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 1月 24 17:32 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 1月 24 17:32 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 1月 24 17:32 cpu.shares
-r--r--r-- 1 root root 0 1月 24 17:32 cpu.stat
-rw-r--r-- 1 root root 0 1月 24 17:32 notify_on_release
-rw-r--r-- 1 chic root 0 1月 24 17:32 tasks
# cat /sys/fs/cgroup/cpu/mycpulimitgrp/cpu.cfs_period_us
100000
# cat /sys/fs/cgroup/cpu/mycpulimitgrp/cpu.cfs_quota_us
-1
//或者
# cgget -g cpu:mycpulimitgrp
mycpulimitgrp:
cpu.shares: 1024
cpu.cfs_quota_us: -1
cpu.stat: nr_periods 0
nr_throttled 0
throttled_time 0
cpu.cfs_period_us: 100000
- cpu.cfs_period_us 表示將每個cpu時間片分成100000份。
- cpu.cfs_period_us 表示當前這個組中的task(tasks中的taskid)將分配多少比例的cpu時間片。如果是雙核cpu,這裏就表示最多可以用到200%的CPU。
爲我們的cgroup分配 50% cpu的配額
# echo 50000 > /sys/fs/cgroup/cpu/mycpulimitgrp/cpu.cfs_quota_us
//或者
# cgset -r cpu.cfs_quota_us=50000 mycpulimitgrp
$ cgexec -g cpu:mycpulimitgrp ./cpu.sh
$ top -p `pidof -x cpu.sh`
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29224 chic 20 0 14264 904 800 R 50.0 0.0 0:21.42 cpu.sh
//stop cpu.sh and clean
# cgdelete -r cpu:mycpulimitgrp
參考:
- Resource Management Guide
- Ubuntu 服務器指南(Control Group)
- linux kernel CGroup
- CGroup 介紹、應用實例及原理描述
- Introduction to Linux Control Groups (Cgroups)
- Docker 和 cgroup