docker的資源控制(CPU、記憶體、IO)
目錄
為什麼要Docker要做資源分配,虛擬機器不需要?
容器和虛擬機器的區別:
虛擬機器不需要做,因為虛擬機器在建立的時候已經做了資源分配(配額),(虛擬CPU,虛擬記憶體,虛擬磁碟等)
而容器共享核心資源,所以需要做Cgroup,按照往年監控的資料,檢視cpu等資源的耗用情況來進行分配
一、Cgroup資源配置方法
Docker是通過Cgroup來控制容器使用的資源配額,包括CPU、記憶體、磁碟i/o三大方面,基本覆蓋了常見的資源配額和使用量控制。
Cgroup是Control Groups的縮寫,是Linux核心提供的一種可以限制、記錄、隔離程式組所使用的物理資源(如CPU、記憶體、磁碟IO等)的機制,被docker等很多專案用於實現程式資源控制。Cgroup本身是提供將程式進行分組化管理的功能和介面的基礎結構,I/O或記憶體的分配控制等具體的資源管理功能。
這些具體的資源管理功能稱為Cgroup子系統,有以下幾大子系統實現:
- blkio:設定限制每個塊裝置的輸入輸出控制。例如:磁碟,usb等
- CPU:使用排程程式為cgroup任務提供CPU的訪問。
- cpuacct:產生cgroup任務的CPU資源報告。
- cpuset:如果是多核心的cpu,這個子系統會為cgroup任務分配單獨的CPU和記憶體。
- devices:允許或拒絕cgroup任務對裝置的訪問。
- freezer:暫停和恢復cgroup任務。
- memory:設定每個cgroup的記憶體限制以及產生記憶體資源報告。
- net_cls:標記每個網路包以供cgroup方便使用。
- ns:名稱空間子系統。
- perf_event:增加了對每個group的監測跟蹤的能力,可以監測屬於某個特定的group的所有執行緒以及執行在特定CPU上的執行緒。
二、使用stress工具測試CPU和記憶體
使用Dockerfile來建立一個基於Centos的stress工具映象
[root@server1 ~]# mkdir stress
[root@server1 ~]# vim stress/Dockerfile
[root@server1 ~]# cd stress/
[root@server1 stress]# vim Dockerfile
FROM centos:7
MAINTAINER chen
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install stress
[root@server1 stress]# docker build -t centos:stress .
使用如下命令建立容器,命令中的–cpu-shares引數值不能保證可以獲得1個vcpu或者多少GHz的CPU資源,它僅是一個彈性的加權值。
[root@server1 ~]# 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。
例如:cpu時間片:1秒
容器A:50% 0.5秒
容器B:25% 0.25秒
容器C:25% 0.25秒
CPU給容器充電是在平均值層面:CPU給A容器充0.5秒,給B容器充0.25秒
可以通過cpu share可以設定容器使用cpu的優先順序,比如啟動了兩個容器及執行檢視cpu使用百分比。
[root@server1 ~]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10 #stress -c 10:容器產生10個子函式程式
[root@server1 ~]# docker exec -it d915d8464584 /bin/bash
[root@d915d8464584 /]# top
[root@server1 ~]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
[root@server1 ~]# docker exec -it 75af41079bdd /bin/bash
[root@75af41079bdd /]# top
可以發現兩個容器cpu使用率是2:1
三、CPU週期限制
Docker提供了–cpu-period、–cpu-quota兩個引數控制容器可以分配到的CPU時鐘週期。
- –cpu-period是用來指定容器對CPU的使用要在多長時間內做一次重新分配。
- –cpu-quota是用來指定在這個週期內,最多可以有多少時間來跑這個容器。
- 與–cpu-shares不同的是,這種配置是指定一個絕對值,容器對CPU資源的使用絕對不會超過配置的值。
cpu-period和cpu-quota的單位為微秒(μs)。cpu-period的最小值為1000微秒,最大值為1秒,預設值為0.1秒(100000μs)
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秒
[root@server1 ~]# docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress
fc40fe4a887829ea1c4c3de476ca550004d408aec0c1d8212f79713869543c55
[root@server1 ~]# docker ps -a
[root@server1 ~]# docker exec -it fc40fe4a8878 /bin/bash
[root@fc40fe4a8878 /]# cd /sys/fs/cgroup/cpu
[root@fc40fe4a8878 cpu]# ls
cgroup.clone_children cpu.cfs_period_us cpu.rt_runtime_us cpuacct.stat notify_on_release
cgroup.event_control cpu.cfs_quota_us cpu.shares cpuacct.usage tasks
cgroup.procs cpu.rt_period_us cpu.stat cpuacct.usage_percpu
[root@fc40fe4a8878 cpu]# cat cpu.cfs_period_us
100000
[root@fc40fe4a8878 cpu]# cat cpu.cfs_quota_us
200000
四、CPU Core控制
對多核CPU的伺服器,Docker還可以控制容器執行使用哪些CPU核心,即使用–cpuset-cpus引數。這對具有多CPU的伺服器尤其有用,可以對需要高效能運算的容器進行效能最優的配置。
[root@server1 ~]# docker run -tid --name cpu1 --cpuset-cpus 0-1 centos:stress
執行以上命令表示建立的容器只能用0、1兩個cpu。最終生成的cgroup的cpu核心配置如下:
[root@server1 ~]# docker exec -it eefe294955f8 bash
[root@eefe294955f8 /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
[root@eefe294955f8 /]# stress -c 5 & #讓容器產生5個子函式程式,並在後臺執行
[root@eefe294955f8 /]# top #使用top命令檢視cpu工作情況(top進去後按1,顯示每個cpu的工作情況)
通過下面指令可以看到容器中程式與cpu核心的繫結關係
[root@server1 ~]# docker exec eefe294955f8 taskset -c -p 1 表示容器中第一個程式pid為1被繫結到cpu1和2上
pid 1's current affinity list: 0,1
五、CPU配額控制引數的混合使用
通過 cpuset-cpus 引數指定容器 A 使用 CPU 核心 0,容器 B 只是用 CPU 核心 1。
在主機上只有這兩個容器使用對應 CPU 核心的情況,它們各自佔用全部的核心資源,cpu-shares 沒有明顯效果。
cpuset-cpus、cpuset-mems 引數只在多核、多記憶體節點上的伺服器上有效,並且必須與實際的物理配置匹配,否則也無法達到資源控制的目的。
在系統具有多個 CPU 核心的情況下,需要通過 cpuset-cpus 引數為設定容器 CPU 核心才能方便地進行測試。
#建立容器cpu10,僅使用cpu1核心,加權值為512
[root@server1 ~]# docker run -itd --name cpu10 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
f885714260cb56310b521d77f3f69db906ea582d28c843297f5d31be59b149d4
[root@server1 ~]# docker exec -it f885714260cb bash
[root@f885714260cb /]# top
建立容器cpu12,僅使用cpu1核心,加權值為1024
[root@server1 ~]# docker run -itd --name cpu12 --cpuset-cpus 1 --cpu-shares 1024 centos:stress stress -c 1
對比cpu使用佔比
六、記憶體限額
與作業系統類似,容器可使用的記憶體包括兩部分: 實體記憶體和Swap
Docker通過下面兩組引數來控制容器記憶體的使用量。
- -m或–memory:設定記憶體的使用限額,例如100M、1024M
- –memory-swap:設定記憶體+swap的使用限額
執行如下命令允許該容器最多使用200M的記憶體和300M的swap
[root@server1 ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
--vm 1:啟動1個記憶體工作執行緒
--vm-bytes 280M:每個執行緒分配280M記憶體
預設情況下,容器可以使用主機上的所有空閒記憶體。
與cpu的cgroups配置類似,Docker會自動為容器在目錄/sys/fs/cgroup/memory/docker/<容器的完整長id>中建立相應cgroup配置檔案
注意:如果讓工作執行緒分配的記憶體超過300M,分配的記憶體超過限額,stress執行緒報錯,容器退出。
[root@server1 ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
七、bps和iops的限制
bps是byte per second,每秒讀寫的資料量。
iops是io per second,每秒io的次數。
可通過以下引數控制容器的bps和iops:
–device-read-bps,限制讀某個裝置的bps。
–device-write-bps,限制寫某個裝置的bps。
–device-read-iops,限制讀某個裝置的iops。
–device-write-iops,限制寫某個裝置的iops。
示例:限制容器寫/dev/sda的速率為5MB/s。
[root@server1 ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress
[root@b4bb0fbc1c44 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
^C28+0 records in
28+0 records out
29360128 bytes (29 MB) copied, 5.60286 s, 5.2 MB/s
通過dd命令測試在容器中寫磁碟的速度是否為5MB/s。因為容器的檔案系統是在主機/dev/sda上的,在容器中寫檔案相當於對主機/dev/sda進行寫操作。另外,oflag=direct指定用direct IO方式寫檔案,這樣 --device-write-bps才能生效。
結果表明限速5MB/s左右。作為對比測試,如果不限速,結果如下:
[root@server1 ~]# docker run -it centos:stress
[root@34a3a0f91892 /]# 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.830403 s, 1.3 GB/s
八、Block IO 的限制
預設情況下,所有容器能平等地讀寫磁碟,可以通過設定–blkio-weight 引數來改變 容器 block IO 的優先順序。
–blkio-weight 與 --cpu-shares 類似,設定的是相對權重值,預設為 500。
在下面 的例子中,容器 A 讀寫磁碟的頻寬是容器 B 的兩倍。
[root@server1 ~]# docker run -it --name nameA --blkio-weight 800 centos:stress
[root@97a7d9a7893c /]# cat /sys/fs/cgroup/blkio/blkio.weight
800
[root@server1 ~]# docker run -it --name nameB --blkio-weight 300 centos:stress
[root@ffab8c022b42 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300
相關文章
- 如何使用 Docker 來限制 CPU、記憶體和 IO等資源?Docker記憶體
- Cgroups控制cpu,記憶體,io示例記憶體
- 在Docker中,如何控制容器佔用系統資源(CPU,記憶體)的份額?Docker記憶體
- Oracle 12c系列(四)|資源隔離之IO、記憶體、CPUOracle記憶體
- CPU、記憶體、磁碟IO之間的關係記憶體
- 效能調優(cpu/IO/JVM記憶體分析)JVM記憶體
- 微服務體系-docker容器cpu記憶體管理微服務Docker記憶體
- Docker之CPU和記憶體磁碟設定(八)Docker記憶體
- Docker CPU資源限制Docker
- 統計和分析系統效能【IO CPU 記憶體】的工具集合記憶體
- 記憶體與IO,磁碟IO,網路IO記憶體
- CPU快取記憶體快取記憶體
- 記憶體CPU監控記憶體
- 為容器指定cpu和記憶體資源(k8s官翻)記憶體K8S
- 資源供給:記憶體和虛擬記憶體記憶體
- 資源記憶體佔用記憶體
- Docker CPU 資源限制——CPU分片功能測試Docker
- Linux下如何檢視哪些程式佔用的CPU記憶體資源最多Linux記憶體
- io記憶體,io埠,彙編 in out 指令記憶體
- RMAN的IO記憶體緩衝區記憶體
- 查詢最佔資源、CPU、記憶體、和執行最長的SQL語句記憶體SQL
- linux下獲取佔用CPU和記憶體資源最多的10個程式Linux記憶體
- aix/linux下監控主機資源(cpu 記憶體等)使用的工具nmonAILinux記憶體
- Docker CPU 資源限制——CPU固定核功能測試Docker
- CPU和記憶體如何互動的記憶體
- 資源供給:再談記憶體和虛擬記憶體記憶體
- 【功能筆記】Ubuntu檢視系統資源佔用(記憶體,cpu和程式) {轉載}筆記Ubuntu記憶體
- Docker執行資源控制Docker
- 利用Kubernetes名稱空間來管理記憶體和CPU資源(二)記憶體
- 利用Kubernetes名稱空間來管理記憶體和CPU資源(一)記憶體
- 談談CPU快取記憶體快取記憶體
- CPU快取和記憶體屏障快取記憶體
- SUSE檢視CPU和記憶體記憶體
- 控制C++的記憶體分配C++記憶體
- Windows xp如何節約記憶體資源Windows記憶體
- 多核cpu、cpu快取記憶體、快取一致性協議、快取行、記憶體快取記憶體協議
- 記憶體屏障在CPU、JVM、JDK中的實現記憶體JVMJDK
- KVM之十一:調整cpu和記憶體記憶體