Docker 技術基礎之 CGroups

LDL1023發表於2019-06-23

簡介

我們都知道,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 可以檢視當前系統支援的子系統,

Docker 技術基礎之 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 可以檢視。

Docker 技術基礎之 CGroups
可以看到,每個子系統在 /sys/fs/cgroup/ 目錄下都有相應的目錄。
我們拿 cpu 子系統來看看,在控制檯執行 ls /sys/fs/cgroup/cpu/
Docker 技術基礎之 CGroups
其中,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 目錄

Docker 技術基礎之 CGroups
可以看到,系統自動在 container 建立了 cpu.cfs_period_us 和 cpu.cfs_quota_us 等進行資源限制的檔案。

2. 在控制檯執行 php loop.php &,loop.php 中程式碼如下

<php?

while (true) {
}

一般情況下,這個死迴圈會把 CPU 佔到 100%,我們執行 top 指令看一下
Docker 技術基礎之 CGroups
可以看到,CPU 的使用率已經 100% 了。

3. 限制程式使用的 CPU

我們檢視一下 container 目錄下的 cpu.cfs_quota_us 和 cpu.cfs_period_us,
Docker 技術基礎之 CGroups
可以看到,輸出值分別為 -1 和 100000(100ms),說明 container 控制組裡的 CPU 還沒任何限制。
接下來,向 cpu.cfs_quota_us 檔案寫入 20000(20ms),同時把 27667 寫入 tasks
Docker 技術基礎之 CGroups
結合 cpu.cfs_period_us 的值,表示每 100ms 的時間裡,被控制組限制的程式只能使用 20ms 的 CPU,也就是 CPU 佔用率為 20%。
Docker 技術基礎之 CGroups

總結

本文中,我們簡單介紹了

  • CGroups 是什麼
  • CGroups 的使用場景
  • CGroups 的功能和子系統
  • CGroups 的一個小實驗

參考

  1. wikipedia cgroups
  2. linux cgroups 簡介

相關文章