Docker之docker资源限制

一 容器的内存限制

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

1.1 内存相关选项

Option Description
-m or --memory= 容器可以使用的最大内存量。如果设置此选项,则允许的最小值为6m(6MB)。
--memory-swap* 允许此容器交换到磁盘的内存量。. See --memory-swap details.
--memory-swappiness 默认情况下,主机内核可以交换容器使用的匿名页面的百分比。您可以将--memory swapiness设置为0到100之间的值,以调整此百分比. See --memory-swappiness details.
--memory-reservation

允许您指定小于--memory的软限制,当Docker检测到主机上存在争用或内存不足时,将激活该限制。如果使用--memory reservation,则必须将其设置为低于--memory才能优先使用。因为它是一个软限制,所以不能保证容器不超过限制。

--kernel-memory 容器可以使用的最大内核内存量。最小允许值为4m。由于内核内存无法调出,内核内存不足的容器可能会阻塞主机资源,这可能会对主机和其他容器产生副作用See --kernel-memory details.
--oom-kill-disable 默认情况下,如果发生内存不足(OOM)错误,内核将终止容器中的进程。要更改此行为,请使用--oom-kill-disable选项。仅在还设置了-m/--memory选项的容器上禁用OOM killer。如果未设置-m标志,主机可能会耗尽内存,内核可能需要终止主机系统的进程以释放内存。

1.2 使用stress-ng测试内存配置

1.2.1 查看stress-ng关于内存的使用帮助

root@node01:~# docker run -it --rm --name wgs-cpu lorel/docker-stress-ng | grep vm
 -m N, --vm N             start N workers spinning on anonymous mmap
       --vm-bytes N       allocate N bytes per vm worker (default 256MB)
       --vm-hang N        sleep N seconds before freeing memory
       --vm-keep          redirty memory instead of reallocating
       --vm-ops N         stop when N vm bogo operations completed
       --vm-locked        lock the pages of the mapped region into memory
       --vm-method m      specify stress vm method m, default is all
       --vm-populate      populate (prefault) page tables for a mapping
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

1.2.2 内存测试样例

指定最大内存400M

root@node01:~# docker run -it --rm --name wgs-cpu -m 400M  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

1.2.3 验证内存测试结果

root@node01:~# docker stats --no-stream
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O         PIDS
e25aa2cd0454   wgs-cpu             60.79%    400MiB / 400MiB       99.99%    1.02kB / 0B      9.7GB / 0B        5

root@node01:~# top
top - 18:28:06 up 8:25, 2 users, load average: 2.74, 4.37, 2.64
Tasks: 210 total, 5 running, 205 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.3 us, 93.4 sy, 0.0 ni, 0.0 id, 2.0 wa, 0.0 hi, 1.3 si, 0.0 st
MiB Mem : 1959.3 total, 406.8 free, 764.0 used, 788.5 buff/cache
MiB Swap: 2048.0 total, 1876.5 free, 171.5 used. 1023.7 avail Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                  

246002 root 20 0 268400 204572 572 R 47.7 10.2 0:24.75 stress-ng-vm
246003 root 20 0 268400 203500 572 R 47.7 10.1 0:24.74 stress-ng-vm

1.2.4 动态调整容器内存限制

1.2.4.1 查看容器id

root@node01:~# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS     NAMES
082e41fc7e39   lorel/docker-stress-ng   "/usr/bin/stress-ng …"   4 minutes ago   Up 4 minutes             wgs-cpu

1.2.4.2 查看容器内存限制

root@node01:~# cat /sys/fs/cgroup/memory/docker/082e41fc7e3927ba644d11303840df33e076b15d98322a37f46c21aef691e9b3/memory.limit_in_bytes 
419430400

1.2.4.3 动态修改容器内存限制

root@node01:~# echo 838860800 > /sys/fs/cgroup/memory/docker/082e41fc7e3927ba644d11303840df33e076b15d98322a37f46c21aef691e9b3/memory.limit_in_bytes 
root@node01:~# cat /sys/fs/cgroup/memory/docker/082e41fc7e3927ba644d11303840df33e076b15d98322a37f46c21aef691e9b3/memory.limit_in_bytes 
838860800

1.2.4.4 验证容器内存限制

root@node01:~# docker stats --no-stream
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O     PIDS
082e41fc7e39   wgs-cpu   97.12%    514.1MiB / 800MiB   64.26%    1.16kB / 0B   47.4GB / 0B   5

二 容器的cpu限制

2.1 容器cpu限制介绍

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

