Redhat 7 官方系統文檔和cgroup官方文檔

  1. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/7.4_release_notes/

以下是官方cgroup介紹






第 1 章 控制組羣(CGROUP)簡介

Red Hat Enterprise Linux 6 提供新的內核功能:控制族羣(control group),本手冊中使用其簡稱 cgroup。Cgroup 可讓您爲系統中所運行任務(進程)的用戶定義組羣分配資源 -- 比如 CPU 時間、系統內存、網絡帶寬或者這些資源的組合。您可以監控您配置的 cgroup,拒絕 cgroup 訪問某些資源,甚至在運行的系統中動態配置您的 cgroup。可將 cgconfig(“控制組羣配置 ”)服務配置爲在引導時啓動,並重新建立您預先定義的 cgroup,這樣可使其在重啓過程中保留它們。
使用 cgroup,系統管理員可更具體地控制對系統資源的分配、優先順序、拒絕、管理和監控。可更好地根據任務和用戶分配硬件資源,提高總體效率。
1.1. 如何管理控制組羣
Cgroup 是分層管理的,類似進程,且子 cgroup 會繼承其上級 cgroup 的一些屬性。但這兩個模式也有不同。
Linux 進程模式

Linux 系統中的所有進程都是通用父進程 init 的子進程,該進程在引導時由內核執行並啓動其它進程(這些進程會按順序啓動其子進程)。因爲所有進程都歸結到一個父進程,所以 Linux 進程模式是一個單一層級結構,或者樹結構。
另外,init 之外的每個 Linux 進程都會繼承其父進程的環境(比如 PATH 變量)[1]和某些屬性(比如打開文件描述符)。
Cgroup 模式

Cgroup 與進程在以下方面類似:
它們是分級的,且
子 cgroup 會集成其 cgroup 的某些屬性。
根本的不同是在某個系統中可同時存在不同的分級 cgroup。如果 Linux 進程模式是進程的單一樹模式,那麼 cgroup 模式是一個或者更多任務的獨立、未連接樹(例如:進程)。
需要多個獨立 cgroup 分級,因爲每個分級都會附加到一個或者多個子系統中。子系統[2]代表單一資源,比如 CPU 時間或者內存。Red Hat Enterprise Linux 6 提供 9 個 cgroup 子系統,根據名稱和功能列出如下。
Red Hat Enterprise Linux 中的可用子系統
blkio -- 這個子系統爲塊設備設定輸入/輸出限制,比如物理設備(磁盤,固態硬盤,USB 等等)。
cpu -- 這個子系統使用調度程序提供對 CPU 的 cgroup 任務訪問。
cpuacct -- 這個子系統自動生成 cgroup 中任務所使用的 CPU 報告。
cpuset -- 這個子系統爲 cgroup 中的任務分配獨立 CPU(在多核系統)和內存節點。
devices -- 這個子系統可允許或者拒絕 cgroup 中的任務訪問設備。
freezer -- 這個子系統掛起或者恢復 cgroup 中的任務。
memory -- 這個子系統設定 cgroup 中任務使用的內存限制,並自動生成由那些任務使用的內存資源報告。
net_cls -- 這個子系統使用等級識別符(classid)標記網絡數據包,可允許 Linux 流量控制程序(tc)識別從具體 cgroup 中生成的數據包。
ns -- 名稱空間子系統。
注意
您可能在 cgroup 文獻,比如 man page 或者內核文檔中看到術語資源控制器或者控制器。這兩個詞與 “subsystem(子系統)”的含義相同,且基於這樣的事實,即子系統通常調度資源或者在其所附屬層級的 cgroup 中應用限制。
子系統(資源控制器)的定義非常普通:它是根據一組任務行動的東西,例如進程。

1.2. 子系統、層級、控制組羣和任務的關係

請記住 cgroup 術語中系統進程稱爲任務。
這裏有一些簡單的規則管理子系統、cgroup 層級以及任務之間的關係,並給出那些規則的合理結果。
規則 1
任何單一子系統(比如 cpu)最多可附加到一個層級中。
結果是,cpu 子系統永遠無法附加到兩個不同的層級。
規則 2
單一層級可附加一個或者多個子系統。
結果是,cpu 和 memroy 子系統(或者任意數目的子系統)都可附加到單一層級中,只要每個子系統不再附加到另一個層級即可。
規則 3
每次在系統中創建新層級時,該系統中的所有任務都是那個層級的默認 cgroup(我們稱之爲 root cgroup)的初始成員。對於您創建的任何單一層級,該系統中的每個任務都可以是那個層級中唯一一個 cgroup 的成員。單一任務可以是在多個 cgroup 中,只要每個 cgroup 都在不同的層級中即可。只要某個任務成爲同一層級中第二個 cgroup 的成員,就會將其從那個層級的第一個 cgroup 中刪除。一個任務永遠不會同時位於同一層級的不同 cgroup 中。
結果是,如果 cpu 和 memory 子系統都附加到名爲 cpu_and_mem 的層級中,且 net_cls 子系統是附加到名爲 net 的層級中,那麼運行的 httpd 進程可以是 cpu_and_mem 中任意 cgroup 的成員,同時也是 net 中任意 cgroup 的成員。
httpd 進程所在 cpu_and_mem 中的 cgroup 可將其 CPU 時間限制爲分配給其它進程時間的一半,並將其內存用量限制爲最多 1024 MB。另外,net 中的 cgroup 還可將其傳輸速率限制爲 30 MB/秒。
首次創建層級時,該系統中的每個任務都至少是一個 cgroup 的成員,即 root cgroup。因此每當使用 cgroup 時,每個系統任務總是至少在一個 cgroup 中。
規則 4
該系統中的任意進程(任務)都將自己分支創建子進程(任務)。該子任務自動成爲其父進程所在 cgroup 的成員。然後可根據需要將該子任務移動到不同的 cgroup 中,但開始時它總是繼承其父任務的 cgroup(進程術語中稱其爲“環境”)。
cpu_and_mem 層級中名爲 half_cpu_1gb_max 的 cgroup 成員的任務,以及 net 層級中 cgroup trans_rate_30 的成員。當 httpd 進程將其自身分成幾個分支時,其子進程會自動成爲 half_cpu_1gb_max cgroup 和 trans_rate_30 cgroup 的成員。它會完全繼承其父任務所屬的同一 cgroup。
此後,父任務和子任務就彼此完全獨立:更改某個任務所屬 cgroup 不會影響到另一個。同樣更改父任務的 cgroup 也不會以任何方式影響其子任務。總之:所有子任務總是可繼承其父任務的同一 cgroup 的成員關係,但之後可更改或者刪除那些成員關係。

1.3. 資源管理實施

因爲某個任務可屬於任一層級中的單一 cgroup,所以只有一個方法可讓單一子系統限制或者影響任務。這是合理的:是一個功能,而不是限制。
您可以將幾個子系統分組在一起以便它們可影響單一層級中的所有任務。因爲該層級中的 cgroup 有不同的參數設定,因此會對那些任務產生不同的影響。
有時可能需要重構層級。例如:從附加了幾個子系統的層級中刪除一個子系統,並將其附加到不同的層級中。
反正,如果從不同層級中分離子系統的需求降低,則您可以刪除層級並將其子系統附加到現有層級中。
這個設計允許簡單的 cgroup 使用,比如爲單一層級中的具體任務設定幾個參數,單一層級可以是隻附加了 cpu 和 memeory 子系統的層級。
這個設計還允許高精度配置:系統中的每個任務(進程)都可以是每個層級的成員,每個層級都有單一附加的子系統。這樣的配置可讓系統管理員絕對控制每個單一任務的所有參數。

