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

时间:2018-02-05 08:30:41

标签: linux docker memory

我已经理解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

的约束

2 个答案:

答案 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 docscgroup/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内存限制页面。