十一、Docker的资源限制
十一、Docker的资源限制

十一、Docker的资源限制

11.1 容器资源限制

11.1.1 容器资源限制介绍

官方文档:https://docs.docker.com/config/containers/resource_constraints/

默认情况下,容器没有资源的使用限制,可以使用主机内核调度程序允许的尽可能多的资源

Docker提供了控制容器使用资源的方法,可以限制容器使用多少内存或CPU等,在docker run命令运行时配置标志实现资源限制功能

其中许多功能都要求宿主机的内核支持,要检查是否支持这些功能,可以使用docker info命令,如果内核中禁用了某项功能可能会在输出结尾处看到警告,如下所示:

WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.

可以通过修改内核参数消除以上警告

官方文档:https://docs.docker.com/engine/install/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilities

root@ubuntu-2010:~# vim /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

root@ubuntu-2010:~# update-grub

11.1.2 OOM (out of Memory Exception)

对于Linux主机,如果没有足够的内存来执行其他重要的系统任务,将会抛出OOM(Out of Memory Exception,内存溢出、内存泄漏、内存异常),随后系统会开始杀死进程以释放内存,凡事运行在宿主机的进程都有可能被kill,包括dockerd和其他的应用程序,如果重要的系统进程被kill,会导致和该进程相关的服务全部宕机。通常越小号内存比较大的应用越容易被kill,比如:MySQL数据库,Java程序等

模拟OOM

产生OOM异常时,dockerd尝试通过调整docker守护进程上的OOM优先级来减轻这些风险,以便它比系统上的其他进程更不可能被杀死但是对每个容器的OOM优先级并未调整,这使得单个容器被杀死的可能性比Dokcer守护程序或其他系统进程被杀死的可能性更大,不推荐通过在守护程序或容器上手动设置– oom -score-adj为极端负数,或通过在容器上设置– oom-kill-disable来绕过这些安全措施

OOM的优先级机制:

linux会为每个进程计算一个分数,最终将分数最高的kill

/proc/PID/oom_score_adj
#范围为 -1000 到 1000,值越高容易被宿主机 kill掉,如果将该值设置为 -1000 ,则进程永远不会被
宿主机 kernel kill

/proc/PID/oom_adj
#范围为 -17 到+15 ,取值越高越容易被干掉,如果是 -17 , 则表示不能被 kill ,该设置参数的存在
是为了和旧版本的 Linux 内核兼容。

/proc/PID/oom_score
#这个值是系统综合进程的内存消耗量、 CPU 时间 (utime + 、存活时间 (uptime - start time)
和 oom_adj 计算出的进程得分 ,消耗内存越多得分越高,容易被宿主机kernel 强制杀死

11.2 容器的内存限制

Docker可以强制执行硬性内存限制,即只允许容器使用给定的内存大小。

Docker也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内核检测到主机上的内存不够用了

11.2.1 内存相关选项

以下设置大部分的选项取正整数,跟着一个后缀b,k,m,g,表示字节,千字节,兆字节或千兆字节

选项描述
-m, --memory=容器可以使用的最大物理内存量,硬限制,此选项最小允许值为4m(4MB),此项较为常用
--memory-swap*允许此容器交换到磁盘的内存量,必须先用-m 对内存限制才可以使用
--memory-swappiness设置容器使用交换分区的倾向性,值越高表示越倾向于使用swap分区,范围为0-100,0为能不用就不用,100为能用就用,N表示内存
使用率达到N%时,就会时候swap空间
--memory-reservation允许指定小于–memory的软限制,当Docker检测到主机上的争用或内存不足时会激活该限制,如果使用–memory-reserva
tion,则必须将其设置为低于–memory才能使其优先生效。因为它是软限制,所以不能保证容器不超过限制
--kernel-memory容器可以使用的最大内核内存量,最小为4m,由于内核内存与用户空间内存隔离,因此无法与用户空间内
存直接交换,因此内核内存不足的容器可能会阻塞宿主机资源,这会对主机和其他容器或者其他服务进程产生影响,因此不要设置内核内存大小
--oom-kill-disable默认情况下,如果发生内存不足(OOM)错误,则内核将终止容器中的进程。要更改此行为,请使用--oom-kill-disable选项。
仅在设置了该-m/--memory选项的容器上禁用OOM。如果-m未设置该标志,则主机可能会用完内存,内核可能需要终止主机系统
的进程以释放内存

11.2.2 swap限制

