我已经理解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
显示的RES
为256 MB,VIRT
为2000 MB。但是,这究竟意味着什么?尝试使用比允许的更多内存的容器内的进程会发生什么?在哪种意义上,它受-m
?
答案 0 :(得分:4)
据我了解the docs --oom-kill-disable
不受-m
约束,但实际上需要它:
默认情况下,如果内存不足,内核会终止容器中的进程 发生(OOM)错误。要更改此行为,请使用 --oom-kill-disable选项。仅在已设置-m / - memory选项的容器上禁用OOM杀手。如果-m标志不是 设置,这可能导致主机内存不足并需要 杀死主机的系统进程以释放内存。
开发人员声明back in 2015
主机可以在设置或不设置-m标志的情况下耗尽内存。但 它也无关紧要,因为除非-m是,否则--oom-kill-disable不会执行任何操作 过去了。
关于您的更新,当OOM-killer
被禁用且内存限制被点击(intresting OOM article)时会发生什么情况,id表示对malloc
的新调用等会失败如here所述,但它也取决于交换配置和主机可用内存。如果您的-m
限制高于实际可用内存,则主机将开始终止进程,其中一个可能是docker守护进程(他们试图通过changing its OOM priority避免)。
kernel docs(cgroup/memory.txt
)说
如果禁用OOM杀手,cgroup下的任务将挂起/睡眠 内存cgroup在请求负责任内存时的OOM-waitqueue
对于cgroup的实际实现(哪个docker也使用),你必须check the sourcecode。
答案 1 :(得分:1)
“杀手”的工作&#39;在Linux中,牺牲一个或多个进程,以便在其他所有方法都失败时为系统释放内存。仅当主机启用了内存过量使用时才会启用OOM杀手
--oom-kill-disable
的设置会设置 cgroup 参数,以便在满足-m
指定的条件时禁用此特定容器的oom杀手。没有-m
标志,oom杀手将无关紧要。
-m标志并不意味着当它使用超过xmb的ram时停止进程,只是你要确保docker容器不消耗所有主机内存,这会强制内核终止其进程。使用-m标志时,不允许容器使用超过给定数量的用户或系统内存。
当容器遇到OOM时,它不会被杀死,但它可以挂起并保持不动状态,因此在您手动干预并重新启动或终止容器之前,容器内的进程无法响应。希望这有助于清除您的问题。
有关内核如何对OOM执行操作的更多详细信息,请查看Linux OOM管理和Docker内存限制页面。