web-dev-qa-db-ja.com

Dockerコンテナに対して「--oom-kill-disable」は何をしますか?

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

どうやら、ワーカーの1つが許可されているよりも多くのメモリを割り当て、SIGKILLを受け取ります。親プロセスは存続していることに注意してください。

-mの効果が、プロセスが割り当てたメモリが多すぎる場合にOOMキラーを呼び出すことである場合、-mand--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によって制約されていますか?

10
tgpfeiffer

私が理解しているように the docs--oom-kill-disable-mによって制約されていませんが、実際には必要です:

デフォルトでは、メモリー不足(OOM)エラーが発生した場合、カーネルはコンテナー内のプロセスを強制終了します。この動作を変更するには、--oom-kill-disableオプションを使用します。 -m /-memoryオプションも設定したコンテナでのみOOMキラーを無効にします。 -mフラグが設定されていない場合、これによりホストのメモリが不足し、ホストのシステムプロセスを強制終了してメモリを解放する必要がある場合があります。

開発者は 2015年に戻る と述べました

ホストは、-mフラグを設定してもしなくても、メモリ不足になる可能性があります。ただし、--oom-kill-disableは-mが渡されない限り何もしないので、無関係です。

更新に関して、OOM-killerが無効でメモリ制限に達した場合( intresting OOM記事 )、idはmallocへの新しい呼び出しなどを示します here のように失敗するだけですが、スワップ構成とホストの使用可能なメモリにも依存します。 -mの制限が実際に使用可能なメモリを超えている場合、ホストはプロセスを強制終了します。プロセスの1つは、Dockerデーモン( OOM優先度を変更する )によって回避しようとする可能性があります。

kernel docscgroup/memory.txt)は言う

OOM-killerが無効になっている場合、cgroupの下のタスクは、責任のあるメモリを要求すると、メモリcgroupのOOM-waitqueueでハング/スリープします。

Cdocの実際の実装(Dockerも使用)については、 ソースコードを確認 する必要があります。

7
BNT

Linuxの「oom killer」の仕事は、他のすべてが失敗したときにシステムのメモリを解放するために、1つ以上のプロセスを犠牲にすることです。 OOMキラーは、ホストでメモリオーバーコミットが有効になっている場合にのみ有効になります

--oom-kill-disableを設定すると、cgroupパラメータが設定され、-mで指定された条件が満たされたときに、この特定のコンテナのoom killerが無効になります会った。 -mフラグがなければ、oom killerは無関係です。

-mフラグは、xmbを超えるRAMを使用するときにプロセスを停止することを意味するのではなく、Dockerコンテナーがすべてのホストメモリを消費しないことを確認しているだけです。これにより、カーネルがプロセスを強制終了する可能性があります。 -mフラグを使用すると、コンテナーはユーザーまたはシステムの所定量を超えるメモリを使用できません。

コンテナーがOOMにヒットしても、コンテナーは強制終了されませんが、ハングして機能しなくなる可能性があるため、手動で介入して再起動するかコンテナーを強制終了するまで、コンテナー内のプロセスは応答できません。これがあなたの質問をクリアするのに役立つことを願っています。

カーネルがOOMでどのように動作するかの詳細については、Linux OOM管理とDockerメモリの制限のページを確認してください。

3
Oron Zimmer