簡介:
Linux CGroup全稱Linux Control Group, 是Linux內核的一個功能,用來限制,控制與分離一個進程組群的資源(如CPU、內存、磁盤輸入輸出等)。這個項目最早是由Google的工程師在2006年發起(主要是Paul Menage和Rohit Seth),最早的名稱為進程容器(process containers)。在2007年時,因為在Linux內核中,容器(container)這個名詞太過廣泛,為避免混亂,被重命名為cgroup,並且被合並到2.6.24版的內核中去。然后,其它開始了他的發展。
Linux CGroupCgroup 可讓您為系統中所運行任務(進程)的用戶定義組群分配資源 — 比如 CPU 時間、系統內存、網絡帶寬或者這些資源的組合。您可以監控您配置的 cgroup,拒絕 cgroup 訪問某些資源,甚至在運行的系統中動態配置您的 cgroup。
主要功能:
- 限制資源使用,比如內存使用上限以及文件系統的緩存限制。
- 優先級控制,CPU利用和磁盤IO吞吐。
- 一些審計或一些統計,主要目的是為了計費。
- 掛起進程,恢復執行進程。
cgroups子系統
- cpu 子系統,主要限制進程的 cpu 使用率。
- cpuacct 子系統,可以統計 cgroups 中的進程的 cpu 使用報告。
- cpuset 子系統,可以為 cgroups 中的進程分配單獨的 cpu 節點或者內存節點。
- memory 子系統,可以限制進程的 memory 使用量。
- blkio 子系統,可以限制進程的塊設備 io。
- devices 子系統,可以控制進程能夠訪問某些設備。
- net_cls 子系統,可以標記 cgroups 中進程的網絡數據包,然后可以使用 tc 模塊(traffic control)對數據包進行控制。
- net_prio — 這個子系統用來設計網絡流量的優先級
- freezer 子系統,可以掛起或者恢復 cgroups 中的進程。
- ns 子系統,可以使不同 cgroups 下面的進程使用不同的 namespace
- hugetlb — 這個子系統主要針對於HugeTLB系統進行限制,這是一個大頁文件系統。
cgroups 層級結構(Hierarchy)
內核使用 cgroup 結構體來表示一個 control group 對某一個或者某幾個 cgroups 子系統的資源限制。cgroup 結構體可以組織成一顆樹的形式,每一棵cgroup 結構體組成的樹稱之為一個 cgroups 層級結構。
cgroups層級結構可以 attach 一個或者幾個 cgroups 子系統,當前層級結構可以對其 attach 的 cgroups 子系統進行資源的限制。每一個 cgroups 子系統只能被 attach 到一個 cpu 層級結構中。
好好理解下這個圖即可:

創建了 cgroups 層級結構中的節點(cgroup 結構體)之后,可以把進程加入到某一個節點的控制任務列表中,一個節點的控制列表中的所有進程都會受到當前節點的資源限制。同時某一個進程也可以被加入到不同的 cgroups 層級結構的節點中,因為不同的 cgroups 層級結構可以負責不同的系統資源。所以說進程和 cgroup 結構體是一個多對多的關系。

上面這個圖從整體結構上描述了進程與 cgroups 之間的關系。最下面的P代表一個進程。每一個進程的描述符中有一個指針指向了一個輔助數據結構css_set(cgroups subsystem set)。 指向某一個css_set的進程會被加入到當前css_set的進程鏈表中。一個進程只能隸屬於一個css_set,一個css_set可以包含多個進程,隸屬於同一css_set的進程受到同一個css_set所關聯的資源限制。
上圖中的”M×N Linkage”說明的是css_set通過輔助數據結構可以與 cgroups 節點進行多對多的關聯。但是 cgroups 的實現不允許css_set同時關聯同一個cgroups層級結構下多個節點。 這是因為 cgroups 對同一種資源不允許有多個限制配置。
一個css_set關聯多個 cgroups 層級結構的節點時,表明需要對當前css_set下的進程進行多種資源的控制。而一個 cgroups 節點關聯多個css_set時,表明多個css_set下的進程列表受到同一份資源的相同限制。
實踐操作
查看cgroup掛載點(centos7.5):
1 [root@k8s-master ~]# mount -t cgroup 2 cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) 3 cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) 4 cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) 5 cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) 6 cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu) 7 cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) 8 cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) 9 cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) 10 cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) 11 cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) 12 cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
創建隔離組
[root@k8s-master ~]# cd /sys/fs/cgroup/cpu
[root@k8s-master cpu]# mkdir cpu_test
目錄創建完成會自動生成以下文件
[root@k8s-master cpu]# ls cpu_test/
![]()
寫個死循環測試程序增加cpu使用率
1 int main(void) 2 { 3 int i = 0; 4 for(;;) i++; 5 return 0; 6 }
啟動程序后cpu使用100%
默認-1不限制,現在改成20000,可以理解使用率限制在20%
[root@k8s-master cpu]# echo 20000 > /sys/fs/cgroup/cpu/cpu_test/cpu.cfs_quota_us
找到進程號增加到cpu tasks里面,在看top cpu使用率很快就下來
[root@k8s-master ~]# echo 23732 >> /sys/fs/cgroup/cpu/cpu_test/tasks
其它資源限制和cpu基本一致就先寫這么多了


