Docker 基礎技術之 Linux cgroups 詳解


本文首發於我的公眾號 Linux雲計算網絡(id: cloud_dev),專注於干貨分享,號內有 10T 書籍和視頻資源,后台回復「1024」即可領取,歡迎大家關注,二維碼文末可以掃。

推薦大家到公眾號閱讀,那里閱讀體驗更好,也沉淀了很多篇干貨。

前面兩篇文章我們總結了 Docker 背后使用的資源隔離技術 Linux namespace。
Docker 基礎技術之 Linux namespace 詳解
Docker 基礎技術之 Linux namespace 源碼分析

本篇將討論另外一個技術——資源限額,這是由 Linux cgroups 來實現的。

cgroups 是 Linux 內核提供的一種機制,這種機制可以根據需求把一系列任務及子任務整合(或分隔)到按資源划分等級的不同組內,從而為系統資源管理提供一個統一的框架。(來自 《Docker 容器與容器雲》)

通俗來說,cgroups 可以限制和記錄任務組(進程組或線程組)使用的物理資源(包括 CPU、內存、IO 等)。

為了方便用戶(程序員)操作,cgroups 以一個偽文件系統的方式實現,並對外提供 API,用戶對文件系統的操作就是對 cgroups 的操作。

從實現上來,cgroups 實際上是給每個執行任務掛了一個鈎子,當任務執行過程中涉及到對資源的分配使用時,就會觸發鈎子上的函數對相應的資源進行檢測,從而對資源進行限制和優先級分配。

cgroups 的作用

總結下來,cgroups 提供以下四個功能:

資源限制:cgroups 可以對任務使用的資源總額進行限制,如設定應用運行時使用內存的上限,一旦超過這個配額就發出 OOM(Out of Memory)提示。

優先級分配:通過分配的 CPU 時間片數量和磁盤 IO 帶寬大小,實際上就相當於控制了任務運行的優先級。

資源統計:cgroups 可以統計系統的資源使用,如 CPU 使用時長、內存用量等,這個功能非常適用於計費。

任務控制:cgroups 可以對任務執行掛起、恢復等操作。

cgroups 的子系統

cgroups 在設計時根據不同的資源類別分為不同的子系統,一個子系統本質上是一個資源控制器,比如 CPU 資源對應 CPU 子系統,負責控制 CPU 時間片的分配,內存對應內存子系統,負責限制內存的使用量。進一步,一個子系統或多個子系統可以組成一個 cgroup,cgroups 中的資源控制都是以 cgroup 為單位來實現,一個任務(或進程或線程)可以加入某個 cgroup,也可以從一個 cgroup 移動到另一個 cgroup,但這里有一些限制,在此就不再贅述了,詳細查閱相關資料了解。

對於我們來說,最關鍵的是知道怎么用,下面就針對 CPU、內存和 IO 資源來看 Docker 是如何使用的?

對於 CPU,Docker 使用參數 -c 或 --cpu-shares 來設置一個容器使用的 CPU 權重,權重的大小也影響了 CPU 使用的優先級。

如下,啟動兩個容器,並分配不同的 CPU 權重,最終 CPU 使用率情況:

docker run --name "container_A" -c 1024 ubuntu
docker run --name "container_B" -c 512 ubuntu

當只有一個容器時,即使指定較少的 CPU 權重,它也會占滿整個 CPU,說明這個權重只是相對權重,如下將上面的 “container_A” 停止,“container_B” 就分配到全部可用的 CPU。

對於內存,Docker 使用 -m(設置內存的限額)和 --memory-swap(設置內存和 swap 的限額)來控制容器內存的使用量,如下,給容器限制 200M 的內存和 100M 的 swap,然后給容器內的一個工作線程分配 280M 的內存,因為 280M 在容許的 300M 范圍內,沒有問題。其內存分配過程是不斷分配又釋放,如下:

如果讓工作線程使用內存超過 300M,則出現內存超限的錯誤,容器退出,如下:

對於 IO 資源,其使用方式與 CPU 一樣,使用 --blkio-weight 來設置其使用權重,IO 衡量的兩個指標是 bps(byte per second,每秒讀寫的數據量) 和 iops(io per second, 每秒 IO 的次數),實際使用,一般使用這兩個指標來衡量 IO 讀寫的帶寬,幾種使用參數如下:

  • --device-read-bps,限制讀某個設備的 bps。

  • --device-write-bps,限制寫某個設備的 bps。

  • --device-read-iops,限制讀某個設備的 iops。

  • --device-write-iops,限制寫某個設備的 iops。

假如限制容器對其文件系統 /dev/sda 的 bps 寫速率為 30MB/s,則在容器中用 dd 測試其寫磁盤的速率如下,可見小於 30MB/s。

如果是正常情況下,我的機器可以達到 56.7MB/s,一般都是超 1G 的。

上面幾個資源使用限制的例子,本質上都是調用了 Linux kernel 的 cgroups 機制來實現的,每個容器創建后,Linux 會為每個容器創建一個 cgroup 目錄,以容器的 ID 命名,目錄在 /sys/fs/cgroup/ 中,針對上面的 CPU 資源限制的例子,我們可以在 /sys/fs/cgroup/cpu/docker 中看到相關信息,如下:

其中,cpu.shares 中保存的就是限制的數值,其他還有很多項,感興趣可以動手實驗看看。

總結

cgroups 的作用,cgroups 的實現,cgroups 的子系統機制,CPU、內存和 IO 的使用方式,以及對應 Linux 的 cgroups 文件目錄。


我的公眾號 「Linux雲計算網絡」(id: cloud_dev) ,號內有 10T 書籍和視頻資源,后台回復 「1024」 即可領取,分享的內容包括但不限於 Linux、網絡、雲計算虛擬化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++編程技術等內容,歡迎大家關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM