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.
可以通过修改内核参数消除以上警告
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

#同时开两个容器
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