第 2 章 使用控制組羣

使用 cgroup 的最簡單的方法是安裝 libcgroup 軟件包,該軟件包包含大量與 cgroup 有關的命令行工具及其相關 man page。您可以使用 shell 命令和可在任意系統中使用的工具掛載層級並設定 cgroup 參數(不保留)。但是,使用 libcgroup 提供的工具可簡化過程並擴展功能。因此,本指南着重全面介紹 libcgroup 命令。在大多數情況下,我們會將對等的 shell 命令包括在內以便清楚闡述基礎機理。我們建議您在可行的情況下儘量使用 libcgroup 命令。
注意
要使用 cgroup,首先請確定在您的系統中安裝 libcgroup 軟件包,方法爲作爲 root 運行:
~]# yum install libcgroup
2.1. cgconfig 服務
由 libcgroup 軟件包安裝的 cgconfig 服務可提供創建層級的方便方法,並在層級中附加子系統,且在那些層級中管理 cgroup。我們建議您使用 cgconfig 在您的系統中管理層級和 cgroup。
紅帽企業版 Linux 6 不默認啓動 cgconfig 服務。當使用 chkconfig 啓動該服務時,它讀取 cgroup 配置文件 -- /etc/cgconfig.conf。Cgroup 因此會在不同會話間重新創建並保留。根據配置文件的內容,cgconfig 可創建層級、掛載所需文件系統、創建 cgroup 以及爲每個組羣設定子系統參數。
libcgroup 軟件包默認安裝的 /etc/cgconfig.conf 文件爲每個子系統創建並掛載獨立層級,並在這些層級中附加子系統。
如果您停止 cgconfig 服務(使用 service cgconfig stop 命令),則會卸載它掛載的所有層級。
2.1.1. cgconfig.conf 文件
cgconfig.conf 文件包含兩個主要類型的條目 -- mount 和 group。掛載條目生成並掛載層級並將其作爲虛擬文件系統,同時將子系統附加到那些層級中。掛載條目使用以下語法定義:
mount {
<controller> = <path>;

}
示例用法請參考 例 2.1 “創建掛載條目”。
例 2.1. 創建掛載條目
以下示例爲 cpuset 子系統創建層級:
mount {
cpuset = /cgroup/cpu;
}
對等的 shell 命令:
~]# mkdir /cgroup/cpu
~]# mount -t cgroup -o cpu cpu /cgroup/cpu
組羣條目創建 cgroup 並設定子系統參數。組羣條目使用以下語法定義:
group <name> {
[<permissions>]
<controller> {
<param name> = <param value>;

}

}
請注意 permissions 部分是可選的。要爲組羣條目定義權限,請使用以下語法:
perm {
task {
uid = <task user>;
gid = <task group>;
}
admin {
uid = <admin name>;
gid = <admin group>;
}
}
示例用法請參考 例 2.2 “創建組羣條目”:
例 2.2. 創建組羣條目
以下示例爲 sql 守護進程創建 cgroup,可爲 sqladmin 組羣中的用戶在 cgroup 中添加任務,並讓 root 用戶修改子系統參數:
group daemons/sql {
perm {
task {
uid = root;
gid = sqladmin;
} admin {
uid = root;
gid = root;
}
} cpu {
cpu.shares = 100;
}
}
當與 例 2.1 “創建掛載條目” 中的掛載條目示例合併時,對等的 shell 命令爲:
~]# mkdir -p /cgroup/cpu/daemons/sql
~]# chown root:root /cgroup/cpu/daemons/sql/*
~]# chown root:sqladmin /cgroup/cpu/daemons/sql/tasks
~]# echo 100 > /cgroup/cpu/daemons/sql/cpu.shares
注意
您必須重啓 cgconfig 服務方可使 /etc/cgconfig.conf 中的更改生效:
~]# service cgconfig restart
當安裝 cgroups 軟件包時,會在 /etc/cgconfig.conf 中寫入示例配置文件。每行開始的 #符號將該行註釋出來以便 cgconfig 服務忽略它。

2.2. 創建層級並附加子系統

警告
以下步驟覆蓋從創建新層級到在其中附加子系統到內容,這些步驟假設還沒有在您的系統中配置 cgroup。在這種情況下,這些步驟不會影響系統中的操作。更改有任務的 cgroup 中的可調參數可能會馬上影響那些任務。本指南提示您它首次演示更改會影響一個或者多個任務的可調 cgroup 參數。
在已經配置了 cgroup 的系統中(可以是手動配置,或者使用 cgconfig 服務配置),這些命令會失敗,除非您首先卸載可影響系統操作的現有層級。不要在產品系統中試驗這些步驟。
要創建層級並在其中附加子系統,請作爲 root 編輯 /etc/cgconfig.conf 文件的 mount 部分。mount 部分的條目有以下格式:
subsystem = /cgroup/hierarchy;
下一次啓動 cgconfig 時,它會創建層級併爲其附加子系統。
以下示例創建名爲 cpu_and_mem 的層級,並附加 cpu、cpuset、cpuacct 和 memory 子系統。
mount {
cpuset = /cgroup/cpu_and_mem;
cpu = /cgroup/cpu_and_mem;
cpuacct = /cgroup/cpu_and_mem;
memory = /cgroup/cpu_and_mem;
}
備用方法

您還可以使用 shell 命令和工具創建層級並在其中附加子系統。
作爲 root 爲該層級創建掛載點。在掛載點中包括 cgroup 名稱:
~]# mkdir /cgroup/name
例如:
~]# mkdir /cgroup/cpu_and_mem
下一步,請使用 mount 命令掛載該層級並同時附加一個或者多個系統。例如:
~]# mount -t cgroup -o subsystems name /cgroup/name
其中 subsystems 是使用逗號分開的子系統列表,name 是層級名稱。所有可用子系統的簡要論述請參考 Red Hat Enterprise Linux 中的可用子系統,第 3 章 子系統和可調參數 中有詳細的參考。
例 2.3. 使用 mount 命令附加子系統
在這個示例中,已經有名爲 /cgroup/cpu_and_mem 的目錄,它可以作爲我們所創建層級的掛載點服務。我們將在名爲 cpu_and_mem 的層級中附加 cpu、cpuset 和 memory 子系統,並在 /cgroup/cpu_and_mem 中 mount cpu_and_mem 層級:
~]# mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem
您可以使用 lssubsys [3]命令列出所有可用子系統及其當前掛載點(例如:掛載附加這些子系統的層級的位置)
~]# lssubsys -am
cpu,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
cpuacct
devices
freezer
blkio
這個輸出表示:
在掛載到 /cgroup/cpu_and_mem 的層級中附加子系統 cpu、cpuset 和 memory,且
還沒有在任何層級中附加子系統 net_cls、ns、cpuacct、devices、freezer 和 blkio,因缺少相應的掛載點。

[3] lssubsys 是 libcgroup 命令提供的工具之一。您必須安裝 libcgroup 方可使用這個工具:如果您無法運行 lssubsys,請參考 第 2 章 使用控制組羣。

