歡迎光臨
每天分享高質量文章

平凡:Docker底層的核心知識——cgroups

Linux核心之旅
快來點選關註

作者簡介

平凡,西安郵電大學在讀研二學生,

積極樂觀,在做好自己專業的同時也喜歡瞭解各方面的知識,包括會使用hadoop與tensorflow。也深入學習linux, 分析了許多如行程排程、檔案系統的核心原始碼。對新技術也懷抱有很大的學習熱情,目前專註於docker和kubernetes。

本來呢,

可以滿足下大家的好奇心

給大家附一張作者的照片

但是

作者有點扭捏害羞了

於是小編我決定

給大家大概描述下我的這位師兄

(高能預警!前方靈魂畫手出沒)


哈哈哈我又來聊天氣了

這次還是帶著我平凡師兄

哦對了

我師兄聲音也是很好聽的

下方語音包,點選食用

聲音資源載入中…


我的上一篇部落格Docker底層的核心知識——namespace講解了核心中支援Docker作資源隔離的機制namespace。本篇文章主要講述Docker背後內核的另一機制——cgourps。cgroups不僅可以用來限制被namespace隔離的資源,還可以為資源設定權重、計算使用量、操控任務啟停等。

從Linux系統中看cgroups

 我們依然先從作業系統中直觀的看一下cgroups是個什麼東西

進入到sys/fs/cgroup/目錄下,我們可以看到許多目錄,如上圖所見。 
這些如blkio、cpu、cpuacct等目錄都是cgroups機制的子系統,子系統的概念一會再解釋。簡單來說,就是這些東西就是對cgroup做資源限制的。blkio負責為塊裝置設定輸入/輸出限制,比如物理驅動裝置——磁碟。cpu使用排程程式控制任務對cpu的使用,cpuacct自動生成cgroup中任務對CPU資源使用情況的報告。 
而正如我們所見,為了讓cgroups便於使用者理解和使用,也為了用精簡的核心程式碼為cgroup提供熟悉的許可權和名稱空間管理,核心開發者們按照Linux虛擬檔案系統轉換器介面實現了一套名為cgroup的檔案系統,非常巧妙地用來表示cgroups的層級概念,把各個子系統的實現都封裝到檔案系統的各項操作中。那麼,我們就可以像操作檔案一樣對cgroups的層級進行瀏覽和操作管理。除了cgroup檔案系統以外,核心沒有為cgroups的訪問和操作新增任何系統呼叫,這點與namespace不同,namespace都是透過系統呼叫來進行操作和管理的。

cgroups的由來

在作業系統中感受了cgroups,下麵我們來看看cgroups的由來。 
cgroups是由Google的工程師於2006年提出的,最初名為process container。為什麼叫這個名字呢?因為剛開始有cgroups的概念時,namespace其實是cgroups的一個子系統,也就是說,cgroups當時還具有資源隔離的功能。不過後來的發展將namespace獨立出去了。另外,由於container具有多重含義容易引起誤解,就在2007年更名為control groups,並整合進Linux核心,顧名思義就是把任務放到一個組裡面加以控制,這個組就是cgroup。

cgroups的官方定義

在這裡給出最嚴謹的官方定義: 
cgroups是Linux核心提供的一種機制,這種機制可以根據需求把一系列系統任務及其子任務整合(或分隔)到按資源劃分等級的不同組內,從而為系統資源管理提供一個統一的框架。

關於cgroups的術語

相信大家經常會聽人說cgroups或者cgroup。就比如我文章前面,一會提到cgroups,一會提到cgroup,這兩個術語之間有什麼區別呢?接下來列舉關於cgroups的幾個術語加以理解: 
cgroups:cgroups是Linux核心中的一個機制,我們用它來作容器資源的限制等功能。 
cgroup:cgroup中文叫做控制組。它是cgroups實現資源控制的一個基本單位。cgroup表示按某種資源控制標準劃分而成的一個任務組。它其中包含有一個或多個任務。 
task:前面介紹cgroup時提到的任務就是task。任務表示系統的一個行程或執行緒。之所以把行程和執行緒統稱為任務,是因為核心本身的排程和管理並沒有對行程和執行緒做區分,只根據clone建立時傳入引數的不同從概念上區別行程和執行緒,所以cgroups中簡化稱之。 
subsystem:cgroups中的子系統。一個子系統就是一個資源排程控制器。比如前面一開始讓大家看的cpu、memory、blkio、cpuacct等都是子系統。 
hierarchy:中文叫做層級。層級由一系列cgroup以一個樹狀結構排列而成。每個層級透過系結對應的子系統進行資源控制。前面一開始看到的目錄就是子系統,而這些子系統就掛載著層級。一個層級內建立一個目錄就類似於fork一個cgroup,這個cgroup繼承了父cgroup的配置屬性。當然,後面可以進行配置屬性的修改。 
語言敘述太蒼白,請看實際操作: 
我們進入cpu子系統的層級下,建立一個目錄cgroup1,這個cgroup1就是一個新建立的cgroup控制組,我們可以看下cgroup1中的內容。 

