cgroups 系統是 linux 內核提供的一個基于進程組的資源管理的框架,可以為特定的進程組限定可以使用的資源。其具體介紹可以參考周明耀先生的CGroup 介紹、應用實例及原理描述【1】,該文詳細講述了cgroup的概念、結構、原理,并給出了應用實例,是不可多得的精品級入門文檔,因此建議移步學習,其內容在此也不作復述。
本文主要解答對cgroup的認知和運用上的一些常見問題。
1. namespace與hierarchy、cgroup是什么關系,容器=層級?
為了更好的理解他們的關系,我們先看一下曹江華先生的Linux 容器的建立和簡單管理【2】中對cgroup子系統的介紹,其中提到了這樣一個子系統——ns:
ns 子系統提供了一個將進程分組到不同名稱空間的方法。在具體名稱空間中,進程可彼此互動,但會與在其它名稱空間中運行的進程隔絕。這些分開的名稱空間在用于操作系統級別的虛擬化時,有時也稱之為容器。
可見,容器和層級并沒有直接的關系,容器在cgroup系統中只是作為一個子系統(資源管理器)為hierarchy中的進程劃分命名空間,將之隔離開來。
值得一提的是,提到ns子系統的文章都是2013年之前的,這是因為在2013年linux內核中的cgroup功能做了很多改動,直接把ns子系統剔除了。參考Wiki中提到的:
Redesign of cgroups started in 2013, with additional changes brought by versions 3.15 and 3.16 of the Linux kernel.……The "ns" subsystem was added early in cgroups development to integrate namespaces and control groups. If the "ns" cgroup was mounted, each namespace would also create a new group in the cgroup hierarchy. This was an experiment that was later judged to be a poor fit for the cgroups API, and removed from the kernel.
為什么要剔除ns子系統呢?筆者的理解是這樣的,用過cgroup的人會清楚,cgroup就是對系統資源進行分配,而容器不僅對進程使用的資源做隔離,還要禁止不同容器間進程的通信,這超出了cgroup的職責范圍,使其功能變得更加復雜和紊亂。因此,容器不再由cgroup管理,而是交由其他技術實現了。
2. cgroup有沒有ID?單個cgroup可在不同hierarchy中重復嗎?
cgroup沒有ID,不過有指向hierarchy(結構體)的指針和指向top-cgroup的指針,還包含有分別組織起兄弟cgroup和子cgroup的鏈表的表頭,因此每個cgroup在系統中都是唯一的。
Hierarchy本質上是文件系統中的一個目錄結構,cgroup在hierarchy中是以目錄的形式存在的,不同的hierarchy中的cgroup均是不同的目錄,目錄中包含的是該cgroup和該hierarchy子系統的一系列配置文件,以及子cgroup。
3. hierarchy與subsystem的關系
hierarchy可有多個不同的subsystem依附,如cpu、memory同時依附;一個subsystem只能依附一個hierarchy,但如果第二個hierarchy沒有其他subsystem,那么就可以依附,如可同時存在兩個僅有cpu依附的hierarchy。詳細規則可參考Red Hat EnterPRise Linux 6 Resource Management Guide【3】中的Relationships Between Subsystems, Hierarchies, Control Groups and Tasks一節。
4.root-cgroup是否包含hierarchy中所有進程?
不是,同一hierarchy內每個cgroup的進程都不會出現在其他cgroup中。
root-cgroup默認的設定是,系統一旦有新的進程出現,即刻會被root-cgroup包含進去(除了子進程,子進程生成時會自動與父進程同在一個cgroup)。某個cgroup管理的進程可在其目錄下的tasks文件中查看,操作進程加入cgroup也僅需將pid添加進該文件中。
*注:一旦把一個進程放進某個cgroup,不把它移到其他cgroup是不會離開該cgroup的;而只要加入到其他cgroup,原cgroup將會自動釋放該進程。
5.子cgroup能否繼承父cgroup資源配置?
會自動繼承,因為子cgroup的資源配置不能超出父cgroup的限定范圍。正如Ubuntu Document中提到:
In general, the kernel enforces the hierarchical constraints on limits, so that for instance if devices cgroup /child1 cannot access a disk drive, then/child1/child2 cannot give itself those rights.
而在父cgroup的限定下,子cgroup的資源配置相互之間可以相同。
6.如果給多個cgroup分配的資源有重疊會怎樣?譬如說給A分配了50%的資源,給B分配了100%的資源,它們會如何競爭?
這里給出筆者針對CPU資源的實驗結果:假設A需要使用10%的資源,B需要用80%的資源,那么當限制A使用50%的資源的時候,B是能用80%的;但A需要使用80%的資源的話,那么限定A使用50%的時候,A和B運行時都使用50%的資源。
可見,cgroup的功能是限定資源,而不是劃分資源。
操作cgroup的命令和子系統配置文件的功能可以參考how to use cgroup【4】。
7.如何在更改容器狀態后快速切換資源的分配?
修改該容器對應cgroup的配置文件。
8.為什么每個cgroup里都會自動創建一個user目錄?- Ubuntu 14.04
參考help.ubuntu.com中的解釋:
As of Ubuntu 14.04 (Linux Kernel 3.16), users are automatically placed in a set of cgroups which they own, safely allowing them to constrain their own jobs using child cgroups. This feature is relied upon, for instance, for unprivileged container creation in lxc.
參考資料
【1】CGroup 介紹、應用實例及原理描述. http://www.ibm.com/developerworks/cn/linux/1506_cgroup/index.html
【2】Linux 容器的建立和簡單管理. https://www.ibm.com/developerworks/cn/linux/1312_caojh_linuxlxc/
【3】Red Hat Enterprise Linux 6 Resource Management Guide. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html
【4】how to use cgroup. http://tiewei.github.io/devops/howto-use-cgroup/
【5】CGROUPS. https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
【6】wiki/Cgroups. https://en.wikipedia.org/wiki/Cgroups
【7】All About the Linux Kernel: Cgroup’s Redesign. http://www.linux.com/news/featured-blogs/200-libby-clark/733595-all-about-the-linux-kernel-cgroups-redesign
【8】Ubuntu Document. https://help.ubuntu.com/lts/serverguide/cgroups-delegation.html
新聞熱點
疑難解答