--memory-swap #只有在设置了 --memory 后才会有意义。使用 Swap,可以让容器将超出限制部分的内
存置换到磁盘上,WARNING: 经常将内存交换到磁盘的应用程序会降低性能

不同的–memory-swap设置会产生不同的效果:

–memory-swap–memory功能
正数S正数M容器可用内存总空间为S,其中RAM为M,swap为S-M,若S=M,则无可用swap资源
0正数M相当于未设置swap(unset)
unset正数M若主机(Docker Host)启用了swap,则容器的可用swap为2*M
-1正数M若主机(Docker Host)启用了swap,则容器可使用最大至主机上所有swap空间
--memory-swap #值为正数, 那么--memory 和--memory-swap 都必须要设置,--memory-swap 表示
你能使用的内存和 swap 分区大小的总和,例如: --memory=300m, --memory-swap=1g, 那么该容
器能够使用 300m 物理内存和 700m swap,即--memory 是实际物理内存大小值不变,而 swap 的实际
大小计算方式为(--memory-swap)-(--memory)=容器可用 swap
--memory-swap #如果设置为 0,则忽略该设置,并将该值视为未设置,即未设置交换分区
--memory-swap #如果等于--memory 的值,并且--memory 设置为正整数,容器无权访问 swap
-memory-swap #如果未设置,如果宿主机开启了 swap,则实际容器的swap 值最大为 2x( --
memory),即两倍于物理内存大小,例如,如果--memory="300m"与--memory-swap没有设置,该容器可
以使用300m总的内存和600m交撒空间,但是并不准确(在容器中使用free 命令所看到的 swap 空间并不精
确,毕竟每个容器都可以看到具体大小,宿主机的 swap 是有上限的,而且不是所有容器看到的累计大小)
--memory-swap #如果设置为-1,如果宿主机开启了 swap,则容器可以使用主机上 swap 的最大空间

注意:在容器中执行free命令看到的是宿主机的内存和swap使用,而非容器自身的swap使用情况

root@ubuntu-18:~# free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       706Mi       480Mi        16Mi       762Mi       1.0Gi
Swap:         4.0Gi          0B       4.0Gi

root@ubuntu-18:~# docker run -ti --rm -m 2G --memory-swap 3g centos bash
[root@2bbc5b86cc59 /]# free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       742Mi       443Mi        16Mi       763Mi       1.0Gi
Swap:         4.0Gi          0B       4.0Gi

11.2.3 stress-ng 压力测试工具

stress-ng是一个压力测试工具,可以通过软件仓库进行安装,也提供了docker版本的容器

  • 软件包安装
#centos8由epel源提供
[root@centos8-1 ~]# yum -y install stress-ng

#ubuntu
root@ubuntu-18:~# apt -y install stress-ng
  • 容器方式安装
root@ubuntu-18:~# docker pull lorel/docker-stress-ng
Using default tag: latest
latest: Pulling from lorel/docker-stress-ng
Image docker.io/lorel/docker-stress-ng:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
c52e3ed763ff: Pull complete 
a3ed95caeb02: Pull complete 
7f831269c70e: Pull complete 
Digest: sha256:c8776b750869e274b340f8e8eb9a7d8fb2472edd5b25ff5b7d55728bca681322
Status: Downloaded newer image for lorel/docker-stress-ng:latest
docker.io/lorel/docker-stress-ng:latest

root@ubuntu-18:~# docker images
REPOSITORY               TAG       IMAGE ID       CREATED       SIZE
lorel/docker-stress-ng   latest    1ae56ccafe55   5 years ago   8.1MB

查看帮助:

root@ubuntu-18:~# docker run -it --rm lorel/docker-stress-ng
stress-ng, version 0.03.11

Usage: stress-ng [OPTION [ARG]]
--h, --help show help
--affinity N start N workers that rapidly change CPU affinity
--affinity-ops N stop when N affinity bogo operations completed
--affinity-rand change affinity randomly rather than sequentially
--aio N start N workers that issue async I/O requests
--aio-ops N stop when N bogo async I/O requests completed
--aio-requests N number of async I/O requests per worker
......
--zero-ops N stop when N /dev/zero bogo read operations completed
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s
Note: Sizes can be suffixed with B,K,M,G and times with s,m,h,d,y

假如一个容器未做内存使用限制,则该容器可以利用到系统内存最大空间,默认创建的容器没有做内存资源限制。