2.3. 在現有層級中附加或者刪除子系統

要在現有層級中添加子系統,從現有層級中取消層級或者將其移動到不同的層級中,請作爲 root 編輯 /etc/cgconfig.conf 文件的 mount 部分,使用 第 2.2 節 “創建層級並附加子系統” 中所述的語法。當 cgconfig 下次啓動時,它會根據您指定的層級識別那些子系統。
備用方法

要在現有層級中取消附加子系統,請重新掛載該層級。請在 mount 命令中包括額外的子系統以及 remount 選項。
例 2.4. 重新掛載層級添加子系統
lssubsys 命令顯示在 cpu_and_mem 層級中附加 cpu、cpuset 和 memory 子系統:
~]# lssubsys -am
cpu,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
cpuacct
devices
freezer
blkio
我們使用 remount 選項重新掛載 cpu_and_mem 層級,並在子系統列表中包含 cpuacct:
~]# mount -t cgroup -o remount,cpu,cpuset,cpuacct,memory cpu_and_mem /cgroup/cpu_and_mem
lssubsys 命令現在顯示附加到 cpu_and_mem 層級中的 cpuacct:
~]# lssubsys -am
cpu,cpuacct,cpuset,memory /cgroup/cpu_and_mem
net_cls
ns
devices
freezer
blkio
同樣,您可以重新掛載該層級並使用 -o 選項忽略子系統名稱從現有層級中分離子系統。例如:要分離 cpuacct 子系統,只要您重新掛載並忽略它即可:
~]# mount -t cgroup -o remount,cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem

2.4. 卸載層級

您還可以使用 umount 命令卸載 cgroup 中的層級:
~]# umount /cgroup/name
例如:
~]# umount /cgroup/cpu_and_mem
如果該層級目前爲空(即它只包含 root cgroup),則在卸載它時會取消激活該層級。如果該層級包含任意其他 cgroup,該層級在內核中仍保持活躍,即使不再掛載它也是如此。
要刪除層級,請確定您在卸載該層級前刪除所有子 cgroup ,或者使用 cgclear 命令,它可在層級非空時也可取消激活層級 -- 請參考 第 2.11 節 “卸載控制組羣”。

2.5. 創建控制組羣

請使用 cgcreate 命令創建 cgroup。cgcreate 的語法爲:cgcreate -t uid:gid -auid:gid -g subsystems:path ,其中:
-t(可選)- 指定用戶(使用用戶 ID,uid)和組羣(使用組羣 ID,gid)以便讓這個 cgroup 擁有 tasks 僞文件。這個用戶可在該 cgroup 中添加任務。
注意

請注意:從 cgroup 中刪除任務的唯一方法是將其移動到不同的 cgroup中。要移動任務,該用戶必須有目的 cgroup 的寫訪問。對源 cgroup 的寫訪問並不重要。
-a(可選)- 指定用戶(使用用戶 ID,uid)和組羣(使用組羣 ID,gid)以便這個 cgroup 擁有 tasks 外的所有僞文件。這個用戶可修改這個 cgroup 中的任務對系統資源的訪問。
-g -- 指定在其中創建 cgroup 的層級,格式爲與那些層級關聯的用逗號分開的 subsystems 列表。如果這個列表中的子系統在不同的層級中,則要在每個層級中都創建該組羣。層級列表後是一個冒號,然後是與該層級有關的子組羣 path。不要在該 path 中包含層級掛載點。
例如:目錄 /cgroup/cpu_and_mem/lab1/ 中的 cgroup 稱爲 lab1 -- 其路徑已唯一確定,因爲對於給定的子系統最多有一個層級。還請注意該組羣可由創建該 cgroup 的現有層級中的所有子系統控制,即使沒有在 cgcreate 命令中指定這些子系統 -- 請參考 例 2.5 “cgcreate 用法”。
因爲同一層級中的所有 cgroup 有相同的控制器,該子組羣與其父 cgroup 有相同的控制器。
例 2.5. cgcreate 用法
請考慮在 cpu_and_mem 層級中一同掛載 cpu 和 memory 子系統的系統,並將 net_cls 控制器掛載到名爲 net 的另一個層級中。我們現在運行:
~]# cgcreate -g cpu,net_cls:/test-subgroup
cgcreate 命令創建兩個組羣,名爲 test-subgroup,一個位於 cpu_and_mem 層級,一個位於 net 層級。cpu_and_mem 層級中的 test-subgroup 組羣由 memory 子系統控制,即使在 cgcreate 命令中沒有指定它也是如此。
備用方法

請使用 mkdir 命令直接創建 cgroup 的子組羣:
~]# mkdir /cgroup/hierarchy/name/child_name
例如:
~]# mkdir /cgroup/cpuset/lab1/group1

2.6. 刪除控制組羣

使用 cgdelete 刪除 cgroup,其語法與 cgcreate 類似。運行 cgdelete subsystems:path,其中:
subsystems 是用逗號分開的子系統列表。
path 是到與該層級相對 root 的 cgroup 的路徑。
例如:
~]# cgdelete cpu,net_cls:/test-subgroup
cgdelete 還可使用 -r 選項遞歸刪除所有子組羣。
刪除 cgroup 時,將其所有任務都移動到它的父組羣中。

2.7. 設置參數

在可修改相關的 cgroup 的用戶帳戶中運行 cgset 命令設定子系統參數。例如:如果有 /cgroup/cpuset/group1,則請使用以下命令指定這個組羣可訪問的 CPU:
cpuset]# cgset -r cpuset.cpus=0-1 group1
cgset 的語法爲:cgset -r parameter=value path_to_cgroup ,其中:
parameter 是要設定的參數,該參數與給定 cgroup 的目錄中的文件對應。
value 是爲參數設定的值
path_to_cgroup 是到相對該層級 root 的 cgroup 路徑。例如:如果設定 root 組羣的參數(如有 /cgroup/cpuacct/ 文件),請運行:
cpuacct]# cgset -r cpuacct.usage=0 /
另外,因爲 . 與 root 組羣相關(即 root 組羣本身),您還可運行:
cpuacct]# cgset -r cpuacct.usage=0 .
備註:/ 是首選語法。
注意

只能爲該 root 組羣設定少量參數(比如上面的示例中演示的 cpuacct.usage 參數)。這是因爲 root 組羣擁有所有現有資源,因此定義某些參數限制現有進程就沒有任何意義,例如 cpuset.cpu 參數。

要設定 root 組羣的子組羣 group1 參數,請運行:
cpuacct]# cgset -r cpuacct.usage=0 group1
該組羣名稱結尾的斜槓(例如:cpuacct.usage=0 group1/)是可選的。
您可以使用 cgset 設定的值可能取決於在具體層級中設定的較大的值。例如:如果將 group1 限制爲只能使用系統中的 CPU 0,則您無法將 group1/subgroup1 設定爲使用 CPUs 0 和 1,或者只使用 CPU 1。
您還可以使用 cgset 將一個 cgroup 中的參數複製到另一個現有 cgroup 中,例如:
~]# cgset --copy-from group1/ group2/
使用 cgset 複製參數的語法爲:cgset --copy-from path_to_source_cgrouppath_to_target_cgroup,其中:
path_to_source_cgroup 是相對該層級中 root 組羣,到要複製其參數的 cgroup 的路徑。
path_to_target_cgroup 是相對該層級 root 組羣的目的 cgroup 的路徑。
請確定您在從一個組羣將參數複製到另一個組羣前爲不同子系統設定強制參數,否則命令會失敗。有關強制參數的詳情請參考 重要 - 強制參數。
備用方法

