20.Docker资源限制

docker资源限制

https://docs.docker.com/config/containers/resource_constraints/

默认情况下,容器没有资源限制,并且可以使用主机内核调度程序允许的尽可能多的给定资源。Docker提供了一些方法来控制容器可以使用多少内存或CPU,从而设置docker run命令的运行时配置标志。

其中许多功能都要求您的内核支持Linux功能。要检查支持,可以使用 docker info命令。如果您的内核中禁用了功能,则可能在输出末尾看到警告,如下所示:

WARNING: No swap limit support

对于Linux主机,如果没有足够的内存来执行系统任务,就会抛出OOM(Out of Memory Exception,内存溢出、内存泄漏)随后系统会开始杀死进程以释放内存,凡是运行在宿主机的进程都可能被kill,如果主要的系统进程被Kill,会导致和该进程相关的服务全部宕机;产生OOM异常时,Docker创世通过调整守护进程上的OOM优先级来减轻风险,以便它比其他进程更不可能被杀死;不推荐通过守护进程或容器上手动设置--oom-score-adj为极端负数,或通过在容器上设置--oom-kill-disable 来绕过安全措施。

OOM优先级机制

Linux会为每个进程算一个分数,最终它会将分数最高的进程kill。

#范围为-1000到1000,值越高越容易被宿主机kill,如果设置为-1000,进程永远不会被宿主机kernel kill
/proc/PID/oom_score_adj
#范围从-17到+15,取值越高越容易被干掉,如果是-17表示不能被kill,该参数的存在是为了和旧版本Linux内核兼容
/proc/PID/oom_adj
#这个值是系统综合进程的内存消耗量、CPU时间(Utime+stime)、存活时间(uptime- start time)和oom_adj计算出的进程得分,消耗内存越多得分越高,越容易被主机kernel强制杀死
/proc/PID/oom_score

内存限制

Option Description
-m or --memory= 容器可以使用的最大内存量。如果设置此选项,则允许的最小值为“4m”(4 MB)。
--memory-swap* 此容器允许交换到磁盘的内存量,必须要在设置了物理内存限制的前提下才能设置交换分区限制。
--memory-swappiness 默认情况下,设计容器使用交换分区的倾向。您可以将“-memory swappeiness”设置为0到100之间的值,以调整此百分比。值越高越倾向使用
--memory-reservation 允许您指定小于“-memory”的软限制,当Docker检测到主机上存在争用或内存不足时,将激活该限制。如果使用“-memory reservation”,则必须将其设置为低于“-memory”,才能使其优先。因为这是一个软限制,它不能保证容器不超过限制。
--kernel-memory 容器可以使用的最大内核内存量。允许的最小值为“4m”。由于内核内存与用户空间内存隔离,因此无法与用户空间内存直接交换,因此内存内核不足的容器可能会阻塞主机资源,这可能会对主机和其他容器产生影响,因此建议不要设置。
--oom-kill-disable 默认情况下,如果发生内存不足(OOM)错误,内核将终止容器中的进程。要更改此行为,请使用“-oom kill disable”选项。仅在还设置了“-m/--memory”选项的容器上禁用OOM killer。如果没有设置“-m”标志,主机可能会耗尽内存,内核可能需要终止主机系统的进程以释放内存。
--oom-score-adj 宿主机kernel对进程使用的内存进行评分,评分较高的将被内核kill掉,可以指定一个容器的评分,但不推荐

内存限制验证

#测试镜像
docker pull lorel/docker-stress-ng  
#查看帮助
docker run -it --rm lorel/docker-stress-ng   --help

内存大小硬限制

#启动两个工作进程,每个进程最大允许使用内存256M,且宿主机不限制当前容器最大内存
docker run -it --rm --name limittest001 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
docker stats
#宿主机限制容器最大内存
docker run -it --rm -m 256m --name limittest002 lorel/docker-stress-ng --vm 2 --vm-bytes 256M
docker stats
#宿主机cgroup验证(单位 字节)
cat /sys/fs/cgroup/memory/docker/{conrainer ID}/memory.limit_in_bytes
#或者使用echo修改、一般只能增加;缩小内存会报错write error:Divice or resource busy
echo 268435456  > /sys/fs/cgroup/memory/docker/{conrainer ID}/memory.limit_in_bytes

内存大小软限制