范例:默认一个workers分配256M内存,2个即占512M内存

root@ubuntu-18:~# docker run --name c1 -ti --rm lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

#因为上一个命令是前台执行,下面在另一个终端窗口执行,可以看到占用512M内存左右
root@ubuntu-18:~# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
946c2116dc5c   c1        198.97%   517.1MiB / 1.904GiB   26.52%    726B / 0B   35.3MB / 0B   5

范例:指定内存最大值

root@ubuntu-18:~# docker run --name c1 -ti --rm -m 300m lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

#在另一个终端执行
root@ubuntu-18:~# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O         PIDS
20fcd04ada9e   c1        142.23%   299.9MiB / 300MiB   99.97%    976B / 0B   28.2GB / 8.19kB   5

范例:OOM

root@ubuntu-18:~# docker run -ti --rm lorel/docker-stress-ng --vm 14
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 14 vm

#另一个终端窗口同事执行下面命令
root@ubuntu-18:~# docker run -ti --rm lorel/docker-stress-ng --vm 14
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 14 vm

#注意启动数量不要直接把systemd关了

root@ubuntu-18:~# docker stats
CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT   MEM %     NET I/O   BLOCK I/O   PIDS
043a2ee51aef   beautiful_leakey   --        -- / --             --        --        --          --
               --                 --        -- / --             --        --        --          --

#观察日志出现00M现象
root@ubuntu-18:~# tail /var/log/syslog 
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680264] [ 5732]     0  5732    67111    27737   585728    38809          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680265] [ 5733]     0  5733    67111    33613   585728    32933          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680265] [ 5734]     0  5734    67111    45249   585728    21295          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680266] [ 5735]     0  5735    67111    35368   585728    31176          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680267] [ 5736]     0  5736    67111    30551   585728    35992          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680267] [ 5737]     0  5737    67111    34057   585728    32489          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680268] [ 5738]     0  5738    67111    38014   585728    28532          1000 stress-ng-vm
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680268] Out of memory: Kill process 5725 (stress-ng-vm) score 1033 or sacrifice child
Sep 26 20:58:48 ubuntu-18 kernel: [  230.680291] Killed process 5725 (stress-ng-vm) total-vm:268444kB, anon-rss:127584kB, file-rss:564kB, shmem-rss:32kB
Sep 26 20:58:48 ubuntu-18 kernel: [  230.697920] oom_reaper: reaped process 5725 (stress-ng-vm), now anon-rss:0kB, file-rss:0kB, shmem-rss:32kB

范例:查看内存限制

#启动两个工作进程,每个工作进程最大允许使用内存 256M,且宿主机不限制当前容器最大内存
root@ubuntu-18:~# docker run -ti --rm lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

root@ubuntu-18:~# docker ps -a
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS     NAMES
ed4ee22d7dba   lorel/docker-stress-ng   "/usr/bin/stress-ng …"   8 seconds ago   Up 7 seconds             exciting_jennings

root@ubuntu-18:~# ls /sys/fs/cgroup/memory/docker/ed4ee22d7dba695740ac277ec5417e5aefc9e52b6c08463e078653e7fa9246b1/
cgroup.clone_children  memory.kmem.limit_in_bytes          memory.kmem.tcp.usage_in_bytes  memory.memsw.max_usage_in_bytes  memory.soft_limit_in_bytes  tasks
cgroup.event_control   memory.kmem.max_usage_in_bytes      memory.kmem.usage_in_bytes      memory.memsw.usage_in_bytes      memory.stat
cgroup.procs           memory.kmem.slabinfo                memory.limit_in_bytes           memory.move_charge_at_immigrate  memory.swappiness
memory.failcnt         memory.kmem.tcp.failcnt             memory.max_usage_in_bytes       memory.numa_stat                 memory.usage_in_bytes
memory.force_empty     memory.kmem.tcp.limit_in_bytes      memory.memsw.failcnt            memory.oom_control               memory.use_hierarchy
memory.kmem.failcnt    memory.kmem.tcp.max_usage_in_bytes  memory.memsw.limit_in_bytes     memory.pressure_level            notify_on_release

root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/ed4ee22d7dba695740ac277ec5417e5aefc9e52b6c08463e078653e7fa9246b1/memory.limit_in_bytes 
9223372036854771712
root@ubuntu-18:~# echo 2^63 | bc
9223372036854775808

范例:内存限制200m

