簡介
我們都知道,docker 容器具有很好的隔離性,我們可以在一臺伺服器上執行很多 docker 容器。
雖然一臺伺服器可以執行著很多 docker 容器,但這些容器是共用一臺伺服器的 CPU 和記憶體資源的,如果任由容器隨意使用資源不加限制的話,很有可能會造成一部分容器佔用過多資源,而其他容器無法正常執行。
docker 基於這點考慮,提供了控制容器資源的功能,而這個功能,是利用 Linux 的 CGroups 來實現的。
接下來我們來了解和實驗一下 Linux 的 CGroups。
CGroup 介紹
CGroups,Control Groups 的縮寫,用來限制、控制與分離一個程式組群的資源,如 CPU、記憶體、磁碟、網路 IO 等,是將任意程式進行分組化管理的 Linux 核心功能。
主要目的是為不同使用者層面的資源管理提供一個統一化的介面。
功能及子系統
功能
CGroups 提供了四大功能:
- 資源限制:CGroups 可以對任務需要的資源總額進行限制。比如設定任務執行時使用的記憶體上限,一旦超出就發 OOM。
- 優先順序分配:通過分配的 CPU 時間片數量和磁碟 IO 頻寬,實際上就等同於控制了任務執行的優先順序。
- 資源統計:CGroups 可以統計系統的資源使用量,比如 CPU 使用時長、記憶體用量等。
- 任務控制:CGroups 可以對任務執行掛起、恢復等操作。
任務(Task),表示作業系統的一個程式或者執行緒。
子系統
子系統,英文是 Subsystem,是 CGroups 中資源排程控制器(又叫 Controllers)。
我們在 Linux 控制檯下執行 cat /proc/cgroups
可以檢視當前系統支援的子系統,
- cpuset:為 CGroups 中的任務分配獨立 CPU(在多核系統)和記憶體節點。
- cpu:限制 CPU 時間片的分配,與 cpuacct 掛載在同一目錄。
- cpuacct:生成 CGroups 中的任務佔用 CPU 資源的報告,與 cpu 掛載在同一目錄。
- blkio:對塊裝置的 IO 進行限制。
- memory:對 CGroups 中的任務的可用記憶體進行限制,並自動生成資源佔用報告。
- devices:允許或禁止 CGroups 中的任務訪問裝置。
- freezer:暫停/恢復 CGroups 中的任務。
- net_cls:使用等級識別符(classid)標記網路資料包,這讓 Linux 流量控制器(tc 指令)可以識別來自特定 CGroups 任務的資料包,並進行網路限制。
- perf_event:
- net_prio:允許基於 CGroups 設定網路流量(netowork traffic)的優先順序。
- hugetlb:限制使用的記憶體頁數量。
- pids:限制任務的數量。
使用方法
CGroups 給使用者暴露出來的操作介面是檔案系統,即它以檔案和目錄的形式組織在 /sys/fs/cgroup/
目錄下。我們在 Linux 控制檯下執行 mount -t cgroup
可以檢視。
可以看到,每個子系統在 /sys/fs/cgroup/
目錄下都有相應的目錄。
我們拿 cpu 子系統來看看,在控制檯執行 ls /sys/fs/cgroup/cpu/
,
其中,cpu.cfs_period_us 和 cpu.cfs_quota_us 這兩個引數要組合使用,可以用來限制程式在長度為 cpu.cfs_period_us 的時間內,只能被分配到總量為 cpu.cfs_quota_us 的 CPU 時間。
接下來讓我們實驗一下。
1. 在控制檯執行 mkdir -p /sys/fs/cgroup/cpu/container
,檢視 container 目錄
可以看到,系統自動在 container 建立了 cpu.cfs_period_us 和 cpu.cfs_quota_us 等進行資源限制的檔案。
2. 在控制檯執行 php loop.php &
,loop.php 中程式碼如下
<php?
while (true) {
}
一般情況下,這個死迴圈會把 CPU 佔到 100%,我們執行 top 指令看一下
可以看到,CPU 的使用率已經 100% 了。
3. 限制程式使用的 CPU
我們檢視一下 container 目錄下的 cpu.cfs_quota_us 和 cpu.cfs_period_us,
可以看到,輸出值分別為 -1 和 100000(100ms),說明 container 控制組裡的 CPU 還沒任何限制。
接下來,向 cpu.cfs_quota_us 檔案寫入 20000(20ms),同時把 27667 寫入 tasks
結合 cpu.cfs_period_us 的值,表示每 100ms 的時間裡,被控制組限制的程式只能使用 20ms 的 CPU,也就是 CPU 佔用率為 20%。
總結
本文中,我們簡單介紹了
- CGroups 是什麼
- CGroups 的使用場景
- CGroups 的功能和子系統
- CGroups 的一個小實驗