#软限建议小于硬限制
docker run -it --rm --name limittest003 --memory-reservation 512m lorel/docker-stress-ng --vm 2 --vm-bytes 256m
#宿主机cgroup验证
cat /sys/fs/cgroup/memory/docker/{conrainer ID}/memory.soft_limit_in_bytes

关闭OOM机制

#需要有限制才可关闭
dokcer run -it --rm --name limittest004 --oom-kill-disable nginx:web
WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.

docker run -it --rm -m 256m --name limittest004 --oom-kill-disable nginx:web
#宿主机cgroup验证
cat /sys/fs/cgroup/memory/docker/{conrainer ID}/memory.oom_control

限制交换分区

#不建议使用
docker run -it --rm -m 1024m --name limittest005 --memory-swap 2048m  nginx:web
#宿主机cgroup验证
cat /sys/fs/cgroup/memory/docker/{conrainer ID}/memory.memsw.limit_in_bytes

CPU限制

同一个单位时间内只能有一个进程在CPU上运行,那么这么多进程怎么在CPU上执行和调度呢?

  • 实时优先级:0 - 99

  • 非实时优先级(nice):-20 - 19对应100-139的进程优先级

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

场景 优先级 说明
CPU密集型场景 越低越好 计算密集型任务的特点是要进行大量的计算,消耗CPU资源;比如数据处理、对视频进行高清解码等
IO密集型场景 较高 涉及到网络、硬盘IO的任务都是IO密集型任务,这类任务消耗CPU较少,任务大部分时间都在等待IO操作完成;比如web应用,高并发,数据量大的动态网站;数据库

硬盘调度算法

cat /sys/block/sda/queue/sheduler
noop deadline [cfq]
#noop算法不进行优化,使用原生硬盘IO 建议ssd盘使用
#deadline sata盘建议使用
#cfq默认基于时间
Option Description
--cpus=<value> 指定容器可以使用多少可用CPU资源。例如,如果主机有两个cpu,并且您设置了“-CPUs=”1.5“,那么容器最多保证有一个半cpu。这相当于设置--cpu period=“100000”--cpu quota=“150000”`。
--cpu-period=<value> 指定CPU CFS调度程序周期,与“-CPU配额”一起使用。默认为100000微秒(100毫秒)。大多数用户不会更改默认设置。对于大多数用例,--cpu是一个更方便的选择。
--cpu-quota=<value> 对容器施加CPU CFS配额。计算方式为cpu-quota/cpu-period的结果,早起使用(docker1.12及以前)使用此方法限制CPU限制值,新版本docker(docker1.13及以上版本)通常使用--cpus
--cpuset-cpus 限制容器可以使用的特定CPU或核心。如果您有多个CPU,则容器可以使用以逗号分隔的列表或以连字符分隔的CPU范围。第一个CPU编号为0。有效值可以是“0-3”(使用第一、第二、第三和第四个CPU)或“1,3”(使用第二和第四个CPU)。
--cpu-shares 用于设置cfs中调度的相对最大比例权重,cpu-share的值越高的容器,将会分得更多的时间片默认时间片1024,最大262144

CPU限制验证

#测试镜像
docker pull lorel/docker-stress-ng  
#查看帮助
docker run -it --rm --name limittest  lorel/docker-stress-ng --vm 4 
docker stats
#查看CPU限制
cat /sys/fs/cgroup/cpuset/docker/{conrainer ID}/cpuset.cpus

#进行限制
docker run -it --rm --name limittest -cpus 2 lorel/docker-stress-ng --cpu 4 --vm 4 

将容器运行在指定的CPU上

docker run -it --rm --name limittest -cpus 2 --cpuset-cpus 1,3 lorel/docker-stress-ng --cpu 4 --vm 4 
#手工修改
echo "0,2-3" > /sys/fs/cgroup/cpuset/docker/{conrainer ID}/cpuset.cpus

基于cpu-share对CPU进行切分

#启动两个容器
docker run -it --rm --name limittest001 --cpu-shares 1024 lorel/docker-stress-ng --cpu 4 --vm 4 
docker run -it --rm --name limittest002 --cpu-shares 2048 lorel/docker-stress-ng --cpu 4 --vm 4 
#查看CPU限制
cat /sys/fs/cgroup/cpuset/docker/{conrainer ID}/cpu.shares
#手工修改
echo 1024  > /sys/fs/cgroup/cpuset/docker/{conrainer ID}/cpu.shares
posted @ 2021-01-20 01:04  Gmiao  阅读(201)  评论(0编辑  收藏  举报