docker(八):Docker資源限制

  默認狀況下,一個容器是沒有任何資源限制的,它可以耗盡當前主機內核可以調度給容器的全部資源,就像擁有飢餓者能力的豬頭帝同樣,永遠吃不飽。這顯然是不合理的,由於資源吃多了會被制裁的。在 linux 系統中,若是內核探測到當前主機已經沒有可用的內存分配給某些重要的系統進程,它就會啓動 OOM killer 或者觸發 kernel panic,詳情請查看另外一篇文章Linux OOM killer。OOM killer 會殺死符合條件的進程,docker daemon 也有可能會被 kill。爲此 docker 調整了 docker daemon 的 OOM 優先級,可是 docker container的優先級沒有被調整啊,怎麼辦?小場面,道友慢慢聽我道來。html

  docker run 有參數來調整 docker container 的 oom_score,使之不會被幹掉,且調完優先級後咱們仍然是須要限制 dockercontainer 的資源使用的,否則用完了宿主機的資源,別的系統進程就木得用了,限制資源分爲 Memory 和 CPU 兩塊。linux

Memory Limit

  • Introductiondocker

    • 每個參數指定的值的單位能夠是b/k/m/g
  • Argumentsapi

    • -m or --memoryapp

      • 限制一個容器可用的物理內存,此參數最小值爲4M
    • --memory-swap *ide

      • 限制一個容器可使用交換分區的大小,此參數只有在設置了 -m 時纔有意義。值有下表中的幾種狀況。
      • 容器中使用 free 命令看到的信息沒有意義,具體還要根據表格中的方式計算。
    • --memory-swappiness函數

      • 控制進程將物理內存交換到swap分區的傾向,默認係數爲60。係數越小,就越傾向於使用物理內存。取值範圍爲0-100。
      • 當值爲0時,表示儘可能不使用swap分區。
      • 當值爲100時,表示儘可能使用swap分區。
      • 若是不設置,則值從主機繼承。
    • --memory-reservation性能

      • 啓用彈性的內存共享,當宿主機資源充足時,容許容器儘可能多地使用內存,當檢測到內存競爭或者低內存時,強制將容器的內存下降到 memory-reservation 所指定的內存大小。按照官方說法,不設置此選項時,有可能出現某些容器長時間佔用大量內存,致使性能上的損失。
    • --kernel-memory測試

      • 內核內存,不會被交換到swap上。通常狀況下,不建議修改。
    • --oom-kill-disableui

      • 禁止容器被 OOM killer 殺掉。前提是已經設置了-m。
-m or --memory --memory-swap 功能
正數 M 正數 N 容器的可用總空間爲 N,其中物理內存爲 M,swap 爲 N-M;若N=M,則表示無可用 swap 資源。
正數 M 0 至關於未設置 swap。
正數 M unset 若宿主機啓用了 swap,則容器的可用 swap 爲 2*M。
正數 M -1 若宿主機啓用了 swap,則容器可最大可以使用主機上的全部swap資源。
  • Example