要直接在 cgroup 中設置參數,請使用 echo 命令將值插入相關子系統僞文件。例如:這個命令可將值 0-1 插入 cgroup group1 的 cpuset.cpus 僞文件中:
~]# echo 0-1 > /cgroup/cpuset/group1/cpuset.cpus
在此設定這個值,則這個 cgroup 中的任務就限制在該系統的 CPU 0 和 1 中。

2.8. 將某個進程移動到控制組羣中

您還可以運行 cgclassify 命令將進程移動到 cgroup 中:
~]# cgclassify -g cpu,memory:group1 1701
cgclassify 的語法爲:cgclassify -g subsystems:path_to_cgroup pidlist,其中:
subsystems 是用逗號分開的子系統列表,或者 * 啓動與所有可用子系統關聯的層級中的進程。請注意:如果在多個層級中有同名的 cgroup,則 -g 選項會將該進程移動到每個組羣中。請確定在擁有您在此指定子系統的每個層級中都有該 cgroup。
path_to_cgroup 是到其層級中的 cgroup 的路徑
pidlist 是用空格分開的進程識別符(PID)列表
您還可以在 pid 前面添加 -- sticky 選項以保證所有子進程位於同一 cgroup 中。如果您沒有設定這個選項且 cgred 守護進程正在運行,則會根據 /etc/cgrules.conf 中的設置將子進程分配到 cgroup 中。該進程本身則仍保留在啓動它的 cgroup 中。
使用 cgclassify,您可以同時移動多個進程。例如:這個命令將 PID 爲 1701 和 1138 的進程移動到 cgroup 中的 group1/:
~]# cgclassify -g cpu,memory:group1 1701 1138
請注意要移動的 PID 間要用空格分開,且應該在不同的層級中指定這些組羣。
備用方法

要將進程直接移動到 cgroup 中,請將其 PID 寫入該 cgroup 中的 tasks 文件中。例如:要將 PID 爲 1701 的進程移動到位於 /cgroup/lab1/group1/ 的 cgroup 中:
~]# echo 1701 > /cgroup/lab1/group1/tasks
2.8.1. cgred 守護進程
Cgred 是一個守護進程,它可根據在 /etc/cgrules.conf 文件中設定的參數將任務移動到 cgroup 中。/etc/cgrules.conf 文件中的條目可以使用以下兩個格式之一:
user hierarchies control_group
user:command hierarchies control_group
例如:
maria devices /usergroup/staff
這個條目指定任何屬於名爲 maria 用戶的進程根據在 /usergroup/staff cgroup 中指定的參數訪問設備子系統。要將具體命令與具體 cgroup 關聯,請添加 command 參數,如下:
maria:ftp devices /usergroup/staff/ftp
該條目現在指定何時名爲 maria 的用戶使用 ftp 命令,自動將該進程移動到包含 devices子系統的層級中的 /usergroup/staff/ftp cgroup 中。請注意:該守護進程只有在符合適當的條件後纔可將該進程移動到該 cgroup 中。因此,ftp 可能會在錯誤的組羣中短暫運行。再有,如果該進程在錯誤組羣中迅速生出子進程,則不會移動這些子進程。
/etc/cgrules.conf 文件中的條目可包括以下額外符號:
@ - 當在 user 使用前綴時,代表是一個組羣而不是單獨用戶。例如:@admins 是 admins 組羣中的所有用戶。

    • 代表“所有”。例如:subsystem 字段中的 * 代表所有子系統。
      % - 代表與以上行中項目相同的項目。例如:
      @adminstaff devices /admingroup
      @labstaff % %

2.9. 在控制組羣中啓動一個進程

重要

有些子系統擁有強制參數,您在可以將任務移動到使用那些子系統的 cgroup 前必須設定這些參數。例如:在您將任務移動到使用 cpuset 子系統的 cgroup 前,必須爲那個 cgroup 定義 cpuset.cpus 和 cpuset.mems 參數。
本章的示例演示了命令的正確語法,但只適用於在此示例中爲所有控制器設定了相關強制參數的系統。如果您還沒有配置相關控制器,您就無法直接將本章中的命令示例直接用於您的系統。
給定子系統的強制參數的描述請參考 第 3.10 節 “附加資源”。

您還可以運行 cgexec 命令在 cgroup 中啓動進程。例如:這個命令啓動了 group1 cgroup 中的 lynx 網頁瀏覽器,目的是限制 cpu 子系統爲那個組羣造成的負擔。
~]# cgexec -g cpu:group1 lynx http://www.redhat.com
cgexec 語法爲:cgexec -g subsystems:path_to_cgroup command arguments ,其中:
subsystems 是用逗號分開的子系統列表或者 * 啓動與所有可用子系統關聯的層級中的進程。請注意:如 第 2.7 節 “設置參數” 所述的 cgset,如果在多個層級中有同名的 cgroup,-g 選項會在每個組羣中創建進程。請確定您在擁有在此指定的子系統的層級中都有該 cgroup。
path_to_cgroup 是到與該層級相關的 cgroup 的路徑。
command 是要運行的命令
arguments 是該命令所有參數

您還可以在 command 前面添加 -- sticky 將所有子進程放在同一 cgroup 中。如果您沒有設定這個選項,且 cgred 守護進程正在運行,則將根據在 /etc/cgrules.conf 中的設置將子進程分配到 cgroup 中。而該進程本身仍保留在啓動它的 cgroup 中。
備用方法
當您啓動新進程時,它會繼承其父進程的組羣。因此在具體 cgroup 中啓動進程的備選方法是將您的 shell 進程移動到那個組羣中(請參考 第 2.8 節 “將某個進程移動到控制組羣中”),然後在那個 shell 中啓動該進程。例如:
~]# echo $$ > /cgroup/lab1/group1/taskslynx
請注意:退出 lynx 後,您現有 shell 中仍在 group1 cgroup 中。因此更好的方法應爲:
~]# sh -c "echo \$$ > /cgroup/lab1/group1/tasks && lynx"
2.9.1. 在控制組羣中啓動服務
您可在某個 cgroup 中啓動某些服務。在 cgroup 中啓動的服務必須:
使用 /etc/sysconfig/servicename 文件
使用 /etc/init.d/functions 的 daemon() 功能啓動該服務
要在某個 cgroup 中啓動合格服務,請在 /etc/sysconfig 中編輯其文件,使該文件包含格式如下的條目:CGROUP_DAEMON="subsystem:control_group",其中 subsystem 是與具體層級關聯的子進程,control_group 是那個層級中的 cgroup。例如:
CGROUP_DAEMON="cpuset:daemons/sql"

2.10. 獲得有關控制組羣的信息

2.10.1. 查找某個進程
要查找某個進程所屬 cgroup,請運行:
~]$ ps -O cgroup
或者如果您知道該進程的 PID,請運行:
~]$ cat /proc/PID/cgroup

2.10.2. 查找子系統

