`--oom-kill-disable`对Docker容器有什么作用?

tgp*_*fer 8 linux memory docker

我知道这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
Run Code Online (Sandbox Code Playgroud)

显然,其中一个工作程序分配的内存超出了允许的范围,并收到SIGKILL。请注意,父进程保持活动状态。

现在,-m如果一个进程分配了过多的内存,如果的效果是调用OOM杀手,那么在指定-m and 时会发生什么--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)
Run Code Online (Sandbox Code Playgroud)

在不同的外壳中:

$ 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
Run Code Online (Sandbox Code Playgroud)

我看docker stats节目的256 MB内存消耗,并top显示一个RES256 MB和VIRT2000 MB。但是,这实际上意味着什么?尝试使用超出允许范围的内存的容器内部的进程将发生什么?从哪个意义上讲,它受到约束-m

小智 7

Linux 中“oom Killer”的工作是牺牲一个或多个进程,以便在其他所有方法都失败时为系统释放内存。仅当主机启用了内存过量使用时,才会启用 OOM Killer

\n\n

的设置--oom-kill-disable将设置cgroup参数,以在满足 指定的条件时禁用此特定容器的 oom Killer -m。如果没有该-m标志,oom Killer 将变得无关紧要。

\n\n

-m 标志并不\xe2\x80\x99t 意味着当进程使用超过 xmb 的内存时停止该进程,\xe2\x80\x99 只是你\xe2\x80\x99s 确保 docker 容器不会\xe2\x80\ x99t 消耗所有主机内存,这可以强制内核终止其进程。使用 -m 标志,不允许容器使用超过给定数量的用户或系统内存。

\n\n

当容器遇到 OOM 时,它不会被杀死,但它可以挂起并保持在失效状态,因此容器内的进程可以响应,直到您手动干预并重新启动或杀死容器。希望这有助于解答您的疑问。

\n\n

有关内核如何处理 OOM 的更多详细信息,请查看 Linux OOM 管理和 Docker 内存限制页面。

\n


BNT*_*BNT 6

据我了解,文档不受限制 --oom-kill-disable-m但实际上需要它:

默认情况下,如果发生内存不足(OOM)错误,内核将终止容器中的进程。要更改此行为,请使用--oom-kill-disable选项。仅在还设置了-m /-memory选项的容器上禁用OOM杀手。如果未设置-m标志,则可能导致主机内存不足,并要求终止主机的系统进程以释放内存。

一名开发人员在2015年表示

无论是否设置了-m标志,主机都可能耗尽内存。但这也无关紧要,因为--oom-kill-disable不会执行任何操作,除非通过-m。

关于您的更新,OOM-killer禁用时发生了什么,但是达到了内存限制(有趣的OOM文章),id表示对new的调用malloc将失败,如此处所述但这还取决于交换配置和可用的主机记忆。如果您的-m限制超出了实际的可用内存,则主机将开始终止进程​​,其中之一可能是docker守护进程(他们试图通过更改其OOM优先级来避免此进程)。

内核文档cgroup/memory.txt)说

如果禁用了OOM-killer,则cgroup下的任务在请求可靠内存时将在内存中挂起/休眠cgroup的OOM-waitqueue

对于cgroup的实际实现(docker也利用了),您必须检查sourcecode

  • 抱歉,我想我应该更明确地表达我的问题,这似乎可以归结为:如果它不是 OOM 杀手,那么使用什么机制来限制已用内存?据我所知,当使用“-m 50m”时,如果容器超过该限制,一个进程将被终止。但是使用“-m 50m --oom-kill-disable”,什么会阻止任何进程使用超过该内存限制的内存呢? (2认同)