root@ubuntu-18:~# docker run -ti --rm -m 200m lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O        PIDS
2fd07fac41ca   vigilant_ride   201.54%   200MiB / 200MiB     99.99%    766B / 0B   150MB / 3.58GB   5
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/2fd07fac41cae4daeb2b1ef8c5e4a4a5bb5e2cb762cfc42b60cd17a13c1f0b2f/memory.limit_in_bytes 
209715200
root@ubuntu-18:~# echo 209715200/1024/1024 | bc
200

#动态修改内存限制
root@ubuntu-18:~# echo 300*1024*1024 | bc
314572800
root@ubuntu-18:~# echo 314572800 > /sys/fs/cgroup/memory/docker/2fd07fac41cae4daeb2b1ef8c5e4a4a5bb5e2cb762cfc42b60cd17a13c1f0b2f/memory.limit_in_bytes
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/2fd07fac41cae4daeb2b1ef8c5e4a4a5bb5e2cb762cfc42b60cd17a13c1f0b2f/memory.limit_in_bytes
314572800
root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O         PIDS
2fd07fac41ca   vigilant_ride   189.37%   299.9MiB / 300MiB   99.96%    1.05kB / 0B   2.84GB / 59.1GB   5

#通过echo命令可以改内存限制的值,但是只能在原基础上增大内存限制,缩小内存限制会报错
root@ubuntu-18:~# echo 209715200 > /sys/fs/cgroup/memory/docker/2fd07fac41cae4daeb2b1ef8c5e4a4a5bb5e2cb762cfc42b60cd17a13c1f0b2f/memory.limit_in_bytes
-bash: echo: write error: Device or resource busy
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/2fd07fac41cae4daeb2b1ef8c5e4a4a5bb5e2cb762cfc42b60cd17a13c1f0b2f/memory.limit_in_bytes
314572800

范例:内存大小软限制

root@ubuntu-18:~# docker run -ti --rm -m 256m --memory-reservation 128m lorel/docker-stress-ng --vm 2 --vm-bytes 256m
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O        PIDS
877bfca51d5d   stoic_matsumoto   178.06%   255.9MiB / 256MiB   99.97%    766B / 0B   306MB / 2.32GB   5

#查看硬限制
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/877bfca51d5d14c000edcac65648ee35c4a12fc8bf96e826941256b6abe690d3/memory.limit_in_bytes 
268435456

#查看软限制
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/877bfca51d5d14c000edcac65648ee35c4a12fc8bf96e826941256b6abe690d3/memory.soft_limit_in_bytes 
134217728

#软限制不能高于硬限制
root@ubuntu-18:~# docker run -ti --rm -m 256m --memory-reservation 257m lorel/docker-stress-ng --vm 2 --vm-bytes 256m
docker: Error response from daemon: Minimum memory limit can not be less than memory reservation limit, see usage.
See 'docker run --help'.

范例:关闭OOM机制

#查看docker OOM机制默认值
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/memory.oom_control 
oom_kill_disable 0
under_oom 0
oom_kill 0


#启动容器时关闭OOM机制
root@ubuntu-18:~# docker run -ti --rm -m 200m --oom-kill-disable lorel/docker-stress-ng -vm 2 --vm-bytes 256m

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O    PIDS
c884d6d6be43   busy_cannon   0.00%     200MiB / 200MiB     100.00%   836B / 0B   0B / 211MB   5
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/c884d6d6be4354078a98f3acca8f35a97e8d2b42975bebd953ede551c291d8f9/memory.oom_control 
oom_kill_disable 1
under_oom 1
oom_kill 0

范例:交换分区限制

root@ubuntu-18:~# docker run -ti --rm -m 200m --memory-swap 512m lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

root@ubuntu-18:~# docker ps -a
CONTAINER ID   IMAGE                    COMMAND                  CREATED              STATUS              PORTS     NAMES
3dc448647c14   lorel/docker-stress-ng   "/usr/bin/stress-ng …"   About a minute ago   Up About a minute             nostalgic_burnell
root@ubuntu-18:~# cat /sys/fs/cgroup/memory/docker/3dc448647c14ccb88c5905c4bf06f983362f7cc3e5de525012805ec205cabece/memory.memsw.limit_in_bytes 
536870912
root@ubuntu-18:~# echo 536870912/1024/1024 | bc
512

11.3 容器的CPU限制

11.3.1 容器的CPU限制介绍

官方文档说明:https://docs.docker.com/config/containers/resource_constraints/

