透過現象看本質——聊一聊docker的硬體資源控制與驗證
前言
前面兩篇文章主要介紹了有關docker的基礎概念、安裝、以及對鏡像容器的相關操作。重點在于指令的含義以及常用的一些指令的可選項的含義的了解,本文在此基礎上來聊一聊基于硬體層面是上有關docker的資源(實體)控制。
一、docker管理資源機制——Control group
Control group 是Linux核心提供的一種限制所使用實體資源的機制,這些資源主要是CPU、記憶體、blkio,而Control group簡稱為Cgroup,我們可以在下面的目錄中檢視:
[root@docker cgroup]# ls
blkio cpuacct cpuset freezer memory net_cls,net_prio perf_event systemd
cpu cpu,cpuacct devices hugetlb net_cls net_prio pids
在該目錄下我們可以看到有blkio、cpuset、memory、cpu等與實體硬體資源對應的檔案以及目錄。下面就基于上述的三個方面來聊一聊docker是如何使用該機制對這些資源進行管理的。
二、對CPU的控制
對CPU的控制有下面幾種方式:
- 限制CPU的使用率;
- 多任務按比例配置設定CPU;
- 限制CPU核心(核心數)使用;
2.1基于使用率限制CPU
我們可以在檔案中檢視預設的限制設定,我們先運作一個容器(兩種方式,我們使用run的指令來快速運作一個容器):
#檢查本地是否有鏡像或容器存在
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#運作一個容器
[root@docker ~]# docker run -itd --name test centos:7 /bin/bash
Unable to find image 'centos:7' locally
7: Pulling from library/centos
ab5ef0e58194: Pull complete
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Downloaded newer image for centos:7
ff84f35a0d6fdc77d292f7168546848385ab382f3dc1486077933e944c4424b9
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff84f35a0d6f centos:7 "/bin/bash" About a minute ago Up About a minute test
我們進入docker目錄下的容器編号目錄中,檢視cpu.cfs_quota_us檔案,其中的内容預設為-1(我們可以對此更改)
[root@docker ~]# cd /sys/fs/cgroup/cpu/docker/ff84f35a0d6fdc77d292f7168546848385ab382f3dc1486077933e944c4424b9/
[root@docker ff84f35a0d6fdc77d292f7168546848385ab382f3dc1486077933e944c4424b9]# ls
cgroup.clone_children cpuacct.stat cpu.cfs_period_us cpu.rt_runtime_us notify_on_release
cgroup.event_control cpuacct.usage cpu.cfs_quota_us cpu.shares tasks
cgroup.procs cpuacct.usage_percpu cpu.rt_period_us cpu.stat
[root@docker ff84f35a0d6fdc77d292f7168546848385ab382f3dc1486077933e944c4424b9]# cat cpu.cfs_quota_us
-1
果然,預設的配額值為-1,這就表示預設情況下是不對CPU資源進行控制的,顯然這樣在使用容器的過程中非常容易出現問題,例如一台真實伺服器運作着各種各樣的數量非常多的容器,而其中一台容器占據了接近90%的CPU使用率,那麼剩下來的如此多的容器隻能在剩餘的10%中擷取使用,這很容易引發業務故障,是以我們需要對CPU包括随後的記憶體及檔案IO流進行優化處理的配置。
首先,本小節是對CPU的使用率進行的控制,那麼下面就來看看怎麼配置的吧。
我們可以直接進入這個檔案進行設定,那麼怎麼設定呢?
這就需要說明一下了,CPU的百分比是以1000位機關的,是以總額為100000,即10萬,那麼我們寫入20000,則使用率為20%。除了直接改(echo也行)也可以在指令行中進行設定:
[root@docker ~]# docker run -itd --name test1 --cpu-quota 20000 centos:7 /bin/bash
31f9d00fca956d315736dad8a1f2e4c01128d44370af4b37c10298fd2c6a3ee6
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31f9d00fca95 centos:7 "/bin/bash" 14 seconds ago Up 12 seconds test1
ff84f35a0d6f centos:7 "/bin/bash" 14 minutes ago Up 14 minutes test
那麼我們怎麼驗證或者說測試這個使用率占比最高是在20%呢?
我們可以進入這個容器中執行操作,使得CPU滿載,另外開一個terminal使用top指令檢視CPU使用情況即可。
#下載下傳bc工具,一種任意精度的電腦語言,可以了解為用于精确計算的
[root@31f9d00fca95 /]# yum install bc -y
#我們使用該工具來計算圓周率
[root@31f9d00fca95 /]# echo "scale=5000; 4*a(1)" | bc -l -q
#說明:其中a是bc的一個内置函數,代表arctan(三角函數哈~),由于tan(pi/4)=1,是以4*arctan(1)=pi 【pi就是π】,5000表示計算精确到小數點後面的5000位,-l表示使用标準數學庫,-q表示 不在界面中輸出。
為了示範整個效果我在另外一個終端使用top指令檢視,可以發現整個CPU使用率在20%左右,會有所上浮但是不會過分離譜,計算完成後将會釋放資源的。截取兩張圖作為驗證結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CO5MjN2kDZkFDNmdzN3I2MiFGN1gjMyUmY3QTMjBTMw8CX1EzLcRDMwIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
2.2基于比例配置設定CPU
對于上面基于使用率配置設定給容器的方式可能隻适合于少量的容器情況下,容器數量多的時候并不好計算以及設定使用率,這時我們可以通過按比例配置設定的方式(通過--cpu-share選項配置),這樣既友善又靈活。具體看下面的執行個體示範:
#建立兩個容器,并且使得兩個容器的CPU比例配置設定為1:2
[root@docker ~]# docker run -itd --name c1 --cpu-shares 512 centos:7 /bin/bash
6ec8bb5d2fde0cba2ec436484ec037f694c3eaff744a90fd08173205c8121956
[root@docker ~]# docker run -itd --name c2 --cpu-shares 1024 centos:7 /bin/bash
03a587d09afb591bfaaff79a7c998872b85f4375f9ebd48e9aee9c220ed53f98
#檢視容器
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03a587d09afb centos:7 "/bin/bash" About a minute ago Up About a minute c2
6ec8bb5d2fde centos:7 "/bin/bash" 2 minutes ago Up 2 minutes c1
31f9d00fca95 centos:7 "/bin/bash" 29 minutes ago Up 29 minutes test1
ff84f35a0d6f centos:7 "/bin/bash" 44 minutes ago Up 44 minutes
那麼怎麼進行測試驗證呢?
我們開兩個終端用于進入容器測試,另外一個終端使用docker stats指令檢視驗證。
#進入兩個容器都進行下面的操作,我們以其中一個進行示範
[root@docker ~]# docker exec -it 03a587d09afb /bin/bash
[root@03a587d09afb /]# yum install -y epel-release
[root@03a587d09afb /]# yum install stress -y
#stress是壓測工具,依賴于上面的epel-release
開始在兩個終端上使用stress指令壓測
[root@6ec8bb5d2fde /]# stress -c 4
stress: info: [98] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
^C#驗證到結果後就退出吧,因為CPU很累的
[root@03a587d09afb /]# stress -c 4
stress: info: [97] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
^C#驗證到結果後就退出吧,因為CPU很累的
結果:
當然這個是會動态變化的,不一定完全是1:2的關系但是一定是接近這個比例的哈~~
2.3基于CPU核心使用限制
在docker中可以使用--cpuset-cpus選項來使某些程式獨享CPU的核心,以便提高其處理速度。如果我們的CPU核心數為4那麼對應的編号為0,1,2,3,可以通過top指令來檢視,按下數字1後就可以檢視CPU編号以及對應資訊了。
具體的控制設定如下:
[root@docker ~]# docker run -itd --name test2 --cpuset-cpus 1,3 centos:7 /bin/bash
116606ef1e11b0afa09da67b2782c1cc0d042eb026cbfe113d7dac11ae818dcc
#即基于cpuset-cpus進行設定
使用第二種方式的測試方法,基于top指令檢視驗證,結果如下圖所示:
當然,基于CPU的限制控制也可以三種方式結合使用,本文主要是為了講解這三種方式。
三、對記憶體的控制
記憶體使用相對于CPU而言比較簡單了,通過-m參數進行設定。
執行個體示範:
[root@docker ~]# docker run -itd --name demo -m 512m centos:7 /bin/bash
c69071b6dbc302c5f4d34782a0b7eb663e40cd5f847f4aac45a375c3d4e817d9
在另一個終端上進行檢視:docker stats
結果如下圖:
限制的大小為512m,就表示隻能使用這麼大的記憶體
四、對blkio的控制
對應blkio的設定,主要是對于在一台伺服器上進行容器的混合部署的場景,就會出現同時有多個程式寫入磁盤資料的情況,此時可以通過--device-write-iops選項來限制寫入的iops,相應的有--device-read-bps選項可以限制讀取的iops。但是這種方法隻能針對blkio限制的是裝置,而不是分區。羅列一下吧:
--device-read-bps:限制讀某個裝置的bps(資料量)使用多
--device-write-iops:限制寫入某個裝置的iops(次數)
[root@docker ~]# docker run -itd --name test4 --device-write-bps /dev/sda:30m centos:7 /bin/bash
16004244b632b8ada5faefdca57e321664e89fe9472dd6195f8eb7f07d7602ee