web-dev-qa-db-fra.com

Que fait `--oom-kill-disable` pour un conteneur Docker?

J'ai compris que docker run -m 256m --memory-swap 256m limitera un conteneur afin qu'il puisse utiliser au plus 256 Mo de mémoire et aucun échange. S'il alloue plus, alors un processus dans le conteneur (pas "le conteneur") sera tué. Par exemple:

$ 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

Apparemment, l'un des travailleurs alloue plus de mémoire que ce qui est autorisé et reçoit un SIGKILL. Notez que le processus parent reste actif.

Maintenant, si l'effet de -m est d'invoquer le tueur OOM si un processus alloue trop de mémoire, que se passe-t-il lors de la spécification de -met--oom-kill-disable? L'essayer comme ci-dessus a le résultat suivant:

$ 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)

Dans un autre 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

Je vois le docker stats affiche une consommation de mémoire de 256 Mo et top affiche une RES de 256 Mo et une VIRT de 2000 Mo. Mais qu'est-ce que cela veut vraiment dire? Qu'adviendra-t-il d'un processus à l'intérieur du conteneur qui essaie d'utiliser plus de mémoire que ce qui est autorisé? En ce sens, il est contraint par -m?

10
tgpfeiffer

Si je comprends bien les docs--oom-kill-disable n'est pas contraint par -m mais en fait l'exige:

Par défaut, le noyau tue les processus dans un conteneur si une erreur de mémoire insuffisante (MOO) se produit. Pour modifier ce comportement, utilisez l'option --oom-kill-disable. Ne désactivez le module de suppression OOM que sur les conteneurs où vous avez également défini l'option de mémoire -m/-. Si l'indicateur -m n'est pas défini, cela peut entraîner un manque de mémoire de l'hôte et nécessiter l'arrêt des processus système de l'hôte pour libérer de la mémoire.

Un développeur a déclaré en 2015 que

L'hôte peut manquer de mémoire avec ou sans l'indicateur -m défini. Mais cela n'a pas non plus d'importance car --oom-kill-disable ne fait rien à moins que -m ne soit passé.

En ce qui concerne votre mise à jour, que se passe-t-il lorsque OOM-killer est désactivé et pourtant la limite de mémoire est atteinte ( article OOM intéressant ), je dirais que les nouveaux appels à malloc et ceux-ci échoueront comme décrit ici = mais cela dépend aussi de la configuration du swap et de la mémoire disponible des hôtes. Si ton -m la limite est supérieure à la mémoire réelle disponible, l'hôte commencera à tuer les processus, dont l'un pourrait être le démon docker (qu'ils essaient d'éviter en en changeant sa priorité OOM ).

Les documentation du noya (cgroup/memory.txt) dire

Si OOM-killer est désactivé, les tâches sous cgroup se bloqueront/s'endormiront dans la mémoire OOM-waitqueue de cgroup lorsqu'elles demanderont une mémoire responsable

Pour l'implémentation réelle (que Docker utilise également) des groupes de contrôle, vous devez vérifier le code source .

7
BNT

Le travail du "tueur oom" sous Linux est de sacrifier un ou plusieurs processus afin de libérer de la mémoire pour le système lorsque tout le reste échoue. OOM killer n'est activé que si l'hôte a une surcharge de mémoire activée

Le réglage de --oom-kill-disable définira le paramètre cgroup pour désactiver le tueur oom pour ce conteneur spécifique lorsqu'une condition spécifiée par -m est rencontré. Sans le -m flag, oom killer sera hors de propos.

L'indicateur -m ne signifie pas d'arrêter le processus lorsqu'il utilise plus de xmb de RAM, c'est seulement que vous vous assurez que le conteneur Docker ne consomme pas toute la mémoire de l'hôte, ce qui peut forcer le noyau à tuer son processus. Avec l'indicateur -m, le conteneur n'est pas autorisé à utiliser plus d'une quantité donnée de mémoire utilisateur ou système.

Lorsque le conteneur atteint le MOO, il ne sera pas tué, mais il peut se bloquer et rester à l'état défunt. Par conséquent, les processus à l'intérieur du conteneur ne peuvent pas répondre tant que vous n'intervenez pas manuellement et ne redémarrez pas ou ne tuez pas le conteneur. J'espère que cela aidera à clarifier vos questions.

Pour plus de détails sur la façon dont le noyau agit sur les MOO, consultez la page Gestion des MOO Linux et Limitations de la mémoire Docker.

3
Oron Zimmer