# 爲了防止容器不會由於OOM而被kill掉,就須要在docker run啓動時加上這個參數--oom-kill-disable或者指定--oom-score-adj--oom-score-adj的值爲-1000
# 爲了測試出限制效果,咱們須要用到一個叫作stress的壓力測試鏡像。
[root@docker1 ~]# docker search stress
NAME                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
progrium/stress                                                           29                                      [OK]
polinux/stress            Stress tool in a Docker (Alpine) Raspberry P…   8                                       [OK]
[root@docker1 ~]# docker pull polinux/stress
# 查看命令的幫助信息,會看到有這麼一條示例信息
`stress' imposes certain types of compute stress on your system

Usage: stress [OPTION [ARG]] ...
 -?, --help                顯示幫助信息
     --version            顯示版本號
 -v, --verbose          詳細顯示
 -q, --quiet               靜默模式
 -n, --dry-run           顯示已完成的指令狀況
 -t, --timeout N        指令運行N秒後中止
     --backoff N         等待N微秒後開始運行
 -c, --cpu N              產生N個進程,每一個進程反覆計算隨機數的平方根
 -i, --io N                  產生N個進程,每一個進程反覆調用sync()將內存中的內容寫入到磁盤。
 -m, --vm N              產生N個進程,每一個進程不斷分配和釋放內存。
     --vm-bytes B      指定分配內存的大小,默認256M
     --vm-stride B      不斷的給部份內存賦值,讓COW發生。
     --vm-hang N       指定每一個消耗內存的進程在分配到內存後轉入睡眠狀態N秒,而後釋放內存,一直重複執行這個過程。
     --vm-keep           一直佔用內存,區別於不斷釋放並從新分配內存
 -d, --hdd N              產生N個不斷執行 write 和 unlink 函數的進程(建立文件,寫入內容,刪除文件)
     --hdd-bytes B      指定建立的文件大小

Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
# 測試內存限制。-m參數指定了容器最多使用256M內存,使用stress進行壓力測試,我沒有指定--vm-bytes,默認256M,因此2和進程最可能是會用到512M內存。
[root@docker1 ~]# docker run --name stress -it -m 256m --rm polinux/stress:latest stress --vm 2
# 新打開窗口查看容器使用資源情況,會發現限制成功。
[root@docker1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
24adcc32c8cb        stress              41.63%              256MiB / 256MiB   100%              508B / 0B           303kB / 239MB       3
# 若是docker run有報以下信息,是由於stress指定分配的內存超過了docker run -m預設值的兩倍。-m 指定個257m就不會自動退出了。
[root@docker1 ~]# docker run --name stress -it -m 256m --rm polinux/stress:latest stress --vm 2
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 2 vm, 0 hdd
stress: FAIL: [1] (415) <-- worker 7 got signal 9
stress: WARN: [1] (417) now reaping child worker processes
stress: FAIL: [1] (451) failed run completed in 7s

CPU Limit

  • Introduction

    • 默認狀況下,每個容器均可以無限制使用宿主機上的全部CPU資源。咱們能夠經過一些參數去限制它。
    • 1.13版本之前的docker只支持CFS調度器(非實時進程調度器);1.13版本以後支持Realtime調度器(實時進程調度器)。
  • Arguments

    • --cpus=<value>

      • 按照下面--cpu-shares的舉例,假如是四核CPU,容器B不用,容器A就能用400%?顯然不合理,因此可使用--cpus來限制容器可使用的CPU核數。例如--cpus=0.5。
    • --cpu-period=<value>

      • 限制容器最多能使用CPU多長時間,默認100微秒。1.13版本後可使用--cpus替代。
    • --cpu-quota=<value>

      • 更精細的CPU限制。1.13版本後可使用--cpus替代。
    • --cpuset-cpus

      • 限制容器只能使用哪一個CPU核心。上面使用--cpus設置容器可使用的CPU核數,但限制不了使用哪一個核心,這個使用量可能在覈心1上,也多是核心2上,也多是各使用一部分。
    • --cpu-shares

      • 設置爲共享式CPU,按權重的比例來分配,這是一個軟限制。好比容器A權重爲512,容器B權重爲1024,那CPU的資源將分紅三份,容器A佔1/3,容器B佔2/3;假如容器B用不到CPU的計算能力,那容器A將擁有CPU所有使用權。
  • Example

# 這裏咱們依然使用stress來作CPU的壓力測試。由於我只有一核,因此--cpu的預設值能夠設置爲1或者忽略此選項。
[root@docker1 ~]# cat /proc/cpuinfo| grep "processor"| wc -l
1
[root@docker1 ~]# docker run --name stress -it --cpus 1 --rm polinux/stress:latest stress --cpu 8
# 使用top命令看到有8個子進程
[root@docker1 ~]# docker top stress        
[root@docker1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e8fc27bd1897        stress              99.93%              128KiB / 976.3MiB   0.01%               648B / 0B           0B / 0B             9
# 有時會稍稍超過100%,是正常的。若是是多核CPU,還能夠加上--cpuset-cpus的參數來限制容器只能使用哪一個核心,好比--cpuset-cpus 0,2。限制容器只能使用第一個核心和第三個核心。還可以使用--cpu-shares來共享CPU資源,好比四核CPU,起兩個容器,而後查看stats,會發現,兩個容器的CPU使用量加起來在400%左右。這裏就不演示了,命令以下:
[root@docker1 ~]# docker run --name stress01 -it --cpu-shares 512 --rm polinux/stress:latest stress --cpu 8
[root@docker1 ~]# docker run --name stress02 -it --cpu-shares 1024 --rm polinux/stress:latest stress --cpu 8

   

寫做不易,轉載請註明出處,謝謝~~

相關文章
相關標籤/搜索