Docker核心原理解讀-cgroups

cgroups

1.control groups,能夠根據需求把一系列系統任務整合到按資源劃分等級的不一樣組裏(能夠限制、記錄任務組所使用的物理資源,CPU、Memory、IO等)。它不只能夠限制被namespace隔離起來的資源,還能夠爲資源設置權重、計算使用量、操控任務(進程或線程)啓停等。本質上來講,cgroups是內核附加在程序上的一系列鉤子,經過程序運行時對資源的調度觸發相應的鉤子以達到資源追蹤和限制的目的。

2.特色:
  • cgroup的api是以一個爲文件系統的方式實現,用戶態的程序能夠經過文件操做實現cgroup的組織管理
  • 組織管理操做單元能夠細粒度到線程級別,能夠建立和銷燬cgroup從而實現資源再分配和管理
  • 全部資源管理的功能都以子系統的方式實現,接口統一
  • 子任務建立之初與父任務處於同一個cgroups控制組

3.cgroups提供四大功能:
  • 資源限制(Resource Limitation):cgroups能夠對任務使用的資源總額進行限制。如設定應用運行時使用內存的上限,一旦超過這個配額就發出OOM(Out of Memory)。
  • 優先級分配(Prioritization):經過分配的CPU時間片數量及硬盤IO帶寬大小,實際上就至關於控制了進程運行的優先級。
  • 資源統計(Accounting): cgroups能夠統計系統的資源使用量,如CPU使用時長、內存用量等等,這個功能很是適用於計費。
  • 進程控制(Control):cgroups能夠對進程組執行掛起、恢復等操做。
4.cgroups術語表
  • task(任務):cgroups的術語中,task就表示系統的一個進程或線程。
  • cgroup(控制組):cgroups 中的資源控制都以cgroup爲單位實現。cgroup表示按某種資源控制標準劃分而成的任務組,包含一個或多個子系統。一個任務能夠加入某個cgroup,也能夠從某個cgroup遷移到另一個cgroup。
  • subsystem(子系統):cgroups中的subsystem就是一個資源調度控制器(Resource Controller)。好比CPU子系統能夠控制CPU時間分配,內存子系統能夠限制cgroup內存使用量。
  • hierarchy(層級樹):hierarchy由一系列cgroup以一個樹狀結構排列而成,每一個hierarchy經過綁定對應的subsystem進行資源調度。hierarchy中的cgroup節點能夠包含零或多個子節點,子節點繼承父節點的屬性。整個系統能夠有多個hierarchy。
5.cgroups、任務、子系統、層級之間的關係和基本規則:
  • 規則1:同一個層級能夠附加一個或多個子系統
  • 一個子系統能夠附加到多個層級,當且僅當目標層級只有惟一一個子系統時。圖中小圈中的數字表示子系統附加的時間順序,CPU子系統附加到層級A的同時不能再附加到層級B,由於層級B已經附加了內存子系統。
  • 系統每次新建一個層級時,該系統上的全部任務默認加入這個新建層級的初始化cgroup,這個sgroup也就是root cgroup。對於建立的每一個層級,任務只能存在於其中一個cgroup中任務只能存在於其中一個cgroup中,即一個任務不能存在於同一個層級的不一樣cgroup中,但一個任務能夠存在於不一樣層級中的多個cgroup中。若是操做時把一個任務添加到同一個層級的另外一個cgroup中,則會將它從第一個cgroup中移除。
  • 任務在fork/clone自身時建立的子任務默認與原任務在同一個cgroup中,可是子任務容許被移動到不一樣的cgroup中。即fork/clone完成後,父子任務間在cgroup方面是互不影響的。
6.子系統簡介
實際上就是cgroups的資源控制系統,每種子系統獨立的控制一種資源,目前Docker使用以下9種子系統,具體以下:
  • blkio:爲塊設備設定輸入/輸出限制,好比物理驅動設備(包括磁盤、固態硬盤、USB等)。
  • cpu:使用調度程序控制任務對CPU的使用。
  • cpuacct:自動生成cgroup中任務對CPU資源使用狀況的報告。
  • cpuset:能夠爲cgroup中的任務分配獨立的CPU和內存。
  • devices:能夠開啓或關閉cgroup中任務對設備的訪問。
  • freezer:能夠掛起或恢復cgroup中的任務。
  • memory:能夠設定cgroup中任務對內存使用量的限定,而且自動生成這些任務對內存資源使用狀況的報告。
  • perfevent:使用後使得cgroup中的任務能夠進行統一的性能測試。
  • net_cls:Docker沒有直接使用,它經過使用等級識別符(classid)標記網絡數據包,從而容許Linux流量控制程序(TC:Traffic Controller)識別從具體cgroup中生成的數據包。 
7.cgroups的實現本質上是給任務掛上鉤子,當任務運行的過程當中涉及某種資源時,就會觸發鉤子上所附帶的子系統進行檢測,而後根據資源類別的不一樣使用對應的技術進行資源限制和優先級分配。
  • 判斷資源超出限額:對於不一樣的系統資源,cgroups提供了統一的接口對資源進行控制和統計,但限制的具體方式則不盡相同。如memory子系統,會在描述內存狀態的「mm_struct」結構體中記錄它所屬的cgroup,當進程須要申請更多內存時,就會觸發cgroup用量檢測,用量超過cgroup規定的限額,則拒絕用戶的內存申請,不然就給予相應內存並在cgroup的統計信息中記錄。
  • 實現上,cgroup與任務之間是多對多的關係,所以它們並不直接關聯,而是經過一箇中間結構把雙向的關聯信息記錄起來。每一個任務結構體task_struct都包含了一個指針,能夠查詢到對應cgroup的狀況,同時也能夠查詢到各個子系統的狀態,這些子系統狀態中也包含了找到任務的指針,不一樣類型的子系統按需定義自己的控制信息結構體,最終在自定義的結構體中把子系統狀態指針包含進去,而後內核經過container_of等宏定義來獲取對應的結構體,關聯到任務,以此達到資源限制的目的。 
相關文章
相關標籤/搜索