可以看到cgroup1目錄下直接有這麼多檔案,且和cpu目錄下本來存在的檔案相同。實際上就是cgroup1繼承了根cgroup的配置屬性。這個根cgroup是新建層級之時就有的。我們分別看一下兩個目錄下cpu.shares的值,會發現它們都是1024。 

cgroups的作用

我們上面說完了cgroups的一些術語。以後對cgroups的術語就不用傻傻分不清楚了。我們常說cgroups是做資源限制的,而cgroups的功能其實不單單是做資源限制的。接下來我們看一下cgroups具體能幹些什麼。 
cgroups為我們提供了四項功能: 
資源限制:cgroups可以對任務使用的資源總額進行限制。如cpu的使用,memory的使用。 
優先順序分配:透過分配的CPU時間片數量及磁碟IO頻寬大小,實際上就相當於控制了任務執行的優先順序。 
資源統計:cgroups可以統計系統的資源使用量,如CPU使用時長、記憶體用量等資訊,該功能可以用於資源使用的計費。 
任務控制:cgroups可以對任務執行掛起、恢復等操作。

子系統簡介

前面已經解釋過了什麼是子系統。這裡對子系統再進行詳細的講述,因為一個子系統就是一個資源控制器,每個子系統都獨立地控制一種資源。 
這是我們一開始就看到的圖片,接下來我們挑幾個重要的子系統再進行解釋: 
blkio:可以為塊裝置設定輸入/輸出限制,比如物理驅動裝置。 
cpu:使用排程程式控制任務對CPU的使用。 
cpuacct:自動生成cgroup中任務對CPU資源使用情況的報告。實際就是記錄CPU的使用情況。 
cpuset:可以為cgroup中的任務分配獨立的CPU和記憶體。當然,分配獨立的CPU的前提是節點是多處理器的。 
devices:可以開啟或關閉cgroup中任務對裝置的訪問。 
freezer:可以掛起或恢復cgroup中的任務。這就是cgroups的任務控制功能。 
memory:可以設定cgroup中任務對記憶體使用量的限定,並且自動生成這些任務對記憶體資源使用情況的報告。 
perf_event:使用後使cgroup中的任務可以進行統一的效能測試。 
net_cls:Docker沒有直接使用它,它透過使用等級識別符標記網路資料包,從而允許Linux流量控製程式識別從具體cgroup中生成的資料包。 
pids:用來限制cgroup中任務的數量。 

cproups超出限額的後果

我們都知道cgroup作為一個資源控制的基本單位。那麼,當cgroup使用的資源超出了分配的限額會有什麼後果呢? 
以記憶體為例,當行程所需的記憶體超過了它所屬的cgroup最大限額時,如果Linux設定了OOM,那麼行程會收到OOM訊號並結束;否則行程就會被掛起,進入睡眠狀態,直到cgroup中其他行程釋放了足夠的記憶體資源為止。Docker中是預設開啟OOM的。其他子系統的資源限制與此類似。

總結

cgroups相比於namespace解釋起來比較複雜,因為要做實際的演示比較難。最直觀的瞭解cgroups就是透過看cgroup檔案系統來感受它。(cd
/sys/fs/cgroup/
)除了cgroup檔案系統以外,核心沒有為cgroups的訪問和操作新增任何系統呼叫。雖然操作方式不同,cgroups和namespace一個做資源控制,一個做資源隔離。共同成為Docker背後的核心支援機制。

贊(0)

分享創造快樂