Verificare che il contenitore / servizio sia in esecuzione con la finestra mobile-componi


22

Sto usando il docker-compose.

Alcuni comandi come up -d service_nameo start service_namestanno tornando subito e questo è piuttosto utile se non si desidera che i contenitori in esecuzione dipendano dallo stato della shell, come fanno normalmente up service_name. L'unico caso d'uso lo sta eseguendo da una sorta di continuo server di integrazione / consegna.

Ma questo modo di eseguire / avviare i servizi non fornisce alcun feedback sullo stato attuale del servizio in seguito.

Il riferimento alla CLI Componi Docker per il upcomando menziona l'opzione pertinente, ma, come per la versione 1.7.1, si escludono a vicenda con -d:

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

Posso in qualche modo verificare manualmente che il contenitore funzioni davvero e che non si sia arrestato a causa di un errore?

Risposte:


15
  • docker-compose ps -q <service_name> visualizzerà l'ID contenitore, indipendentemente dal fatto che sia in esecuzione o meno, purché sia ​​stato creato.
  • docker ps mostra solo quelli che sono effettivamente in esecuzione.

Uniamo questi due comandi:

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 psmostra la versione breve degli ID per impostazione predefinita, quindi è necessario specificare il --no-truncflag.

AGGIORNAMENTO : ha generato un avviso "utilizzo grep" se il servizio non era in esecuzione. Grazie a @Dzhuneyt, ecco la risposta aggiornata.

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

Bello, e risolve anche il problema con la risposta attuale che è stata dichiarata nei commenti. Contrassegnando questa come una nuova risposta.
Ivan Kolmychek,

1
Se si utilizza un criterio di riavvio, è necessario filtrarlo per includere solo i contenitori in esecuzione (anziché quelli in stato di riavvio):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Max

1
Funziona ma genera un avviso di "utilizzo grep" se il servizio non è in esecuzione, in altre parole, quando la grep ....parte finisce con una stringa vuota.
Dzhuneyt,

@Dzhuneyt Lo so, sì, hai ragione. Pensi di evitare / gestire quell'avviso grep?
elquimista,

1
@elquimista Sì, ho risolto utilizzando l'operatore OR: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Ciò che fa è: controlla innanzitutto se il servizio esiste (anche se è stato arrestato) e la seconda parte controlla se il servizio esistente è effettivamente in esecuzione. Potresti voler includere questo nel tuo esempio per i futuri lettori che danno un'occhiata solo alla risposta accettata. Penso che sia utile
Dzhuneyt,

12

Per quanto riguarda la versione 1.7.1, non sono presenti comandi simili.

Invece, execpuò essere usato in modo simile.

Quando lo esegui per il servizio che ha alcuni contenitori, funzionerà bene:

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

Ma quando lo esegui per il servizio che non ha contenitori di servizi in esecuzione , mostrerà un errore:

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

Quindi, può essere usato per controllare, c'è qualche contenitore "vivo" per un determinato servizio.


5

Puoi eseguire:

docker-compose ps -q service-name

E otterrai l'id del contenitore se service-nameè in esecuzione. Qualcosa di simile a:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Se il servizio non è in esecuzione, l'output è vuoto, quindi se si desidera utilizzarlo in uno script è possibile fare qualcosa del tipo:

IS_RUNNING=`docker-compose ps -q service-name`
if [[ "$IS_RUNNING" != "" ]]; then
    echo "The service is running!!!"
fi

Sì, funziona anche quello. Contrassegnato come risposta ora.
Ivan Kolmychek,

12
Questo non ti dice se il contenitore è in esecuzione o meno, solo se esiste o no. Prova a fare docker-compose upquindi Ctrl-C. docker-compose psdovrebbe quindi mostrare che gli stati del contenitore non sono "Su", ma docker-compose ps -q service-nameti danno comunque un ID.
Djanderson,

2

Avevo un bisogno simile. Tuttavia, ho un restart: alwaysnel mio ambiente. Quindi può essere un po 'complicato rilevare se qualcosa si blocca e si riavvia in un ciclo.

Ho effettuato un controllo Icinga / Nagios per confrontare anche i tempi di creazione e inizio. Forse è utile a qualcun altro in fondo alla linea:

#!/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)

0

Se si assume questo scenario:

  • i contenitori si avviano ed eseguono indefinitamente o si arrestano immediatamente con un codice di errore (ad esempio per la configurazione mancante)
  • fai il controllo solo una volta dopo che la finestra mobile-compone up -d ritorna

si può controllare se c'è qualsiasi contenitore arrestato a causa di un errore con: docker ps -a | grep 'Exited (255)'.

Questo controllo funziona correttamente anche nel caso di contenitori che dovrebbero arrestarsi immediatamente senza errori (ad es. Contenitori di dati), poiché il loro stato (da docker ps -a) è contrassegnato come Exited (0).

Ad esempio, nel nostro docker-compose.yml, iniziamo i nostri contenitori con:

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

Per php-fpm, usiamo un comando simile:

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

Gli script dotenv_check.jse dotenv_check.phpsono che escono con un codice di errore nel caso in cui manchi una variabile env richiesta.

Il set -ecomando indica allo script di interrompere l'errore, che a sua volta interromperà immediatamente il contenitore. Informazioni su set-e


0

Cosa ne pensi di questo?

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

si elencano i processi, si selezionano le righe in cui "Up" è nella colonna 4 e si filtra per una corrispondenza sul nome del servizio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.