73 votes

La bonne façon de garder le conteneur docker démarré lorsqu'il est utilisé pour des tâches périodiques

J'ai un conteneur docker avec des logiciels installés et configurés.

Aucun programme n'est censé être lancé ou exécuté en permanence.

Ce que je veux, c'est la possibilité de lancer une commande en fonction d'événements externes, par exemple :

docker exec mysupercont /path/to/mycommand -bla -for

y

docker exec mysupercont /path/to/myothercommand 

Mais "exec" impossible quand le conteneur est arrêté, et aussi ce conteneur a quelques données "de travail" à l'intérieur, qui ont utilisé pour ces commandes, donc je ne peux pas utiliser

docker run ...

à chaque fois, car il recrée le conteneur à partir de l'image et détruit mes données.

Quelle est la "bonne" et la "meilleure" façon de faire fonctionner un tel conteneur ? Quelle commande je peux lancer à l'intérieur ?

72voto

MSemochkin Points 855

Vous n'avez pas besoin d'exécuter chaque fois docker run .

docker run est en fait une séquence de deux commandes : "créer" et "démarrer".

Lorsque vous exécutez le conteneur, vous devez spécifier l'option " -it ":

-i, --interactive=false Garder STDIN ouvert même si non attaché
-t, --tty=false Allouer un pseudo-TTY

Exemple :

docker run -it debian:stable bash

Après la fin du travail, la commande spécifiée au démarrage (dans mon exemple, bash). Par exemple, vous effectuez la commande "exit". Le conteneur s'arrête :

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Vous pouvez maintenant le redémarrer

docker start 1329c99a831b

Le conteneur est démarré et exécute à nouveau la commande "bash".
Connectez-vous à cette session "bash" avec la commande

docker attach 1329c99a831b

En résumé : vous devez comprendre la différence entre le run y start conteneur.
D'ailleurs, regardez le documentation pour le rôle des paramètres " -i t " et " -d " pour le "Run"

32voto

elnygren Points 391

Puisque vous avez mentionné des tâches périodiques et que vous utilisez probablement quelque chose comme cron en raison de la façon dont vous voulez utiliser docker exec j'ai le médicament qu'il vous faut. Au moins, j'ai fini par faire quelque chose comme ça.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
  2. Exécuter avec l'habituel docker run -d .... (J'ai utilisé docker-compose )

  3. Configurer la crontab des machines hôtes, par exemple :

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1

Je trouve cette solution intéressante car elle permet de s'appuyer sur l'ancienne et éprouvée crontab dans un environnement linux par défaut, tandis que Docker gère les dépôts et les variables d'environnement plus exotiques de votre logique commerciale. Vous pouvez également fixer des limites si vos tâches périodiques sont bloquées et présentent des fuites de mémoire ou autres.

16voto

qoomon Points 241

La queue provoquera encore quelques opérations sur les fichiers de temps en temps.

Dormir pour toujours, sans aucun effet secondaire

# Ah, ha, ha, ha, stayin' alive...
while :; do :; done & kill -STOP $! && wait $!

Comment cela fonctionne

while :;           # Run an endless loop,
do :;              # of do nothing,
done &             # as background task.
kill -STOP $!      # Stop the background task.
wait $!            # Wait forever, because background task process has been stopped.

11voto

Sue Parker Points 101

La question de savoir si vous pouvez ou non démarrer un conteneur arrêté dépend de la façon dont le conteneur a été créé à l'origine, c'est-à-dire exécuté. Si vous avez exécuté une commande qui s'est terminée, ou si vous quittez une commande interactive, par exemple bash, vous ne pouvez pas démarrer, redémarrer ou exécuter le conteneur arrêté. Tout ce que vous pouvez faire est de le supprimer. C'est de la camelote.

Mais le dernier commentaire de taranaki, utiliser '-itd', semble être ce que le docker a commandé.

Le conteneur continue de fonctionner, et vous pouvez exécuter ce que vous voulez, et vous pouvez arrêter, démarrer ou redémarrer le conteneur. Bien sûr, ce n'est qu'une constatation préliminaire basée sur l'image alpine. Notez que si vous vous attachez au conteneur, il s'arrête lorsque vous le quittez, mais vous pouvez le redémarrer.

3voto

DASKAjA Points 199

J'ai moi-même utilisé toutes les solutions proposées ici, mais toutes ne gèrent pas les signaux SIGTERM provenant du démon Docker lorsqu'il veut arrêter le conteneur (par ex. docker stop $containername ).

Je propose donc ce qui suit :

FROM base:image
# ...
CMD sh -c 'trap "exit" TERM; while true; do sleep 1; done'

Il s'agit essentiellement d'un court Shell Shell qui commence par intercepter ("piéger") les signaux SIGTERM puis se met en veille pendant une seconde dans une boucle infinie.

Je l'utilise principalement avec docker-compose et ofelia pour fournir des conteneurs secondaires afin de sauvegarder un autre service dans un autre conteneur (par exemple, des bases de données MariaDB).

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