要查找可在您內核中使用的子系統以及如何將其掛載到層級中,請運行:
~]$ cat /proc/cgroups
或者查找具體子系統的掛載點,請運行:
~]$ lssubsys -m subsystems
其中 subsystems 是您感興趣的子系統列表。請注意:lssubsys -m 命令只返回每個層級的頂級掛載點。

2.10.3. 查找層級

我們建議您在 /cgroup 掛載層級。假設在您的系統中是這種情況,列出或者瀏覽包含層級組羣的目錄中的內容。如果在您的系統中安裝了 tree,運行該程序獲得所有層級概述以及其中的 cgroup:
~]$ tree /cgroup/

2.10.4. 查找控制組羣

要查找某個系統的 cgroup,請運行:
~]$ lscgroup
您可以指定控制程序和路徑限制具體層級的輸出,格式爲 controller:path。例如:
~]$ lscgroup cpuset:adminusers
只列出附加 cpuset 子系統的層級中的 adminusers cgroup 的子組羣。

2.10.5. 顯示控制組羣的參數

要顯示具體 cgroup 的參數,請運行:
~]$ cgget -r parameter list_of_cgroups
其中 parameter 是包含子系統值的僞文件,list_of_cgroups 是用空格分開的 cgroup 列表。例如:
~]$ cgget -r cpuset.cpus -r memory.limit_in_bytes lab1 lab2
顯示 cgroup lab1 和 lab2 的 cpuset.cpus 和 memory.limit_in_bytes 值。
如果您不知道參數名稱,請使用類似命令:
~]$ cgget -g cpuset /

2.11. 卸載控制組羣

警告
cgclear 目錄將破壞所有層級中的所有 cgroup。如果您沒有在配置文件中保存這些層級,則您無法再次構建它們。
要清除整個 cgroup 文件系統,請使用 cgclear 命令。
將該 cgroup 中的所有任務重新分配到該層級的 root 節點中;刪除所有 cgroup;從該系統中卸載這個文件系統;這樣就破壞了所有之前掛載的層級。最後,實際上是刪除了掛載該 cgroup 文件系統的目錄。
注意
使用 mount 命令創建 cgroup(與使用 cgconfig 服務創建它們相反),結果是在 /etc/mtab 文件(掛載的文件系統表)中生成一個條目。這個更改還在 /proc/mounts 有所體現。但是使用 cgclear 命令卸載 cgroup,與 cgconfig 命令一同使用直接內核界面則不會在 /etc/mtab 文件中有所體現,而只是在 /proc/mounts 文件中寫入新信息。因此使用 cgclear 命令卸載 cgroup 仍可在 /etc/mtab 文件中看出來,且在隨後執行 mount 命令時顯示。所有掛載 cgroup 的準確列表,建議您參考 /proc/mounts 文件。

2.12. 附加資源

cgroup 命令最權威的文檔是 libcgroup 軟件包提供的手冊頁。這部分的數字在以下 man page 列表中指定。
libcgroup Man Page
man 1 cgclassify -- cgclassify 命令是用來將運行的任務移動到一個或者多個 cgroup。
man 1 cgclear -- cgclear 命令是用來刪除層級中的所有 cgroup。
man 5 cgconfig.conf -- 在 cgconfig.conf 文件中定義 cgroup。
man 8 cgconfigparser -- cgconfigparser 命令解析 cgconfig.conf 文件和並掛載層級。
man 1 cgcreate -- cgcreate 在層級中創建新 cgroup。
man 1 cgdelete -- cgdelete 命令刪除指定的 cgroup。
man 1 cgexec -- cgexec 命令在指定的 cgroup 中運行任務。
man 1 cgget -- cgget 命令顯示 cgroup 參數。
man 5 cgred.conf -- cgred.conf 是 cgred 服務的配置文件。
man 5 cgrules.conf -- cgrules.conf 包含用來決定何時任務術語某些 cgroup 的規則。
man 8 cgrulesengd -- cgrulesengd 在 cgroup 中發佈任務。
man 1 cgset -- cgset 命令爲 cgroup 設定參數。
man 1 lscgroup -- lscgroup 命令列出層級中的 cgroup。
man 1 lssubsys -- lssubsys 命令列出包含指定子系統的層級。

第 3 章 子系統和可調參數