CFS定义了进程调度的新模型,它给cfs_rq(cfs的run queue)中的每一个进程安排一个虚拟时钟vruntime。如果一个进程得以执行,随着时间增长,其vruntime将不断增大。没有得到执行的进行vruntime不变,而调度器总是选择vruntime跑的最慢的那个进程来执行。这就是所谓的完全公平。为了区别不用优先级的进程,优先级高的进程vruntime增长的慢,以至于它可能得到更多的运行机会。

CFS的意义在于在一个混杂着大量计算型进程和IO交互进程的系统中,CFS调度器相对其它调度器在对待IO交互进程要更加友善和公平。

CPU密集型的场景:优先级越低越好,计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、数据处理、对视频进行高清解码等等,全靠CPU的运算能力。

IO密集型的场景:优先级值高点,涉及到网络、磁盘IO的任务都是IO密集型任务,这类人物的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度),比如web应用,高并发,数据量大的动态网站来说,数据库应该为IO密集型

2.2 配置默认的 CFS 调度器

默认情况下,每个容器对主机 CPU 周期的访问是无限制的。您可以设置各种约束来限制给定容器对主机 CPU 周期的访问。大多数用户使用和配置 默认的 CFS 调度程序

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

选项 描述
--cpus=<value> 指定容器可以使用多少可用 CPU 资源。例如,如果主机有两个 CPU 并且您设置了--cpus="1.5",则容器最多保证一个半 CPU。这相当于设置--cpu-period="100000"--cpu-quota="150000"
--cpu-period=<value> 指定 CPU CFS 调度程序周期,它与 --cpu-quota. 默认为 100000 微秒(100 毫秒)。大多数用户不会更改默认设置。对于大多数用例,--cpus是一个更方便的选择。
--cpu-quota=<value> 对容器施加 CPU CFS 配额。在--cpu-period限制之前容器被限制的微秒数。因此充当有效上限。对于大多数用例,--cpus是一个更方便的选择。
--cpuset-cpus 限制容器可以使用的特定 CPU 或内核。如果您有多个 CPU,则容器可以使用的以逗号分隔的列表或以连字符分隔的 CPU 范围。第一个 CPU 编号为 0。有效值可能是0-3(使用第一个、第二个、第三个和第四个 CPU)或1,3(使用第二个和第四个 CPU)。
--cpu-shares 将此标志设置为大于或小于默认值 1024 的值以增加或减少容器的权重,并使其访问主机 CPU 周期的更大或更小比例。这仅在 CPU 周期受限时强制执行。当有足够的 CPU 周期可用时,所有容器都会根据需要使用尽可能多的 CPU。这样,这是一个软限制。--cpu-shares不会阻止容器在 swarm 模式下进行调度。它优先考虑可用 CPU 周期的容器 CPU 资源。它不保证或保留任何特定的 CPU 访问。

2.3 使用stress-ng测试cpu配置

2.3.1 查看stress-ng关于cpu的使用帮助

root@node01:~# docker run -it --rm --name wgs-cpu 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

2.3.2 限制cpu测试样例

root@node01:~# docker run -it --rm --name wgs-cpu --cpus 1  lorel/docker-stress-ng --cpu 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 cpu

2.3.3 验证结果

root@node01:~# docker stats --no-stream
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
e8a8cdc6f25d   wgs-cpu   49.65%    7.672MiB / 1.913GiB   0.39%     876B / 0B   0B / 0B     3
root@node01:~# top
top - 18:25:13 up  8:22,  2 users,  load average: 14.12, 5.87, 2.66
Tasks: 253 total,  19 running, 234 sleeping,   0 stopped,   0 zombie
%Cpu(s): 90.8 us,  9.2 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1959.3 total,    359.8 free,    809.4 used,    790.1 buff/cache
MiB Swap:   2048.0 total,   2040.7 free,      7.2 used.    976.0 avail Mem 
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                  

245548 root 20 0 6900 2404 576 R 24.7 0.1 0:11.18 stress-ng-cpu
245549 root 20 0 6900 2404 576 R 24.7 0.1 0:11.18 stress-ng-cpu

2.3.4 查看容器所在CPU编号

2.3.4.1 查看容器id

root@node01:~# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS     NAMES
082e41fc7e39   lorel/docker-stress-ng   "/usr/bin/stress-ng …"   4 minutes ago   Up 4 minutes             wgs-cpu

2.3.4.2 查看容器所在cpu编号

root@node01:~# cat /sys/fs/cgroup/cpuset/docker/082e41fc7e3927ba644d11303840df33e076b15d98322a37f46c21aef691e9b3/cpuset.cpus
0
上一篇:docker容器


下一篇:Docker 与 K8S学习笔记(六)—— 容器的资源限制