一个宿主机,有几十个核心的CPU,但是宿主机上可以同时运行成百上千个不同的进程用以处理不同的任务,多进程共用一个CPU的核心为可压缩资源,即一个核心的CPU可以通过调度而运行多个进程,但是同一个单位时间内只能有一个进程在CPU上运行,那个这么多的进程怎么在CPU上执行和调度的?

Linux kernel 进程调度基于CFS(Completely Fair Scheduler),完全公平调度

服务器资源密集型

  • CPU 密集型的场景:优先级越低越好,计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、数据处理、对视频进行高清解码等等,全靠CPU的运算能力。
  • IO密集型的场景:优先级值高点,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度),比如web应用,高并发,数据量大的动态网站来说,数据库应该为IO密集型

CFS原理

cfs定义了进程调度的新模型,它给cfs_rq(cfs的run queue)中的每一个进程安排一个虚拟时钟vruntime。如果一个进程得以执行,随着时间的增长,其vruntime将不断增大。没有得到执行的进程vruntime不变,而调度器总是选择vruntime跑得最慢的那个进程来执行。这就是所谓的“完全公平”。为了区别不同优先级的进程,优先级高的进程vruntime增长得慢,以至于它可能得到更多的运行机会。CFS的意义在于,在一个混杂着大量计算型进程和IO交互进程的系统中,CFS调度器相对其它调度器在对待IO交互进程要更加友善和公平

11.3.2 配置默认的CFS调度程序

默认情况下,每个容器对主机的CPU周期的访问都是不受限制的。可以设置各种约束,以限制给定容器对主机CPU周期的访问。大多数用户使用并配置默认的CFS调度程序。在Docker1.13及更高版本中,还可以配置realtime scheduler

CFS是用于常规Linux进程的Linux内核CPU调度程序。通过几个运行时标志,可以配置对容器拥有的CPU资源访问量。使用这些设置时,Docker会在主机上修改容器cgroup的设置。

选项描述
--cpus=指定一个容器可以使用多少个可用的CPU核心资源。例如,如果主机有两个CPU,如果设置了--cpus="1.5",则可以保证容器最多使用1.5个的cpu
(如果是4核CPU,那么还可以是4核心上每核心用一点,但是总计是1.5核心的CPU)。这相当于设置--cpu-period="100000"--cpu-quota="150000"
此设置可在Docker1.13以及更高版本中可用,目的是替代–cpu-period和–cpu-quota两个参数,从而使配置更简单,但是最大不能超出宿主机的CPU
总核心数(在操作系统看到的CPU超线程后的数值),此项较为常用
--cpu-period=指定CPU CFS调度程序周期,必须与--cpu-quota一起使用。默认为100微秒。大多数用户不会更改默认设置。如果使用Docker1.13或更高版本,请改用--cpus
--cpu-quota=在容器上添加CPU CFS配额,计算方式为cpu-quota/cpu-period的结果值,docker1.13以及更高的版本通常使用--cpus=设置此值
--cpuset-cpus用于指定容器运行的CPU编号,也就是所谓的CPU绑定。如果一个或多个CPU,则容器可以使用逗号分隔的列表或用连字符分隔的CPU范围。
第一个CPU的编号为0。有效值可能是0-3(使用第一、第二、第三和第四CPU)或1,3(使用第二和第四CPU)
--cpu-shares用于设置cfs中调度的相对最大比例权重,cpu-share的值越高的容器,将会分得更多的时间片(宿主机多核CPU总数为100%,假如容器A为1024,
容器B为2048,那么容器B将最大是容器A的可用CPU的两倍),默认时间片1024,最大262144。这是一个软限制

11.3.3 使用stress-ng测试cpu配置

范例:查看stress-ng关于cpu的帮助

-root@ubuntu-18:~# docker run -ti --rm --name c1 lorel/docker-stress-ng | grep cpu
 -c N, --cpu N            start N workers spinning on sqrt(rand())
       --cpu-ops N        stop when N cpu bogo operations completed
 -l P, --cpu-load P       load CPU by P %%, 0=sleep, 100=full load (see -c)
       --cpu-method m     specify stress cpu method m, default is all
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

范例:不限制容器CPU

root@ubuntu-18:~# lscpu | grep CPU
CPU op-mode(s):      32-bit, 64-bit
CPU(s):              4
On-line CPU(s) list: 0-3
CPU family:          23
CPU MHz:             1996.251
NUMA node0 CPU(s):   0-3

