¿Cómo detectar si la ejecución de Docker se realizó correctamente mediante programación?

82

Estoy escribiendo un script bash muy simple para verificar rápidamente que mi contenedor aún se construye y se inicia correctamente y que la aplicación interna responde a las solicitudes.

A veces docker runfalla, por ejemplo, porque el puerto al que estoy tratando de vincular el contenedor ya está asignado. Pero cuando esto sucede docker run, el código de salida sigue siendo 0, por lo que no puedo usar el código de salida. ¿Cómo puedo comprobar mediante programación que el contenedor se inició correctamente?

Las soluciones que estoy considerando son:

  • analizar la salida en busca de errores
  • docker ps para ver si el contenedor está funcionando

pero ambos parecen un poco exagerados y feos. ¿Me estoy perdiendo una forma mejor de comprobar si se ha realizado docker runcorrectamente?

Jules Olléon
fuente
1
No estoy seguro de cuál es el problema aquí. Si el proceso en cuestión se comporta de la manera habitual, simplemente puede verificar el código de salida. Si emite un código de salida de 0 incluso para casos fallidos, intente averiguar si es un error. Si el programa devuelve un código de salida de 0 en cualquier caso, probablemente no le quede más remedio que analizar la salida.
devnull
Como dijo @devnull, si no puede confiar en que docker rundevolverá un código de retorno distinto de cero en caso de falla, como lo indica, todo lo que puede hacer es analizar la salida (que puede ser complicada o frágil) o usar otro comando (es decir, su pssugerencia ) para comprobar el resultado del primer comando. Es posible que desee considerar la posibilidad de presentar un ticket con Docker para ver si pueden corregir el código de retorno runtambién.
Etan Reisner
Asegúrese de tener la última versión.
ooga
¿Es un código personalizado que se ejecuta en su contenedor? si es así, puede exportar un puerto en su Dockerfile, cuando su programa esté en un estado de ejecución estable envíe un mensaje "OK" en ese puerto. Su código de cliente espera el mensaje "OK".
rexposadas
3
¿Puede proporcionar un ejemplo de cómo está ejecutando la ventana acoplable y qué versión? Una prueba rápida muestra que el código de salida de la ventana acoplable es 1 para mídocker run -d -p 9010:9010 busybox true ; echo $?
Abel Muiño

Respuestas:

116

Como sugirió Abel Muiño en los comentarios, esto puede haberse solucionado en versiones más recientes de Docker (actualmente estoy ejecutando 0.9.1).

Pero, si está atrapado temporalmente como yo con una versión anterior, encontré una solución decente para verificar si el contenedor comenzó a usar docker inspect.

docker inspectdevuelve un objeto JSON con mucha información sobre el contenedor y, en particular, si el contenedor se está ejecutando actualmente o no. La -fbandera le permite extraer fácilmente los bits necesarios:

docker inspect -f {{.State.Running}} $CONTAINER_ID

o

docker inspect -f "{{.State.Running}}" $CONTAINER_ID

volverá trueo false.

Tenga en cuenta que probablemente desee sleep 1(o más) entre iniciar el contenedor y verificar si está activo. Si hay algún problema con su configuración, es posible que aparezca como "en ejecución" durante muy poco tiempo antes de salir.

Jules Olléon
fuente
11
¿Por qué no usar docker inspect -f {{.State.Running}} <container-id>y usar jqen su lugar? Sólo me preguntaba.
Dharmit
2
¡Porque no me había dado cuenta de que inspeccionar te permite hacer esto directamente! Gracias @DharmitShah, esa es una gran sugerencia, actualizaré mi respuesta.
Jules Olléon
2
Para suprimir el mensaje de error si no existe tal contenedor, redirija stderr con 2> /dev/null.
ThSoft
Si estoy asignando esto a una var, obtengo un error al usarlo, 2> /dev/nullya que no evalúa nada. ¿Cómo puedo hacer que sea predeterminado falsesi el contenedor no existe?
Jake Sankey
1
Sin embargo, esto no se adapta a los contenedores que se reinician constantemente debido a la política de reinicio ... Es decir, si a un contenedor se le asigna una política de reinicio de menos que detenido / siempre, .State.Running siempre devolverá verdadero ... cansarse de!
geekscrap
22

Para evitar analizar cualquier cosa, puede usar docker top , que devuelve 1 si el contenedor no se está ejecutando:

id=$(docker run mycontainer)
if ! docker top $id &>/dev/null
then
    echo "Container crashed unexpectedly..."
    return 1
fi
pedroapero
fuente
10

Podríamos usar docker exec $id true 2>/dev/null || echo not running.

Este comando no escribe en stdout, como lo hace "docker top". Escribe en stderr cuando el contenedor no se está ejecutando, el mismo mensaje que "docker top".

simohe
fuente
2

Aplicar las sugerencias antes mencionadas a un guión.

1 - Cree un script keepMyDockerUp.sh :

vi keepMyDockerUp.sh


#!/bin/bash
Container_ID=INSERT_YOUR_CONTAINER_ID HERE
result=$( docker inspect -f {{.State.Running}} $Container_ID)
echo "result is" $result
if [ $result = "true" ]
then
echo "docker is already running"
else
systemctl restart docker
docker start $Container_ID
fi

2 - Luego, simplemente agréguelo a cron, para que su script verifique si su contenedor Docker está activo de vez en cuando:

crontab -e

Vaya a la última línea y agregue su archivo de secuencia de comandos. Por ejemplo:

* * * * * /root/keepMyDockerUp.sh

3 - Guarde crontab y nunca se preocupe de que su contenedor Docker se caiga nuevamente.

Espero eso ayude...

;-)

Israel
fuente
1

Tuve que usar:

$ docker inspect -f {{.State.Health.Status}} xxx

(el contenedor estaba en ejecución, pero el servicio dentro del contenedor no se inició por completo.

Parte de la salida de inspección:

"State": {
    "Status": "running",
    "Running": true,
    "Paused": false,
    "Restarting": false,
    "OOMKilled": false,
    "Dead": false,
    "Pid": 1618,
    "ExitCode": 0,
    "Error": "",
    "StartedAt": "2019-03-08T10:39:24.061732398Z",
    "FinishedAt": "0001-01-01T00:00:00Z",
    "Health": {
        "Status": "starting",
        "FailingStreak": 0,
        "Log": []
lvthillo
fuente
Esto no indicaría si la ejecución fue exitosa. Porque un contenedor puede ejecutarse y luego fallar.
Vino