在一台Docker宿主機上可以同時啓動多個容器。在默認情況下,Docker的引擎對運行的容器沒有限制硬件資源的使用。而在實際環境下,容器的負載過高會導致佔用宿主機的大量資源。這裏的資源主要是指宿主機的CPU、內存和I/O帶寬這3個方面。
視頻講解如下:
https://www.bilibili.com/video/BV1JFxezrEwe/?aid=115337622199...
一、 什麼是Linux CGroup?
由於Docker是構建在Linux的基礎之上,因此從Linux底層看,Docker是利用了Linux Control Group(簡稱Linux CGroup)實現了對資源使用的控制。因此,要掌握Docker容器的資源管理,有必要先了解一下什麼是Linux CGroup。
Linux CGroup是Linux下的一些進程,通過這些進程可以限制應用程序對資源的使用。並且,通過Linux CGroup可以對系統資源做精細化控制。例如,可以實現對每個容器使用的CPU比率進行限制。
Linux CGroup主要提供了以下的功能。
- Resource limitation:限制資源使用,例如,使用CPU及內存的上限。
- Prioritization:應用程序的優先級控制,例如,控制任務的調度。
- Accounting:應用程序的審計和統計,例如,實現應用程序的計費。
- Control:實現對應用程序的控制,例如,應用程序的掛起、恢復和執行等。
要是使用Linux CGroup功能,則需要先通過執行下面的步驟確定Linux的內核是否啓用了Linux CGroup功能。
(1)確定操作系統的發行版號,如下圖所示。
(2)根據操作系統的發行版號,可以確定是否啓用了Linux CGroup功能。下圖中的CGROUP參數的值是“y”,表示已經啓動Linux CGroup對應的功能特性。
cat /boot/config-3.10.0-693.el7.x86_64 | grep CGROUP
瞭解了Linux CGroup功能特性後,下面將通過3個示例來演示如何使用Linux Group實現對系統資源使用的控制。
二、 通過Linux CGroup限制應用程序的CPU使用率
在本示例中,將利用C語言開發一段執行死循環的代碼。由於是死循環,所以代碼的CPU使用率將很高。然後通過使用Linux CGroup,將代碼的CPU使用率限制在一定範圍內,如20%。下面是具體的操作步驟。
(1)開發一段C程序代碼產生一個死循環,並將代碼保存為hello.c。
//hello.c
int main(void)
{
int i = 0;
for(;;) i++;
return 0;
}
(2)將程序代碼進行編譯。
gcc -o hello hello.c
(3)執行程序代碼,這時程序將產生死循環無法退出。
./hello
(4)在一個新的命令行窗口中,使用“top”命令監控應用程序hello的CPU使用率,可以看到已經達到了99.7%,如下圖所示。
(5)進入“/sys/fs/cgroup/cpu/”目錄下,創建一個新的子目錄hello。該目錄用於設置CPU使用率的閾值,如下圖所示。
cd /sys/fs/cgroup/cpu/
mkdir hello
cd hello/
ls
(6)查看文件cpu.cfs_quota_us的內容為“-1”,表示沒有對其CPU使用率進行限制。
(7)執行下面的語句將CPU使用率的閾值設置為20%。
echo 20000 > cpu.cfs_quota_us
(8)將應用程序hello的進程ID號寫入tasks文件,如下圖所示。
echo 21503 > tasks
(9)再次觀察“top”命令的輸出信息,發現應用程序hello的CPU使用率降到了20%,如下圖所示。
(10)重新啓動一個hello應用程序,並按照上面的步驟將進程ID號寫入tasks文件。這時觀察“top”命令的輸出會發現,兩個hello應用程序各自佔用10%的CPU使用率,如下圖所示。
二、 通過Linux CGroup限制應用程序使用系統內存
具體的操作步驟如下。
(1)進入“cd /sys/fs/cgroup/memory” 目錄下,創建子目錄hello。
cd /sys/fs/cgroup/memory
mkdir hello
cd hello
(2)查看文件memory.limit_in_bytes的內容。
more memory.limit_in_bytes
# 這裏設定的值是9223372036854771712,表示沒有對內存進行任何的限制
。
(3)下面的語句會將內存的閾值設置為64KB。如果應用程序使用的內存超過了該值,則該應用程序會被操作系統自動“殺掉”。
echo 64k > memory.limit_in_bytes
(4)生效配置,將應用程序hello的進程ID號寫入tasks文件。
echo 21503 > tasks
三、 通過Linux CGroup限制應用程序使用I/O帶寬
為了更好地觀察結果,首先安裝iotop工具。
yum -y install iotop
# iotop是一個用來監視磁盤I/O使用狀況的工具,包括pid、user、I/O、進程等相關信息。
下面的步驟演示瞭如何使用Linux CGroup限制應用程序使用I/O帶寬。
(1)使用Linux的“dd”命令從磁盤持續讀寫數據。
dd if=/dev/sda of=/dev/null
(2)通過iotop工具查看I/O讀取的速度為569.04 MB/s,如下圖所示。
(3)查看設備“/dev/sda”的信息。從下圖中可以看到,設備“/dev/sda”的設備號是“disk 8,0”。
ls -l /dev/sda
(4)使用Linux CGroup限制I/O對設備“/dev/sda”的讀取速率。
mkdir /sys/fs/cgroup/blkio/io
cd /sys/fs/cgroup/blkio/io
echo '8:0 1048576' > blkio.throttle.read_bps_device
# 通過這樣,對該設備的讀取速率被限制在了1MB/s之內了。
(5)將“dd”命令的進程ID號21681寫入tasks文件。
echo 21681 > tasks
(6)再次觀察iotop工具的監控輸出信息,會發現這時“dd”命令對該設備的讀取速率已經被設置了1.00 MB/s,如下圖所示。
瞭解了Linux CGroup的功能後,再來討論“Docker是如何對容器使用的資源進行設定”就變得非常簡單了。Docker只是對Linux CGroup進行了封裝,從而簡化了調用操作的方式。