`--oom-kill-disable`参数在Docker容器中的作用是什么?

13

我了解到docker run -m 256m --memory-swap 256m会限制容器的内存使用量,最多只能使用256MB的内存和不包含交换空间。如果分配的内存超过了这个限制,那么容器中的一个进程(而不是“容器”)将被终止。例如:

$ 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 killer,那么当同时指定 -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)
在另一个终端中:
$ 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的限制?

2个回答

14
据我所了解,文档中的--oom-kill-disable选项不受-m限制,但实际上需要它:
默认情况下,如果容器发生内存不足错误,内核会杀死容器中的进程。要更改此行为,请使用--oom-kill-disable选项。仅在您还设置了-m / --memory选项的容器上禁用OOM killer。如果未设置-m标志,则可能导致主机耗尽内存并需要终止主机的系统进程以释放内存。
开发人员在2015年曾表示:
主机可能会耗尽内存,无论是否设置了-m标志。但是,如果未传递-m,则无关紧要,因为--oom-kill-disable不起作用。
关于您的更新,当禁用OOM killer时但遇到内存限制(有趣的OOM文章),我认为新的malloc等调用将会失败,如此处描述,但也取决于交换配置和主机可用内存。如果您的-m限制高于实际可用内存,则主机将开始终止进程,其中一个可能是Docker守护程序(他们尝试通过更改其OOM优先级来避免这种情况)。

内核文档(cgroup/memory.txt)称:

如果禁用 OOM-killer,cgroup 中的任务在请求可计入内存时将挂起/睡眠于内存 cgroup 的 OOM-waitqueue 中。

要查看 cgroups 的实际实现(也是 Docker 所使用的),您需要查看源代码


2
抱歉,我想我在我的问题中应该更加明确,这似乎归结为:如果不是OOM killer,那么用于限制使用的内存的机制是什么?我理解当使用“-m 50m”时,如果容器超过了该限制,一个进程将被杀死。但是使用“-m 50m --oom-kill-disable”,什么会阻止任何进程使用超过该内存限制的内存? - tgpfeiffer

7
'oom killer'在Linux中的工作是在所有其他方法都失败时,牺牲一个或多个进程以释放系统内存。只有启用了内存超额提交的主机才能启用OOM killer。
设置--oom-kill-disable将设置cgroup参数,以在满足-m指定的条件时禁用此特定容器的oom killer。没有-m标志,oom killer将不相关。
-m标志并不意味着当进程使用超过xmb的RAM时停止该进程,而是确保docker容器不会消耗所有主机内存,这可能会强制内核杀死其进程。使用-m标志,容器不允许使用超过给定用户或系统内存量。
当容器遇到OOM时,它不会被杀死,但它可能会挂起并停留在僵尸状态,因此容器内的进程无法响应,直到您手动干预并重新启动或杀死容器。希望这可以解答您的问题。
有关内核如何处理OOM的更多详细信息,请查看Linux OOM管理和Docker内存限制页面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接