Check es el contenedor / servicio que se ejecuta con docker-compose

22

Estoy usando el docker-compose.

Algunos comandos tienen gusto up -d service_nameo start service_nameestán regresando de inmediato y esto es bastante útil si no desea que los contenedores en ejecución dependan del estado del shell, como lo hacen con regular up service_name. El único caso de uso lo ejecuta desde algún tipo de servidor continuo de integración / entrega.

Pero esta forma de ejecutar / iniciar servicios no proporciona ningún comentario sobre el estado real del servicio posterior.

La referencia de Docker Compose CLI para el upcomando menciona la opción relevante, pero, en cuanto a la versión 1.7.1, es mutuamente exclusiva con -d:

--abort-on-container-exit  Stops all containers if any container was stopped.
                           *Incompatible with -d.*

¿De alguna manera puedo verificar manualmente que el contenedor realmente funciona y no se ha detenido debido a algún error?

Ivan Kolmychek
fuente

Respuestas:

15
  • docker-compose ps -q <service_name> mostrará la ID del contenedor sin importar si se está ejecutando o no, siempre que se haya creado.
  • docker ps muestra solo aquellos que realmente se están ejecutando.

Combinemos estos dos comandos:

if [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then
  echo "No, it's not running."
else
  echo "Yes, it's running."
fi

docker psmuestra una versión corta de las ID de forma predeterminada, por lo que debemos especificar el --no-truncindicador.

ACTUALIZACIÓN : arrojó una advertencia de "uso grep" si el servicio no se estaba ejecutando. Gracias a @Dzhuneyt, aquí está la respuesta actualizada.

if [ -z `docker-compose ps -q <service_name>` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then
  echo "No, it's not running."
else
  echo "Yes, it's running."
fi
elquimista
fuente
Agradable, y también aborda el problema con la respuesta actual que se indicó en los comentarios. Marcar esto como una nueva respuesta.
Ivan Kolmychek
1
Si está utilizando una política de reinicio, también debe filtrarla para incluir solo los contenedores en ejecución (en lugar de los que se encuentran en un estado de reinicio):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Máximo
1
Esto funciona, pero arroja una advertencia de "uso grep" si el servicio no se está ejecutando, en otras palabras, cuando la grep ....parte termina con una cadena vacía.
Dzhuneyt
@ Dzhuneyt Lo sé, sí, tienes razón. ¿Pensamientos para evitar / manejar esa advertencia grep?
elquimista
1
@elquimista Sí, lo resolví usando el operador OR: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Lo que esto hace es: primero verifica si el servicio existe (incluso si está detenido) y la segunda parte verifica si el servicio existente se está ejecutando realmente. Es posible que desee incluir esto en su ejemplo para futuros lectores que solo lean la respuesta aceptada. Pienso que es útil.
Dzhuneyt
12

En cuanto a la versión 1.7.1, no hay tales comandos incorporados.

En cambio, execse puede usar de manera similar.

Cuando lo ejecute para el servicio que tiene algunos contenedores, se ejecutará correctamente:

~/apperture-science $ docker-compose exec chell echo 'Still alive!'
Still alive!
~/apperture-science $ echo $?
0

Pero cuando lo ejecuta para el servicio que no tiene contenedores de servicio en ejecución , mostrará un error:

~/apperture-science $ docker-compose exec glados echo "Still alive!"
ERROR: No container found for apperture-science-glados_1
~/apperture-science $ echo $?
1

Por lo tanto, se puede utilizar para verificar si hay algún contenedor "vivo" para un servicio dado.

Ivan Kolmychek
fuente
5

Tu puedes correr:

docker-compose ps -q service-name

Y obtendrá la identificación del contenedor si se service-nameestá ejecutando. Algo como:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Si el servicio no se está ejecutando, la salida está vacía, por lo que si desea usar esto en un script, puede hacer algo como:

IS_RUNNING=`docker-compose ps -q service-name`
if [[ "$IS_RUNNING" != "" ]]; then
    echo "The service is running!!!"
fi
alejandropg
fuente
Sí, eso también funciona. Marcó esto como respuesta ahora.
Ivan Kolmychek
12
Esto no le indica si el contenedor se está ejecutando o no, solo si existe o no. Intenta hacer docker-compose upluego Ctrl-C. docker-compose psentonces debería mostrar que los estados del contenedor no están "arriba", pero docker-compose ps -q service-nameaún así le da una identificación.
djanderson
2

Tenía una necesidad similar Sin embargo, tengo un restart: alwaysen mi entorno. Por lo tanto, puede ser un poco complicado detectar si algo falla y se reinicia en un bucle.

Hice una comprobación de Icinga / Nagios para comparar también los tiempos creados y de inicio. Tal vez sea útil para alguien más en el futuro:

#!/usr/bin/env python
from __future__ import print_function
import argparse
from datetime import timedelta
from datetime import datetime
import sys

from dateutil.parser import parse as parse_date
import docker
import pytz
parser = argparse.ArgumentParser()
parser.add_argument("compose_project",
                    help="The name of the docker-compose project")
parser.add_argument("compose_service",
                    help="The name of the docker-compose service")
args = vars(parser.parse_args())

client = docker.from_env()
service_containers = client.containers.list(filters={
    "label": [
        "com.docker.compose.oneoff=False",
        "com.docker.compose.project={}".format(args["compose_project"]),
        "com.docker.compose.service={}".format(args["compose_service"])
    ]})

if len(service_containers) == 0:
    print("CRITICAL: project({})/service({}) doesn't exist!".format(
        args["compose_project"], args["compose_service"]))
    sys.exit(2)
elif len(service_containers) > 1:
    print("CRITICAL: project({})/service({}) has more than 1 "
          "container!".format(
              args["compose_project"], args["compose_service"]))
    sys.exit(2)

service_container = service_containers[0]
created_at = parse_date(service_container.attrs['Created'])
status = service_container.attrs['State']['Status']
started_at = parse_date(service_container.attrs['State']['StartedAt'])
now = datetime.utcnow().replace(tzinfo=pytz.utc)
uptime = now - started_at

if status in ['stopped', 'exited', 'dead']:
    print("CRITICAL: project({})/service({}) is status={}".format(
        args["compose_project"], args["compose_service"], status))
    sys.exit(2)

if (started_at - created_at) > timedelta(minutes=5):
    if uptime < timedelta(seconds=5):
        print("CRITICAL: project({})/service({}) appears to be "
              "crash-looping".format(
                  args["compose_project"], args["compose_service"]))
        sys.exit(2)

if status == "restarting":
    print("WARNING: project({})/service({}) is restarting".format(
        args["compose_project"], args["compose_service"]))
    sys.exit(1)

print ("OK: project({})/service({}) is up for {}".format(
    args["compose_project"], args["compose_service"], uptime
))
sys.exit(0)
jof
fuente
0

Si asume este escenario:

  • los contenedores se inician y se ejecutan indefinidamente o se detienen inmediatamente con un código de error (es decir, por falta de configuración)
  • realiza la comprobación solo una vez después de que docker-compose up -d devuelve

se puede comprobar si hay algún recipiente detenido debido a un error con: docker ps -a | grep 'Exited (255)'.

Esta comprobación funciona correctamente incluso en el caso de contenedores que se espera que se detengan inmediatamente sin error (es decir, contenedores de datos), ya que su estado (desde docker ps -a) está marcado como Exited (0).

Por ejemplo, en nuestro docker-compose.yml, comenzamos nuestros contenedores con:

command: sh -c 'node dotenv_check.js && pm2 start --no-daemon src/worker.js --watch'

Para php-fpm, usamos un comando similar:

command: >-
  sh -c '
  set -e;
  for PROJECT in frontend backend; do
    cd /var/www/$${PROJECT};
    php dotenv_check.php;
  done;
  php-fpm
  '

Los dotenv_check.jsy dotenv_check.phpson scripts que salen con un código de error en caso de que falte una variable env requerida.

El set -ecomando le dice al script que se detenga en caso de error, lo que, a su vez, detendrá inmediatamente el contenedor. Sobre set-e

Fabio
fuente
0

¿Qué tal esto?

docker-compose ps | awk '$4 == "Up" {print $1}' | grep <service-name>

enumera los procesos, selecciona las líneas donde está "Arriba" en la columna 4 y filtra para encontrar una coincidencia en el nombre del servicio.

George Mauer
fuente