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キラーを呼び出すことである場合、-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)
別のシェルで:
$ 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
によって制約されていますか?
私が理解しているように 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 docs (cgroup/memory.txt
)は言う
OOM-killerが無効になっている場合、cgroupの下のタスクは、責任のあるメモリを要求すると、メモリcgroupのOOM-waitqueueでハング/スリープします。
Cdocの実際の実装(Dockerも使用)については、 ソースコードを確認 する必要があります。
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メモリの制限のページを確認してください。