預設情況下容器是沒有資源限制的,因為它本身就是一個程序,當一個容器佔用太多資源的話,會對其他容器產生影響,所以 ,合理應該分配容器資源是作為管理員必須要關注的問題。
虛擬機器器在建立的時候就已經做了資源分配,(虛擬CPU,虛擬記憶體,虛擬磁碟等)
容器是共用核心資源的,所以需要用Cgroup資源分配,參照因素是往年的監控系統中服務的吞吐量,和資源資料,資源耗用情況來分配
Docker通過Cgroup來控制容器使用的資源配額,包括CPU,記憶體,磁碟三大方面,基本覆蓋了常見的資源配額和使用量的控制
Cgroup是Control Groups的縮寫,是Linux核心提供的一種限制,記錄,隔離行程群組所使用的物理資源(如CPU 記憶體 磁碟IO 等等)的機制,被LXC docker等很多專案用於實現程序資源控制。Cgroup本身是提供將程序進行分組化管理的功能和介面的基礎結構,I/O或記憶體的分配控制等,這些具體的資源管理功能稱為Cgroup子系統,有以下幾個大子系統實現:
stress 是Unix類系統下的工作量和壓力測試工具。它將對使用者指定的CPU數量的I/O,記憶體和硬碟的負載並報告它檢測到任何錯誤。它用於自動壓力測試和偵錯系統元件失敗的唯一或更經常負荷時。它可以執行在x86,ppc64的,和PPC 32 GNU / Linux的,Tru64的,SPARC Solaris的,和其他平臺
[root@localhost ~]# setenforce 0
[root@localhost ~]# iptables -F
[root@localhost ~]# systemctl start docker '開啟docker功能'
[root@localhost opt]# mkdir /opt/stress '在/opt目錄下建立一個stress目錄'
[root@localhost stress]# cd /opt/stress/
[root@localhost stress]# vim Dockerfile '建立stress的映象'
FROM centos:7 '基於Centos:7的映象'
MAINTAINER This is cai '描述資訊'
RUN yum -y install wget '安裝wget下載工具'
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo '去阿里雲官網設定yum源'
RUN yum -y install stress ##安裝stress
[root@localhost stress]# docker build -t centos:stress . '建立映象'
[root@localhost stress]# docker run -itd --cpu-shares 100 centos:stress
說明:預設情況下,每個Docker容器的CPU份額都是1024,單獨一個容器的份額是沒有意義的。只有在同時執行多個容器時,容器的CPU加權的效果才能體現出來。
例如:如果兩個容器A B的CPU分別為1000和500,在CPU進行時間片分配的時候,容器A比容器B多一倍機會獲得CPU的時間片
但分配的結果取決於當時主機和其他容器的執行狀態,實際上也無法保證容器A一定能獲得CPU時間片。比如容器A的程序一直是空閒的,那麼容器B是可以獲取比容器A更多的CPU時間篇的。極端情況下,例如主機上只執行了一個容器,即使它的CPU份額只有50,它也可以獨佔整個主機的CPU資源
Cgroups只在容器分配資源緊缺時,即在需要對容器使用的資源進行限制時,才會生效。因此無法單純根據某個容器的CPU份額來確定有多少CPU資源分配,結果取決於同時執行的其他容器的CPU分配和容器中程序執行情況
可以通過cpu share 可以設定容器使用CPU的優先順序,比如啟動了兩個容器及執行檢視CPU使用百分比
執行容器 容器名字為cpu512 ;–cpu-shares 512權重是512;映象為centos:stress; stress -c 10:分配10個子程序
[root@localhost stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10 #容器產生10個子函數程序
[root@localhost stress]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f1330d9cf4b centos:stress "stress -c 10" 22 sec
[root@localhost stress]# docker exec -it 2f1330d9cf4b bash 進入容器使使用者top檢視CPU使用情況
'CPU的佔用率大概在40%左右,跑了10個程序'
[
root@localhost ~]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
2ea71fafe6df1295294ccfa895d03973eedb49865a34ac9a0b6592ec021d37bf
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ea71fafe6df centos:stress "stress -c 10" 8 seconds ago Up 7 seconds cpu1024
2f1330d9cf4b centos:stress "stress -c 10" 4 minutes ago Up 4 minutes cpu512
[root@localhost ~]# docker exec -it 2ea71fafe6df bash
[root@2ea71fafe6df /]# top
'按1檢視幾個CPU的情況'
'發現cpu1024容器的CPU佔用率大概在25%左右'
Docker提供了 --cpu-period --cpu-quota兩個引數控制容器可以分配到CPU時鐘週期
cpu-period和cpu-quota的單位是微秒。cpu-period的最小值為1000微妙,最大值為1秒,預設值為0.1秒
cpu-quota的值預設為-1,表示不做控制。Cpu-period和cpu-quota引數一般聯合使用
例如:容器程序需要每1秒使用單個CPU的0.2秒時間,可以將cpu-period設定為1000000(即1秒),cpu-quota設定為200000(0.2秒)。當然在多核情況下,如果允許容器程序完全佔用兩個CPU,則可以將cpu-period設定為100000(0.1秒),cpu-quota設定為200000(0.2秒),也就是說,0.2秒代表要使用2個核心數資源,當把一個0.1秒的核心數用完,還有0.1秒的就需要找另一個核心數去完成
[root@localhost stress]# docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress
[root@localhost stress]# docker run -tid --cpu-period 100000 --cpu-quota 200000 centos:stress
8ef8b10290ff87e6f455ab6faed35d6667e8f087ca41f3b019f12cbe95427133
[root@localhost stress]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ef8b10290ff centos:stress "/bin/bash" About a minute ago Up About a minute
[root@localhost stress]# docker exec -it 8ef8b10290ff bash
[root@8ef8b10290ff /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
100000 '重新整理週期為0.1秒'
[root@8ef8b10290ff /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
200000 '可以使用兩個CPU資源'
對多核CPU的伺服器。Docker還可以控制容器執行使用哪些CPU核心,即使用–cpuset-cpus引數
這對具有多CPU的伺服器尤其有用,可以對需要提供效能計算的容器進行效能最優的設定
[root@localhost stress]# docker run -itd --name cpu01 --cpuset-cpus 0-1 centos:stress
c07d9999818631cae0d2ee608e9d849316c87842b631ba04f57aae5d3026ef65
[root@localhost stress]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c07d99998186 centos:stress "/bin/bash" 9 seconds ago Up 8 seconds cpu01
[root@localhost stress]# docker exec -it c07d99998186 bash
[root@c07d99998186 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
[root@localhost stress]# docker exec c07d99998186 taskset -c -p 1
pid 1's current affinity list: 0,1 ''PID程序繫結到0和1上面'
[root@localhost stress]# docker exec -it c07d99998186 bash
[root@c07d99998186 /]# stress -c 10 '分配10個子程序'
'發現0和1的核心數滿載,證明是繫結在0和1的核心數上'
[root@c07d99998186 /]# top
通過cpuset-cpus引數指定容器A使用CPU核心0,容器B只是用CPU核心1
在主機上只有這兩個容器使用對應CPU核心的情況,他們各自佔用全部的核心資源,cpu-shares沒有明顯效果。
Cpuset-cpus cpuset-mems引數只在多核,多記憶體節點上的伺服器有效,並且必須與實際的物理設定匹配,否則也無法達到資源控制的目的
在系統具有多個CPU核心的情況下,需要通過cpuset-cpus引數為設定容器CPU核心才能方便進行測試
[root@localhost stress]# docker run -itd --name cpu3 --cpuset-cpus 1 centos:stress stress -c 1
32768c29c1fefff5c41556f6cbbfcc857eaadc177ed2654bec36048371db3b17
[root@localhost stress]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32768c29c1fe centos:stress "stress -c 1" 6 seconds ago Up 5 seconds cpu3
[root@localhost stress]# docker exec -it 32768c29c1fe bash
[root@32768c29c1fe /]# top
與作業系統類似,容器可使用的記憶體包括兩個部分:實體記憶體和Swap
Docker通過下面兩組引數來控制容器記憶體的使用量
執行如下命令允許該容器最多使用200M記憶體和300M的swap
–vm1:啟動1個記憶體工作執行緒
–vm-bytes 280M:每個執行緒分配280M記憶體(實體記憶體只有200M,所以會去借80M的虛擬記憶體,但是總記憶體數不能超過300M)
映象名為:progrium/stress
[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M '設定的記憶體超過限額300M'
預設情況下,所有容器能平等地讀寫磁碟,可以通過設定–blkio-weight引數來改變容器Block IO的優先順序
–blkio-weight與–cpu-shares類似,設定的是相對權重值,預設為500
[root@localhost ~]# docker run -itd --name conA --blkio-weight 600 centos:stress
'進入容器檢視設定情況'
[root@localhost stress]# docker exec -it 7b9d53a062fb bash
[root@7b9d53a062fb /]# cat /sys/fs/cgroup/blkio/blkio.weight
600 '設定的值為600'
[root@localhost stress]# docker run -itd --name conB --blkio-weight 500 centos:stress
fba42cee52fd4892b731bfefb6aa2d894e18747e72fcd79b50a0ba03c8893832
[root@localhost stress]# docker ps -a | grep conB
fba42cee52fd centos:stress "/bin/bash" 12 seconds ago Up 11 seconds
[root@localhost stress]# docker exec -it fba42cee52fd bash
[root@fba42cee52fd /]# cat /sys/fs/cgroup/blkio/blkio.weight
500
bps是byte per second 每秒讀寫的資料量
iops是 io per second 每秒IO的次數
可通過以下的引數控制容器的bps和iops
[root@localhost ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress
[root@455af49f49b7 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
[root@455af49f49b7 /]# exit '退出容器'
exit
[root@localhost ~]# docker run -it centos:stress '不限速,執行容器'
[root@9e6875fda3e8 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.980528 s, 1.1 GB/s ##發現不限速的讀寫速率是1.1GB/s