子系統是識別 cgroup 的內核模塊。通常它們是爲不同 cgroup 分配各種系統登記的資源控制器。但是可爲其它與內核的互動編輯子系統,這些互動需要以不同方式對待不同的進程組羣。開發新子系統的應用程序編程界面(API)文檔位於內核文件的 cgroups.txt 中,該文件安裝在您系統的 /usr/share/doc/kernel-doc-kernel-version/Documentation/cgroups/(由 kernel-doc 軟件包提供)。cgroup 文檔的最新版本還可在 http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt 中找到。請注意:最新文檔中的功能可能不與您系統中安裝的內核匹配。
用於 cgroup 的包含子系統參數的狀態對象在 cgroup 的虛擬文件系統中是以僞文件出現。這些僞文件可由 shell 命令或者與其對等的系統調用操作。例如:cpuset.cpus 是用來指定可允許 cgroup 訪問哪些 CPU。如果 /cgroup/cpuset/webserver 是用於系統中運行的網頁服務器的 cgroup,則我們會運行以下命令:
~]# echo 0,2 > /cgroup/cpuset/webserver/cpuset.cpus
將值 0,2 寫入 cpuset.cpus 僞文件,並因此將 PID 爲列在 /cgroup/cpuset/webserver/tasks/ 中的任務限制爲只使用系統中的 CPU 0 和 CPU 2。
3.1. blkio
塊 I/O(blkio)子系統控制並監控 cgroup 中的任務對塊設備的 I/O 訪問。在部分這樣的僞文件中寫入值可限制訪問或者帶寬,且從這些僞文件中讀取值可提供 I/O 操作信息。
blkio.weight
指定 cgroup 默認可用訪問塊 I/O 的相對比例(加權),範圍在 100 到 1000。這個值可由具體設備的 blkio.weight_device 參數覆蓋。例如:如果將 cgroup 訪問塊設備的默認加權設定爲 500,請運行:
echo 500 > blkio.weight
blkio.weight_device
指定對 cgroup 中可用的具體設備 I/O 訪問的相對比例(加權),範圍是 100 到 1000。這個值可由爲設備指定的 blkio.weight 參數覆蓋。這個值的格式爲major:minor weight,其中 major 和 minor 是在《Linux 分配的設備》中指定的設備類型和節點數,我們也稱之爲 Linux 設備列表,您可以參考 http://www.kernel.org/doc/Documentation/devices.txt。例如:如果爲訪問 /dev/sda 的 cgroup 分配加權 500,請運行:
echo 8:0 500 > blkio.weight_device
在《Linux 分配的設備》註釋中,8:0 代表 /dev/sda。
blkio.time
報告 cgroup 對具體設備的 I/O 訪問時間。條目有三個字段:major、minor 和 time。Major 和 minor 是在 Linux 分配的設備中指定的設備類型和節點數,time 是時間長度,單位爲毫秒(ms)。
blkio.sectors
報告使用 cgroup 轉換到具體設備或者由具體設備轉換出的扇區數。條目有三個字段:major、minor 和 sectors。major、minor 是在 Linux 分配的設備中指定的設備類型和節點數,sectors 是磁盤扇區數。
blkio.io_service_bytes
報告使用 cgroup 轉換到具體設備或者由具體設備中轉換出的字節數。條目有四個字段:major、minor、operation 和 bytes。Major 和 minor 是在 Linux 分配的設備中指定的設備類型和節點數,operation 代表操作類型(read、write、sync 或者 async),bytes 是轉換的字節數。
blkio.io_serviced
報告使用 cgroup 在具體設備中執行的 I/O 操作數。條目有四個字段:major、minor、operation 和 number。Major 和 minor 是在 Linux 分配的設備中指定的設備類型和節點數,operation 代表操作類型(read、write、sync 或者 async),number 代表操作數。
blkio.io_service_time
報告使用 cgroup 在具體設備中的 I/O 操作請求發送和請求完成之間的時間。條目有四個字段:major、minor、operation 和 time。Major 和 minor 是在 Linux 分配的設備中指定的設備類型和節點數,operation 代表操作類型(read、write、sync 或者 async),time 是時間長度,單位爲納秒(ns)。使用納秒爲單位報告而不是較大的單位是要使報告即使對固態設備也是有意義的。
blkio.io_wait_time
報告在具體設備中 cgroup 爲調度程序隊列中等待的 I/O 操作時間總計。當您解讀這個報告時,請注意:
報告的時間可以比消耗的時間更長,因爲報告的時間是該 cgroup 所有 I/O 操作的總和,而不是該 cgroup 本身等待 I/O 操作的時間。要查找該組羣作爲整體而消耗的等待時間,請使用 blkio.group_wait_time。
如果該設備有 queue_depth > 1,則報告的時間只包括向該設備發送請求之前的時間,而不包括在該設備重新提出請求時等待服務的任何時間。
條目有四個字段:major、minor、operation 和 bytes。Major 和 minor 是在《Linux 分配的設備》中指定的設備類型和節點數,operation 代表操作類型(read、write、sync 或者 async),time 是時間長度,單位爲納秒(ns)。使用納秒報告而不是更大的單位可讓這個報告對固態設備也有意義。
blkio.io_merged
報告使用 cgroup 將 BIOS 請求合併到 I/O 操作請求的次數。條目有兩個字段:number 和 operation。Number 是請求次數,operation 代表操作類型(read、write、sync 或者 async)。
blkio.io_queued
報告 cgroup 爲 I/O 操作排隊的請求次數。條目有兩個字段:number 和 operation。Number 是請求次數,operation 代表操作類型(read、write、sync 或者 async)。
blkio.avg_queue_size
報告在該組羣存在的整個過程中,cgroup 的 I/O 操作的平均隊列大小。每次這個 cgroup 獲得一個時間單位時都對該隊列大小進行採樣。請注意這個報告只有在將系統設定爲 CONFIG_DEBUG_BLK_CGROUP=y 時可用。
blkio.group_wait_time
報告 cgroup 等待每個隊列的時間總計(單位爲納秒 -- ns)。每次這個 cgroup 的隊列獲得一個時間單位時就會更新這個報告,因此如果您在 cgroup 等待時間單位時讀取這個僞文件,則該報告將不會包含等待當前隊列中的操作的時間。請注意這個報告只有在將系統設定爲 CONFIG_DEBUG_BLK_CGROUP=y 時可用。
blkio.empty_time
報告 cgroup 在沒有任何等待處理請求時花費的時間總計(單位爲納秒 -- ns)。每次這個 cgroup 有等待處理請求時都會更新這個報告,因此如果您在 cgroup 沒有任何等待處理請求是讀取這個僞文件,則該報告中不會包含消耗在當前空狀態中的時間。請注意這個報告只有在將該系統設定爲 CONFIG_DEBUG_BLK_CGROUP=y 時可用。
blkio.idle_time
報告調度程序在 cgroup 等待比已經在其它隊列或者來自其它組羣請求更好的請求時顯示閒置的時間總計(單位爲納秒 -- ns)。每次該組羣不顯示閒置時就會更新這個報告,因此如果您在 cgroup 閒置時讀取這個僞文件,則該報告將不會包括消耗在當前閒置狀態的時間。請注意,只有在將系統設定爲 CONFIG_DEBUG_BLK_CGROUP=y 時這個報告纔可用。
blkio.dequeue
報告 cgroup 的 I/O 操作請求被具體設備從隊列中移除的次數。條目有三個字段:major、minor 和 number。major 和 minor 是在 Linux 分配的設備中指定的設備類型和節點數,number 是將該組羣從隊列中移除的次數。請注意這個報告只有在將系統設定爲 CONFIG_DEBUG_BLK_CGROUP=y 時可用。
blkio.reset_stats
重新設定在其它僞文件中記錄的統計數據。在這個文件中寫入一個整數爲這個 cgroup 重新設定統計數據。

3.2. CPU

cpu 子系統調度對 cgroup 的 CPU 訪問。可根據以下參數調度對 CPU 資源的訪問,每個參數都獨立存在於 cgroup 虛擬文件系統的僞文件中:
cpu.shares
包含用來指定在 cgroup 中的任務可用的相對共享 CPU 時間的整數值。例如:在兩個 cgroup 中都將 cpu.shares 設定爲 1 的任務將有相同的 CPU 時間,但在 cgroup 中將 cpu.shares 設定爲 2 的任務可使用的 CPU 時間是在 cgroup 中將 cpu.shares 設定爲 1的任務可使用的 CPU 時間的兩倍。
cpu.rt_runtime_us
以微秒(µs,這裏以“us”代表)爲單位指定在某個時間段中 cgroup 中的任務對 CPU 資源的最長連續訪問時間。建立這個限制是爲了防止一個 cgroup 中的任務獨佔 CPU 時間。如果 cgroup 中的任務應該可以每 5 秒中可有 4 秒時間訪問 CPU 資源,請將 cpu.rt_runtime_us 設定爲 4000000,並將 cpu.rt_period_us 設定爲 5000000。
cpu.rt_period_us
以微秒(µs,這裏以“us”代表)爲單位指定在某個時間段中 cgroup 對 CPU 資源訪問重新分配的頻率。如果某個 cgroup 中的任務應該每 5 秒鐘有 4 秒時間可訪問 CPU 資源,則請將 cpu.rt_runtime_us 設定爲 4000000,並將 cpu.rt_period_us 設定爲 5000000。

3.3. CPUACCT

CPU Accounting(cpuacct)子系統自動生成 cgroup 中任務所使用的 CPU 資源報告,其中包括子組羣中的任務。三個可用報告爲:
cpuacct.stat
報告這個 cgroup 及其子組羣中的任務使用用戶模式和系統(內核)模式消耗的 CPU 循環數(單位由系統中的 USER_HZ 定義)。
cpuacct.usage
報告這個 cgroup 中所有任務(包括層級中的低端任務)消耗的總 CPU 時間(納秒)。
cpuacct.usage_percpu
報告這個 cgroup 中所有任務(包括層級中的低端任務)在每個 CPU 中消耗的 CPU 時間(以納秒爲單位)。

