我已经了解到docker run -m 256m --memory-swap 256m
会限制一个容器最多使用256 MB内存,并且不允许交换。如果它分配更多内存,那么容器中的一个进程(不是“容器”)将被杀死。例如:
$ sudo docker run -it --rm -m 256m --memory-swap 256m \
stress --vm 1 --vm-bytes 2000M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [1] (415) <-- worker 7 got signal 9
stress: WARN: [1] (417) now reaping child worker processes
stress: FAIL: [1] (421) kill error: No such process
stress: FAIL: [1] (451) failed run completed in 1s
字符串
显然,其中一个工作进程分配的内存比允许的多,并收到SIGKILL
。请注意,父进程保持活动状态。
现在,如果-m
的效果是在一个进程分配了太多内存时调用OOM杀手,那么当指定-m
* 和 * --oom-kill-disable
时会发生什么?像上面这样尝试会有以下结果:
$ sudo docker run -it --rm -m 256m --memory-swap 256m --oom-kill-disable \
stress --vm 1 --vm-bytes 2000M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
(waits here)
型
在不同的shell中:
$ docker stats
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f5e4c30d75c9 0.00% 256 MiB / 256 MiB 100.00% 0 B / 508 B 0 B / 0 B 2
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19391 root 20 0 2055904 262352 340 D 0.0 0.1 0:00.05 stress
型
我看到docker stats
显示了256 MB的内存消耗,top
显示了256 MB的RES
和2000 MB的VIRT
。但是,这实际上意味着什么?容器内试图使用超过允许的内存的进程会发生什么?在什么意义上它受到-m
的约束?
3条答案
按热度按时间9jyewag01#
据我所知,文档
--oom-kill-disable
不受-m
的限制,但实际上需要它:默认情况下,如果发生内存不足(OOM)错误,内核会杀死容器中的进程。要更改此行为,请使用--oom-kill-disable选项。仅在您还设置了-m/--memory选项的容器上禁用OOM杀手程序。如果未设置-m标志,则可能导致主机内存不足,并需要杀死主机的系统进程以释放内存。
一位开发商在2015年表示,
无论是否设置了-m标志,主机都可能会耗尽内存。但它也是无关紧要的,因为除非传递-m,否则--oom-kill-disable什么都不做。
关于你的更新,当
OOM-killer
被禁用而内存限制被达到时会发生什么?(intresting OOM article),id说对malloc
的新调用将像here描述的那样失败,但这也取决于交换配置和主机的可用内存。如果您的-m
限制高于实际可用内存,主机将开始杀死进程,其中之一可能是docker守护进程(他们试图通过改变其OOM优先级来避免)。kernel docs(
cgroup/memory.txt
)表示如果禁用了OOM-killer,cgroup下的任务在请求可解释内存时将挂起/休眠在内存cgroup的OOM-等待队列中
对于cgroups的实际实现(docker也使用),您必须使用check the sourcecode。
5ktev3wc2#
在Linux中,“oom killer”的工作是牺牲一个或多个进程,以便在所有其他方法都失败时为系统释放内存。
--oom-kill-disable
的设置将设置cgroup参数,以在满足-m
指定的条件时禁用该特定容器的oom killer。如果没有-m
标志,则oom killer将不相关。-m标志并不意味着当进程使用超过xmb的内存时停止进程,只是确保Docker容器不会消耗所有的主机内存,这可能会迫使内核杀死它的进程。使用-m标志,容器不允许使用超过给定数量的用户或系统内存。
当容器遇到OOM时,它不会被杀死,但它可以挂起并保持在失效状态,因此容器内的进程无法响应,直到您手动干预并重新启动或杀死容器。希望这有助于解决您的问题。
有关内核如何处理OOM的更多详细信息,请查看Linux OOM管理和Docker内存限制页面。
7fyelxc53#
对于使用cgroups v2的新主机上的新Docker版本,
--oom-kill-disable
参数不再受支持。要检查docker使用的
Cgroup
,请运行字符串
当尝试使用选项时,docker给出以下警告
型
From:moby: Improve information about supported (cgroup) constraints
我还在想办法绕过他。