【问题标题】:What does `--oom-kill-disable` do for a Docker container?`--oom-kill-disable` 对 Docker 容器有什么作用?
【发布时间】:2018-02-05 08:30:40
【问题描述】:

我知道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)

在不同的外壳中:

$ 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的约束?

【问题讨论】:

    标签: linux docker memory


    【解决方案1】:

    据我了解the docs --oom-kill-disable 不受-m 的约束,但实际上需要它:

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

    一位开发人员表示back in 2015

    无论是否设置了 -m 标志,主机都可能耗尽内存。但 这也无关紧要,因为 --oom-kill-disable 什么都不做,除非 -m 是 通过了。

    关于您的更新,当OOM-killer 被禁用但内存限制达到(intresting OOM article)时会发生什么情况,我说对malloc 的新调用会像here 所述那样失败,但是它还取决于交换配置和主机可用内存。如果您的 -m 限制高于实际可用内存,主机将开始杀死进程,其中之一可能是 docker 守护进程(它们试图通过 changing its OOM priority 避免)。

    kernel docs (cgroup/memory.txt) 说

    如果 OOM-killer 被禁用,cgroup 下的任务将挂起/休眠 内存 cgroup 请求负责内存时的 OOM-waitqueue

    对于 cgroups 的实际实现(docker 也使用),你必须check the sourcecode

    【讨论】:

    • 对不起,我想我应该在我的问题中更明确,这似乎归结为:使用什么机制来限制使用的内存,如果它是 not OOM 杀手?我知道在使用-m 50m 时,如果容器超过该限制,一个进程将被杀死。但是对于-m 50m --oom-kill-disable,什么会阻止任何进程使用超过该内存限制?
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-08
      • 2015-04-18
      • 2013-10-15
      • 2017-09-29
      • 2014-08-08
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      相关资源
      最近更新 更多