6 votes

Comment arrêter un conteneur docker en veille ?

sleep est un substitut de la plupart des processus complexes, bien sûr.

Ce Dockerfile (comme vous pouvez le voir en utilisant la forme exec pour qu'il n'y ait qu'un seul processus en cours d'exécution et aucun enfant de bash ):

FROM busybox
CMD ["/bin/sleep", "100000"]

crée un conteneur ininterrompu :

docker build -t kill-sleep .
docker run --rm --name kill-sleep kill-sleep

Quand j'essaie de l'arrêter :

time docker stop kill-sleep

kill-sleep
real    0m10.449s
user    0m0.021s
sys     0m0.027s

la commande s'arrête 10 secondes avant que le conteneur ne soit tué.

Le problème n'est pas que sleep ne gère pas les signaux, parce que si je l'exécute sur l'hôte :

sleep 100000
# in another shell
ps faxww | grep sleep
kill -TERM 31333  # the PID

le processus s'arrête immédiatement.

Le problème est peut-être lié au fait que ce programme est exécuté en tant que PID 1 dans le conteneur, mais je n'ai pas encore vu de documentation de référence à ce sujet.

8voto

Attie Points 18031

Lorsque vous exécutez docker stop ... , certaines choses vont se produire :

  1. docker envoie un SIGTERM au processus principal du conteneur. Le processus est capable de masquer/ignorer un fichier SIGTERM et s'il le fait (ou le traite sans s'arrêter) " rien " se produira.
  2. Après un délai d'attente (10 secondes par défaut), docker envoie un SIGKILL au processus principal. Ce signal ne peut pas être masqué par un processus, et donc il meurt immédiatement sans possibilité d'exécuter une procédure d'arrêt.

Idéalement, les processus sont exécutés dans docker répondra à la SIGTERM en temps voulu, en s'occupant de tout le ménage avant de terminer.

Si vous savez que le processus n'a pas de tâches ménagères à effectuer (par ex : sleep ), ou ne répondra pas correctement à SIGTERM vous pouvez spécifier un délai plus court (ou plus long) avec l'option -t drapeau :

-t, --time=10
    Seconds to wait for stop before killing it

Par exemple, dans votre cas, vous voudrez peut-être exécuter docker stop -t 0 ${CONTAINER} .


La raison pour laquelle le comportement de ce signal est différent est due à la sleep fonctionnant avec PID = 1.

Typiquement (par exemple : exécution avec PID != 1), tout signal que le processus ne traite pas explicitement conduit à la fin du processus - essayez d'envoyer un signal sleep a SIGUSR1 .

Cependant, lorsqu'il est exécuté avec PID = 1, les signaux non gérés sont ignorés, sinon vous vous retrouveriez avec une panique du noyau :

Kernel panic - not syncing: Attempted to kill init!

Vous pouvez envoyer un signal au conteneur docker en utilisant les outils docker, par exemple :

docker kill -s TERM kill-sleep

Comme on peut le voir, ceci n'a pas l'effet désiré, alors que ceci le fait :

docker kill -s KILL kill-sleep

Une expérience

Dockerfile

FROM busybox
COPY run.sh /run.sh
RUN chmod +x /run.sh
CMD "/run.sh"

run.sh

#!/bin/sh

echo "sleeping"
sleep 100000

Maintenant, exécutez

docker build -t kill-sleep .
docker run --rm --name kill-sleep kill-sleep

Et ceci dans un terminal différent :

docker stop kill-sleep

Nous observons le même délai / timeout de 10 secondes.

Une solution

Maintenant, nous allons gérer le SIGTERM . Mise en contexte et wait pour sleep sont dues à la façon dont un Shell POSIX gère les signaux (voir ce pour en savoir plus).

run.sh

#!/bin/sh

die_func() {
        echo "oh no"
        sleep 2
        exit 1
}
trap die_func TERM

echo "sleeping"
sleep 100000 &
wait

Exécutez à nouveau les commandes, et nous voyons ce que nous recherchons !

$ time docker stop kill-sleep
kill-sleep

real    0m2.515s
user    0m0.008s
sys     0m0.044s

0voto

parity3 Points 190

Quelques options supplémentaires :

  • ajouter le --init à la commande d'exécution du conteneur. De cette façon, sleep n'est pas PID 1, et init fait la bonne chose sur TERM.
  • ajouter le --stop-signal=KILL à la commande d'exécution du conteneur. Cependant, il est généralement déconseillé d'utiliser KILL comme une opération normale.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X