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

41

J'ai un conteneur Docker avec un logiciel installé et configuré.

Il n’existe aucun programme supposé être démarré / exécuté tout le temps.

Ce que je veux - sa capacité à démarrer une commande en fonction d’événements externes. comme:

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

et

docker exec mysupercont /path/to/myothercommand 

Mais "exec" est impossible lorsque le conteneur est arrêté, et ce conteneur contient également des données "de travail", qui utilisaient ces commandes, je ne peux donc pas utiliser

docker run ...

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

Quel est le "bon" et le "meilleur" moyen de faire couler ce conteneur? Quelle commande je peux commencer à l'intérieur?

Korjavin Ivan
la source
C'est une question très bien expliquée. Voir un autre post similaire ici .
Grant Li
2
docker run -d --name=name container tail -f /dev/null
steampowered

Réponses:

46

Vous n'avez pas besoin de jouer à chaque fois docker run.

docker run est en fait une séquence de deux commandes: "create" et "start".

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

-i, --interactive = false Conservez STDIN ouvert même s'il n'est pas connecté.
-t, --tty = false Alloue un pseudo-TTY.

Exemple:

docker run -it debian:stable bash

Une fois le travail terminé, commande spécifiée au démarrage (dans mon exemple, bash). Par exemple, vous effectuez la "sortie". 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

Maintenant tu peux recommencer

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 conteneur runet start.
Regardez aussi la documentation sur le rôle des paramètres " -i t" et " -d" pour le "Run"

MSemochkin
la source
1
aha, je comprends cela. La question était: je n'ai rien à exécuter dans le conteneur, mais je dois le conserver dans l'état "run". Votre réponse est donc: utilisez bash pour maintenir le conteneur en état d'exécution?
Korjavin Ivan
Oui. Le processus que vous avez spécifié au moment de l'exécution doit être exécuté sur le conteneur continue de fonctionner. L'exemple le plus simple est bash. Peut-être serez-vous le moyen le plus simple de démarrer le conteneur avec le "-d" et de vous y connecter au besoin à l'aide du docker attach ID. Sortez de cette session sans terminer bash, vous pouvez utiliserCTRL-p CTRL-q
MSemochkin le
Le processus que vous spécifiez lors de l'exécution du conteneur reçoit le PID 1. Par conséquent, le conteneur ne peut tout simplement pas fonctionner sans lui
MS
Mon expérience avec start et attach (ou start avec -ai) est que l'édition rapide et interactive de votre ligne de commande ne s'affiche pas. Par exemple, le terminal ne rend ni ne fait écho.
dlamblin
1
C'est chouette. Notez que si vous souhaitez démarrer le conteneur en arrière-plan sans avoir à le redémarrer manuellement (par exemple si vous utilisez un service Web), utilisez les paramètres '-itd', et CTRL-p CTRL-q pour les détacher sans arrêter le récipient.
taranaki
6

Toute cette affaire de savoir si vous pouvez ou non démarrer un conteneur arrêté dépend de la manière 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 vous avez quitté 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, c'est l'enlever. C'est de la camelote.

Mais le dernier commentaire de Taranaki, utilisez '-itd', semble être ce que le docker a ordonné.

Le conteneur continue à fonctionner, vous pouvez exécuter ce que vous voulez et vous pouvez arrêter, démarrer ou redémarrer le conteneur. Bien entendu, il ne s'agit que d'une conclusion préliminaire basée sur l'image alpine. Notez que si vous attachez le conteneur, il s’arrêtera lorsque vous quitterez, mais vous pourrez le redémarrer.

Sue Parker
la source
3
+1 "semble être ce que le docker a commandé" :-)
Matt Alexander
5

Comme vous avez mentionné des tâches périodiques et que vous utilisez probablement quelque chose comme cron à cause de la façon dont vous voulez l'utiliser docker exec, j'ai juste le médicament pour vous. Au moins, j'ai fini par faire quelque chose comme ça.

  1. Dockerfile

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

  3. Configurer les machines hôtes crontab, 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 nous nous appuyons sur l'ancienne crontab, qui a fait ses preuves, dans un bel environnement Linux par défaut, tandis que Docker gère les variables et les variables d'environnement les plus exotiques de votre logique d'entreprise. Vous pouvez également définir certaines limites si vos tâches périodiques sont bloquées et présentent des fuites de mémoire, etc.

Elnygren
la source
0

Tail provoque toujours certaines opérations sur les fichiers de temps en temps.

Voici ma solution pour dormir pour toujours, sans aucun effet secondaire.

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

Comment ça marche

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped
qoomon
la source
1
difficile de comprendre ce que ça fait. pourquoi ne pas dormir 3650d
Pieter
1
Vous avez raison, le sommeil fonctionnerait probablement aussi bien que ma solution, mais il finira par s’éteindre :-D PS: je vais ajouter quelques commentaires, pour que ma solution soit facile à comprendre.
Qoomon