3.4. CPUSET
cpuset 子系統爲 cgroup 分配獨立 CPU 和內存節點。可根據用以下參數指定每個 cpuset,每個參數都在控制組羣虛擬文件系統中有單獨的僞文件:
重要
有些子系統擁有強制參數,您在可以將任務移動到使用那些子系統的 cgroup 前必須設定這些參數。例如:在您將任務移動到使用 cpuset 子系統的 cgroup 前,必須爲那個 cgroup 定義 cpuset.cpus 和 cpuset.mems 參數。
cpuset.cpus(強制)
指定允許這個 cgroup 中任務訪問的 CPU。這是一個用逗號分開的列表,格式爲 ASCII,使用小橫線("-")代表範圍。例如:
0-2,16
代表 CPU 0、1、2 和 16。
cpuset.mems(強制)
指定允許這個 cgroup 中任務可訪問的內存節點。這是一個用逗號分開的列表,格式爲 ASCII,使用小橫線("-")代表範圍。例如:
0-2,16
代表內存節點 0、1、2 和 16。
cpuset.memory_migrate
包含用來指定當 cpuset.mems 中的值更改時是否應該將內存中的頁遷移到新節點的標籤(0 或者 1)。默認情況下禁止內存遷移(0)且頁就保留在原來分配的節點中,即使在 cpuset.mems 中現已不再指定這個節點。如果啓用(1),則該系統會將頁遷移到由 cpuset.mems 指定的新參數中的內存節點中,可能的情況下保留其相對位置 - 例如:原來由 cpuset.mems 指定的列表中第二個節點中的頁將會重新分配給現在由 cpuset.mems 指定的列表的第二個節點中,如果這個位置是可用的。
cpuset.cpu_exclusive
包含指定是否其它 cpuset 及其上、下級族羣可共享爲這個 cpuset 指定的 CPU 的標籤(0或者 1)。默認情況下(0)CPU 不是專門分配給某個 cpuset 的。
cpuset.mem_exclusive
包含指定是否其它 cpuset 可共享爲這個 cpuset 指定的內存節點的標籤(0 或者 1)。默認情況下(0)內存節點不是專門分配給某個 cpuset 的。專門爲某個 cpuset 保留內存節點(1)與使用 cpuset.mem_hardwall 啓用內存 hardwall 功能是一致的。
cpuset.mem_hardwall
包含指定是否應將內存頁面的內核分配限制在爲這個 cpuset 指定的內存節點的標籤(0 或者 1)。默認情況下爲 0,屬於多個用戶的進程共享頁面和緩衝。啓用 hardwall 時(1)每個任務的用戶分配應保持獨立。
cpuset.memory_pressure
包含運行在這個 cpuset 中產生的平均內存壓力的只讀文件。啓用 cpuset.memory_pressure_enabled 時,這個僞文件中的值會自動更新,否則僞文件包含的值爲 0。
cpuset.memory_pressure_enabled
包含指定系統是否應該計算這個 cgroup 中進程所生成內存壓力的標籤(0 或者 1)。計算出的值會輸出到 cpuset.memory_pressure,且代表進程試圖釋放使用中內存的比例,報告爲嘗試每秒再生內存的整數值再乘 1000。
cpuset.memory_spread_page
包含指定是否應將文件系統緩衝平均分配給這個 cpuset 的內存節點的標籤(0 或者 1)。默認情況爲 0,不嘗試爲這些緩衝平均分配內存頁面,且將緩衝放置在運行生成緩衝的進程的同一節點中。
cpuset.memory_spread_slab
包含指定是否應在 cpuset 間平均分配用於文件輸入/輸出操作的內核緩存板的標籤(0 或者 1)。默認情況是 0,即不嘗試平均分配內核緩存板,並將緩存板放在生成這些緩存的進程所運行的同一節點中。
cpuset.sched_load_balance
包含指定是否在這個 cpuset 中跨 CPU 平衡負載內核的標籤(0 或者 1)。默認情況是 1,即內核將超載 CPU 中的進程移動到負載較低的 CPU 中以便平衡負載。
請注意:如果在任意上級 cgroup 中啓用負載平衡,則在 cgroup 中設定這個標籤沒有任何效果,因爲已經在較高一級 cgroup 中處理了負載平衡。因此,要在 cgroup 中禁用負載平衡,還要在該層級的每一個上級 cgroup 中禁用負載平衡。這裏您還應該考慮是否應在所有平級 cgroup 中啓用負載平衡。
cpuset.sched_relax_domain_level
包含 -1 到小正數間的整數,它代表內核應嘗試平衡負載的 CPU 寬度範圍。如果禁用了 cpuset.sched_load_balance,則該值毫無意義。
根據不同系統構架這個值的具體效果不同,但以下值是常用的:
cpuset.sched_relax_domain_level 值

效果
-1
爲負載平衡使用系統默認值
0
不執行直接負載平衡;負載平衡只是階段性的
1
在同一核中的跨線程直接負載平衡
2
在同一軟件包中的跨線程直接負載平衡
3
在同一節點或者刀片中的跨線程直接負載平衡
4
在不使用統一內存訪問(NUMA)構架中跨多個 CPU 的直接負載平衡
5
在使用統一內存訪問(NUMA)構架中跨多個 CPU 的直接負載平衡

3.5. DEVICES

devices 子系統允許或者拒絕 cgroup 中的任務訪問設備。
重要
在紅帽企業版 Linux 6 中將設備白名單列表(devices)子系統視爲技術預覽。
目前紅帽企業版 Linux 6 訂閱服務還不支持技術預覽功能,可能功能並不完備,且通常不適合產品使用。但紅帽在操作系統中包含這些功能是爲了方便用戶,並提供更廣泛的功能。您會發現這些功能可能在非產品環境中很有用,同時還請提供反饋一件和功能建議,以便今後全面支持這個技術預覽。
devices.allow
指定 cgroup 中的任務可訪問的設備。每個條目有四個字段:type、major、minor 和 access。type、major 和 minor 字段中使用的值對應 Linux 分配的設備,也稱 Linux 設備列表中指定的設備類型和節點數,這兩本書可見於 http://www.kernel.org/doc/Documentation/devices.txt
type
type 可以是以下三個值之一:
a - 應用所有設備,可以是字符設備,也可以是塊設備
b - 指定塊設備
c - 指定字符設備
major, minor
major 和 minor 是由《Linux 分配設備》指定的設備節點數。主設備號和副設備號使用冒號分開。例如:8 是主設備號,指定 SCSI 磁盤驅動器;副設備號 1 指定第一個 SCSI 磁盤驅動器中的第一個分區;因此8:1 完整指定這個分區,對應位於 /dev/sda1 的一個文件系統。

  • 可代表所有主要和次要設備節點,例如:9:(所有 RAID 設備)或者 :*(所有設備)。
    access
    access 是以下一個或者多個字母序列:
    r - 允許任務從指定設備中讀取
    w - 允許任務寫入指定設備
    m - 允許任務生成還不存在的設備文件
    例如:當將 access 指定爲 r 時,則只能從指定設備中讀取任務,但當將 access 指定爲 rw 時,則既可從該設備中讀取任務,也可向該設備中寫入任務。
    devices.deny
    指定 cgroup 中任務不能訪問的設備。條目語法與 devices.allow 一致。
    devices.list
    報告爲這個 cgroup 中的任務設定訪問控制的設備。

3.6. FREEZER

