La forma correcta de mantener el contenedor acoplable iniciado cuando se utiliza para tareas periódicas

41

Tengo un contenedor Docker con software instalado y configurado.

No se supone que ningún programa se inicie / ejecute todo el tiempo.

Lo que quiero: su capacidad para iniciar algún comando en función de eventos externos. me gusta:

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

y

docker exec mysupercont /path/to/myothercommand 

Pero "exec" es imposible cuando se detiene el contenedor, y también este contenedor tiene algunos datos "funcionales" en el interior, que se utilizan para esos comandos, por lo que no puedo usar

docker run ...

cada vez, porque recrea el contenedor de la imagen y destruye mis datos.

¿Cuál es la forma "correcta" y la "mejor" para mantener ese contenedor en funcionamiento? ¿Qué comando puedo comenzar adentro?

Korjavin Ivan
fuente
Esta es una pregunta muy bien explicada. Ver otra publicación similar aquí .
Grant Li
1
docker run -d --name=name container tail -f /dev/null
impulsado por vapor el

Respuestas:

46

No necesita realizar cada vez docker run.

docker run es en realidad una secuencia de dos comandos: "crear" y "iniciar".

Cuando ejecute el contenedor, debe especificar " -it":

-i, --interactive = false Mantenga STDIN abierto incluso si no está adjunto
-t, --tty = false Asigne un pseudo-TTY

Ejemplo:

docker run -it debian:stable bash

Después de que el trabajo se completó el comando especificado al inicio (en mi ejemplo bash). Por ejemplo, realiza la "salida". Contenedor se detiene:

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

Ahora puedes comenzar de nuevo

docker start 1329c99a831b

El contenedor se inicia y nuevamente ejecuta el comando "bash".
Conéctese a esta sesión "bash" con el comando

docker attach 1329c99a831b

Para resumir : tienes que entender la diferencia entre el runy el startcontenedor.
Además, mire la documentación para el papel de los parámetros " -i t" y " -d" para el "Ejecutar"

MSemochkin
fuente
1
Ajá, entiendo esto. La pregunta era: no tengo nada que ejecutar dentro del contenedor, pero necesito mantenerlo en estado de "ejecución". Entonces, su respuesta es: ¿usar bash para mantener el contenedor en estado de ejecución?
Korjavin Ivan
Sí. El proceso que especificó en tiempo de ejecución debe ejecutarse en el contenedor para que continúe funcionando. El ejemplo más simple es bash. Quizás sea la forma más fácil de iniciar el contenedor con "-d" y conectarse a él según sea necesario mediante docker attach ID. Sal de esta sesión sin finalizar bash, puedes usarCTRL-p CTRL-q
MSemochkin
El proceso que especifique durante la ejecución del contenedor recibe el PID 1. En consecuencia, el contenedor simplemente no puede funcionar sin él ☺
MSemochkin
Mi experiencia con start y attach (o start con -ai) es que no se muestra la edición rápida e interactiva de su línea de comando. Por ejemplo, el tty no está renderizando ni haciendo eco.
dlamblin
1
Esto es ingenioso. Tenga en cuenta que si desea iniciar el contenedor en segundo plano sin tener que volver a iniciarlo manualmente (por ejemplo, si está ejecutando un servicio web), use los parámetros '-itd' y CTRL-p CTRL-q para desconectar sin detener el envase.
taranaki
6

Todo este asunto de si puede o no iniciar un contenedor detenido depende de cómo se creó originalmente el contenedor, es decir, de cómo se ejecuta. Si ejecutó un comando que finalizó o sale de un comando interactivo, por ejemplo, bash, no puede iniciar, reiniciar o ejecutar el contenedor detenido. Todo lo que puedes hacer es eliminarlo. Es basura

Pero el último comentario de taranaki, use '-itd', parece ser lo que ordenó el acoplador.

El contenedor sigue ejecutándose, y puede ejecutar lo que quiera, y puede detener, iniciar o reiniciar el contenedor. Por supuesto, esto es solo un hallazgo preliminar basado en la imagen alpina. Tenga en cuenta que si se conecta al contenedor, se detendrá cuando salga, pero puede iniciarlo nuevamente.

Sue Parker
fuente
3
+1 "parece ser lo que ordenó el acoplador" :-)
Matt Alexander
5

Como mencionó las tareas periódicas y probablemente esté usando algo como cron debido a la forma en que desea usar docker exec, tengo la medicina para usted. Al menos terminé haciendo algo como esto.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Corre con lo habitual docker run -d ....(solía docker-compose)

  3. Configurar máquinas host crontab, por ejemplo:

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

Considero que esta solución es agradable, ya que podemos confiar en el antiguo y probado crontab en un entorno Linux bastante predeterminado, mientras que Docker maneja los deps y las variables de entorno más exóticos de su lógica de negocios. También puede establecer algunos límites si sus tareas periódicas se atascan y tienen pérdidas de memoria o lo que sea.

elnygren
fuente
0

La cola seguirá causando algunas operaciones de archivo de vez en cuando.

Aquí está mi solución para dormir para siempre, sin efectos secundarios.

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

Cómo funciona

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
fuente
1
Difícil de entender lo que está haciendo. ¿por qué no solo dormir 3650d?
Pieter
1
Tienes razón, el sueño probablemente funcionaría tan bien como mi solución, sin embargo, el tiempo de espera terminará eventualmente :-D PD: Agregaré algunos comentarios, para que mi solución sea fácil de entender.
qoomon