root@ubuntu-18:~# docker run -ti --rm lorel/docker-stress-ng --vm 6
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 6 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
23828dba0be0        awesome_kare        399.66%             1.528GiB / 3.83GiB   39.91%              836B / 0B           0B / 0B             13

root@ubuntu-18:~# cat /sys/fs/cgroup/cpuset/docker/23828dba0be019a3515db1da6e263d43bf9dbae74bba325c029e7f4fffada9e4/cpuset.cpus
0-3
root@ubuntu-18:~# top

范例:限制使用CPU

root@ubuntu-18:~# docker run -ti --rm --cpus 1.5 lorel/docker-stress-ng --cpu 2 --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 cpu, 2 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
c46d64929552        hungry_cartwright   149.58%             533.1MiB / 3.83GiB   13.59%              836B / 0B           0B / 0B             7

root@ubuntu-18:~# top

范例:限制CPU

root@ubuntu-18:~# docker run -ti --rm --cpu-quota 2000 --cpu-period 1000 lorel/docker-stress-ng --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
2f782ba57a8e        youthful_carson     159.68%             1.036GiB / 3.83GiB   27.06%              766B / 0B           0B / 0B             13

范例:绑定CPU

#一般不建议绑在0号CPU上,因为0号CPU一般会比较忙
root@ubuntu-18:~# docker run -ti --rm --cpus=1.5 --cpuset-cpus 1,3 lorel/docker-stress-ng --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                 CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
e98d3ebed8d3        reverent_sanderson   149.70%             1.011GiB / 3.83GiB   26.40%              836B / 0B           0B / 0B             13
root@ubuntu-18:~# cat /sys/fs/cgroup/cpuset/docker/e98d3ebed8d388ec2c57c0522531c9558e567db54ab56c16e1d1b236b6909484/cpuset.cpus 
1,3

root@ubuntu-18:~# top
范例:多个容器的CPU利用率比例
#同时开两个容器
root@ubuntu-18:~# docker run -ti --rm --name c1 --cpu-shares 1000 lorel/docker-stress-ng --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

root@ubuntu-18:~# docker run -ti --rm --name c2 --cpu-shares 500 lorel/docker-stress-ng --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
f6df0768eaae        c2                  132.94%             1.037GiB / 3.83GiB   27.07%              516B / 0B           0B / 0B             13
1bdaa8237c0d        c1                  266.57%             1.037GiB / 3.83GiB   27.06%              976B / 0B           0B / 0B             13

#查看容器c1的cpu利用比例
root@ubuntu-18:~# cat /sys/fs/cgroup/cpu,cpuacct/docker/1bdaa8237c0d5ed1b44a3df58ab0afbaefa15efe91325b3a650109857dc6e5f4/cpu.shares 
1000

#查看容器c2的cpu利用比例
root@ubuntu-18:~# cat /sys/fs/cgroup/cpu,cpuacct/docker/f6df0768eaaefc0e127b890e50140075649fb137feff5e0575c3c939325e8c6a/cpu.shares 
500

#再打开新的容器,cpu分配比例会动态调整
root@ubuntu-18:~# docker run -ti --rm --name c3 --cpu-shares 2000 lorel/docker-stress-ng --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
09f5a17ead96        c3                  226.50%             1.037GiB / 3.83GiB   27.07%              726B / 0B           11.3MB / 0B         13
f6df0768eaae        c2                  55.73%              1.037GiB / 3.83GiB   27.06%              936B / 0B           0B / 0B             13
1bdaa8237c0d        c1                  113.27%             1.036GiB / 3.83GiB   27.06%              1.12kB / 0B         0B / 0B             13

范例:动态调整cpu shares值

root@ubuntu-18:~# echo 2000 > /sys/fs/cgroup/cpu,cpuacct/docker/f6df0768eaaefc0e127b890e50140075649fb137feff5e0575c3c939325e8c6a/cpu.shares 
root@ubuntu-18:~# docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
09f5a17ead96        c3                  157.87%             1.037GiB / 3.83GiB   27.06%              866B / 0B           11.3MB / 0B         13
f6df0768eaae        c2                  156.43%             1.037GiB / 3.83GiB   27.06%              936B / 0B           0B / 0B             13
1bdaa8237c0d        c1                  83.45%              1.036GiB / 3.83GiB   27.06%              1.19kB / 0B         0B / 0B             13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注