亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

容器核心技術–CGroup

接上一個小節,我們來試想這樣一個場景:

一臺宿主機的容器中運行了一個監控服務,但監控服務占用了宿主機全部的 CPU 和內存等資源,導致宿主機上的其他服務和容器都被卡死,無法正常運行。

監控類服務不應占用大量資源,無論是什么原因引起的問題,都不應該影響宿主機的正常使用,否則容器的隔離就沒有意義。Namespace 只能做到系統資源維度的隔離,無法做到硬件資源的控制。我們需要使用一種機制 Cgroup,指定容器應用最大占用多少資源。

Linux cgroups 的全稱是 Linux Control Groups,它是 Linux 內核的特性,主要作用是限制、記錄和隔離進程組(process groups)使用的物理資源(CPU、Memory、IO 等)。

1. CGroup 核心概念

前面說過 CGroup 是用來對進程進行資源管理的,因此 CGroup 需要考慮如何抽象這兩種概念:進程和資源,同時如何組織自己的結構。CGroup 機制中有以下幾個基本概念:

  • task:任務,對應于系統中運行的一個實體,下文統稱進程;
  • subsystem:子系統,具體的資源控制器(resource class 或者 resource controller),控制某個特定的資源使用;
  • cgroup:控制組,一組任務和子系統的關聯關系,表示對這些任務進行怎樣的資源管理策略;
  • hierarchy:層級樹,由一系列 CGroup 組成的樹形結構。每個節點都是一個 CGroup ,CGroup 可以有多個子節點,子節點默認會繼承父節點的屬性。系統中可以有多個 hierarchy。

Cgroup 機制非常復雜,上面的名詞了解就好,學習 Docker 暫時還不需要深入研究它。

在 Linux 環境中,我們可以執行 ls -al /sys/fs/cgroup/ 查看當前系統的 Cgroup:

圖片描述

我們看到目錄中有若干個子目錄,除了 systemd 目錄,其他的一個子目錄對應一個子系統,子系統功能如下所示。

子系統 功能
blkio 為塊設備,如硬盤等設備,設定輸入輸出限制
cpu 設置 cgroup 中進程的 CPU 被調度的策略
cpuacct 統計 cgroup 中進程的 CPU 占用
cpuset 設置 cgroup 中進程可以使用的 CPU 和內存
devices 控制 cgroup 中進程對設備的訪問
freezer 掛起或者恢復 cgroup 中的進程
hugetlb 用于控制 cgroup 中進程的內存占用,這是一個大頁文件系統。
memory 控制 cgroup 中進程的內存占用,并統計內存資源使用情況。
net_cls 將 cgroup 中進程產生的網絡包分類,允許 Linux 流量控制系統識別從具體 cgroup 中生成的數據包。
net_prio 控制 cgroup 中進程的網絡流量的優先級
perf_event 識別任務的 cgroup 成員,可以用來做性能分析
pids 限制 cgroup 及其所有子孫 cgroup 里面能創建的總的進程數量
rdma 限制 RDMA/IB 資源

3. 演示:使用 Cgroup 限制進程 CPU 資源占用

在上面的表格中, 你會發現大量出現Cgroup 中的進程這個描述,原因在于我們必須先掛載子系統,將進程納入 Cgroup 組規則中,然后 Cgroup 機制才能控制這個進程。

我們馬上上手嘗試一下,先安裝stress

sudo dnf install https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/s/stress-1.0.4-16
.el7.x86_64.rpm

Tips:我們使用stress 的軟件進行壓力負載測試,stress 會根據設定,執行一系列消耗系統資源的操作,使得系統在一定的負載下運行。

啟動一個壓力負載測試的進程:

# 產生 1個進程,每個進程都反復不停地計算隨機數的平方根
stress -c 1 > /dev/null &

使用top 命令查看資源占用情況
圖片描述

圖中兩個紅框從左到右分別代表壓力測試的進程號是 1816,CPU 占用百分比 99%,說明壓力測試進程正常生效了。

切換到 root 用戶:

sudo su - root

進入 /sys/fs/cgroup/cpu 這個目錄:

cd /sys/fs/cgroup/cpu

創建一個 Cgroup 組,即在當前目錄下創建一個子目錄:

mkdir testcpu

進入 testcpu 目錄:

cd testcpu

查看 cpu.cfs_period_us 代表時間周期總長度:

cat cpu.cfs_period_us  # 100000

cpu.cfs_quota_us 設為當前 cgroup 在設置的周期長度內所能使用的 CPU 時間 10000,即總周期100000的 10%:

echo 10000 > cpu.cfs_quota_us  

將壓力測試的進程添加到 Cgroup 組的規則中,1816 是stress進程 id:

echo 1816 > tasks

top 查看資源占用,發現 stress 進程的 CPU 占用率被壓到了 10%,說明 Cgroups 對于 CPU 的控制起了效果。
圖片描述

3. 思考

試想一下,我們將本節限制 CPU 資源的操作對象,從 stress 這個程序,改換成前一節的 container,就獲得了一個同時限制了硬件資源和系統資源的容器。

4. 小結

通過本節的介紹,我們對 Cgroup 有了直觀的認知。Cgroup 是個非常強大的系統,容器技術需要使用它進行資源的限制,但這不代表著 Cgroup 只能用于容器技術,比如在云服務商的計費系統中,也有它的身影。

或許你會感覺這一節與上一節 Namespace 的內容有些生僻,別擔心,我們介紹 Namespace 和 CGroup 的目的不是去精通他們的底層原理和使用方法,而是要真正認識到:容器的本質就是一個特殊的進程。