freezer 子系統掛起或者恢復 cgroup 中的任務。
freezer.state
freezer.state 有三個可能的值:
FROZEN -- 掛起該 cgroup 中的任務。
FREEZING -- 該系統正在掛起該 cgroup 中的任務。
THAWED -- 已經恢復該 cgroup 中的任務。
要掛起具體進程:
將那個進程移動到附加了 freezer 子系統的層級的 cgroup 中。
停滯那個具體 cgroup 以便掛起其中包含的這個進程。
不可能將進程移動到掛起(frozen)的 cgroup 中。
請注意可將 FROZEN 和 THAWED 值寫入 freezer.state,但無法寫入 FREEZING,只能讀取它

3.7. MEMORY

memory 子系統自動生成 cgroup 中任務使用的內存資源報告,並設定由那些任務使用的內存限制:
memory.stat
報告大範圍內存統計,如下表所述:
表 3.1. memory.stat 報告的值

統計
描述
cache
頁緩存,包括 tmpfs(shmem),單位爲字節
rss
匿名和 swap 緩存,不包括 tmpfs(shmem),單位爲字節
mapped_file
memory-mapped 映射的文件大小,包括 tmpfs(shmem),單位爲字節
pgpgin
存入內存中的頁數
pgpgout
從內存中讀出的頁數
swap
swap 用量,單位爲字節
active_anon
在活躍的最近最少使用(least-recently-used,LRU)列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位爲字節
inactive_anon
不活躍的 LRU 列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位爲字節
active_file
活躍 LRU 列表中的 file-backed 內存,以字節爲單位
inactive_file
不活躍 LRU 列表中的 file-backed 內存,以字節爲單位
unevictable
無法再生的內存,以字節爲單位
hierarchical_memory_limit
包含 memory cgroup 的層級的內存限制,單位爲字節
hierarchical_memsw_limit
包含 memory cgroup 的層級的內存加 swap 限制,單位爲字節

另外,這些文件除 hierarchical_memory_limit 和 hierarchical_memsw_limit 之外,都有一個對應前綴 total,它不僅可在該 cgroup 中報告,還可在其下級 cgroup 中報告。例如:swap 報告 cgroup 的 swap 用量,total_swap 報告該 cgroup 及其所有子組羣的 swap 用量總和。
當您解讀 memory.stat 報告的數值時,請注意各個統計數據之間的關係:
active_anon + inactive_anon = 匿名內存 + tmpfs 的文件緩存 + swap 緩存
因此,active_anon + inactive_anon ≠ rss,因爲 rss 不包括 tmpfs。
active_file + inactive_file = 緩存減去 tmpfs 大小
memory.usage_in_bytes
報告該 cgroup中進程使用的當前總內存用量(以字節爲單位)。
memory.memsw.usage_in_bytes
報告該 cgroup 中進程使用的當前內存用量和 swap 空間總和(以字節爲單位)。
memory.max_usage_in_bytes
報告該 cgroup 中進程使用的最大內存用量(以字節爲單位)。
memory.memsw.max_usage_in_bytes
報告該 cgroup 中進程使用的最大內存用量和 swap 空間用量(以字節爲單位)。
memory.limit_in_bytes
設定用戶內存的最大量(包括文件緩存)。如果沒有指定單位,則將該數值理解爲字節。但是可以使用前綴代表更大的單位 - k 或者 K 代表千字節,m 或者 M 代表 MB,g 或者 G 代表 GB。
您不能使用 memory.limit_in_bytes 限制 root cgroup;您只能在該層級中較低的組羣中應用這些值。
在 memory.limit_in_bytes 中寫入 -1 刪除現有限制。
memory.memsw.limit_in_bytes
設定最大內存與 swap 用量之和。如果沒有指定單位,則將該值解讀爲字節。但是可以使用前綴代表更大的單位 - k 或者 K 代表千字節,m 或者 M 代表 MB,g 或者 G 代表 GB。
您不能使用 memory.memsw.limit_in_bytes 限制 root cgroup;您只能在該層級中較低的組羣中應用這些值。
在 memory.memsw.limit_in_bytes 中寫入 -1 刪除現有限制。
memory.failcnt
報告內存達到在 memory.limit_in_bytes 設定的限制值的次數。
memory.memsw.failcnt
報告內存加 swap 空間限制達到在 memory.memsw.limit_in_bytes 設定的值的次數。
memory.force_empty
當設定爲 0 時,會清空這個 cgroup 中任務所使用的所有頁面的內存。這個接口只可在 cgroup 中沒有任務時使用。如果無法清空內存,則在可能的情況下將其移動到上級 cgroup 中。刪除 cgroup 前請使用 memory.force_empty 以避免將不再使用的頁面緩存移動到它的上級 cgroup 中。
memory.swappiness
將內核傾向設定爲換出這個 cgroup 中任務所使用的進程內存,而不是從頁緩衝中再生頁面。這也是在 /proc/sys/vm/swappiness 中設定的使用同一方法爲整個系統設定的內核傾向。默認值爲 60。低於這個值會降低內核換出進程內存的傾向,將其設定爲 0 則完全不會爲 cgroup 中的任務換出進程內存。高於這個值將提高內核換出進程內存的傾向,大於 100時內核將開始換出作爲這個 cgroup 中進程的地址空間一部分的頁面。
請注意那個值爲 0 不會阻止換出進程內存;系統缺少內存時仍可能發生換出內存,這是因爲全局虛擬內存管理邏輯不讀取該 cgroup 值。要完全鎖定頁面,請使用 mlock() 而不時 cgroup。
您不能更改以下組羣的 swappiness:
root cgroup,它使用在 /proc/sys/vm/swappiness 中設定的 swappiness。
有屬於它的子組羣的 cgroup。
memory.use_hierarchy
包含指定是否應將內存用量計入 cgroup 層級的吞吐量的標籤(0 或者 1)。如果啓用(1),內存子系統會從超過其內存限制的子進程中再生內存。默認情況(0)是子系統不從任務的子進程中再生內存。

3.8. NET_CLS

net_cls 子系統使用等級識別符(classid)標記網絡數據包,可允許 Linux 流量控制程序(tc)識別從具體 cgroup 中生成的數據包。可將流量控制程序配置爲給不同 cgroup 中的數據包分配不同的優先權。
net_cls.classid
net_cls.classid 包含一個說明流量控制句柄的十六進制的值。例如:0x1001 代表通常寫成 10:1 的句柄,這是 iproute2 使用的格式。
這些句柄的格式爲:0xAAAABBBB,其中 AAAA 是十六進制主設備號,BBBB 是十六進制副設備號。您可以忽略前面的零;0x10001 與 0x00010001 一樣,代表 1:1。
參考 tc 的 man page 瞭解如何配置流量控制程序使用 net_cls 添加到網絡數據包中的句柄。

3.9. NS

ns 子系統提供了一個將進程分組到不同名稱空間的方法。在具體名稱空間中,進程可彼此互動,但會與在其它名稱空間中運行的進程隔絕。這些分開的名稱空間在用於操作系統級別的虛擬化時,有時也稱之爲容器。

3.10. 附加資源

具體子系統內核文檔
以下所有文件都位於 /usr/share/doc/kernel-doc-<kernel_version>/Documentation/cgroups/ 目錄中(由 kernel-doc 軟件包提供)。
blkio 子系統 -- blkio-controller.txt
cpuacct 子系統 -- cpuacct.txt
cpuset 子系統 -- cpusets.txt
devices 子系統 -- devices.txt
freezer 子系統 -- freezer-subsystem.txt
memory 子系統 -- memory.txt

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章