Docker healthcheck

Ich habe mich gewundert, warum bei docker ps bei einigen Containern ein (healthy) hinter der uptime steht, bei anderen aber nicht. Dem bin ich mal nachgegangen.

Docker Logo (Wikipedia/dotCloud Inc. Apache Licence 2.0)
Docker Logo (Wikipedia/dotCloud Inc. Apache Licence 2.0)(

(healthy)

Mit dem Status (healthy) zeigt docker an, dass der Container vollständig einsatzbereit ist. Ohne diesen Zusatz ist nur sichergestellt, dass der Prozess des Containers läuft. Ob der z.B. darin integrierte Apache Server richtig läuft, ist völlig unklar. Diese Information kann der Dockerservice nur vom Container selbst über den sog. healthcheck erfragen. Manche Container stellen diesen zu Verfügung, wie bei mir ClamAV, Nextcloud tut dies aber nicht von sich aus.

Die Ausgangslage: beim nextcloud Container steht kein (healthy), bei clamav aber schon
raspithek.de - Olli Graf
docker-ps-orgCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Die Ausgangslage: beim nextcloud Container steht kein (healthy), bei clamav aber schon

healthcheck

Der Healthcheck besteht ganz simple aus einem Kommando, das den korrekten Zustand des Containers abfragt. In vielen Fällen ist das ein URL-Aufruf.

Healthcheck selber definieren

Da Nextcloud von sich aus keinen Healthcheck zur Verfügung stellt, rüsten wir ihn jetzt im docker-compose.yml einfach nach.

Dazu fügst du einfach den folgenden Block in die Datei ein.

healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/status.php"]
      interval: "30s"      # alle 30 Sekunden prüfen
      timeout: "10s"       # max. 10 Sekunden auf Antwort warten
      retries: "3"         # nach 3 Fehlversuchen gilt der Container als unhealthy
      start_period: "1m"   # Wartezeit nach dem Start, bevor geprüft wird

Ich habe den Block vor die volumes: Sektion gesetzt.

Die Konfiguration erklärt sich fast von selbst. Unter test: steht das Kommando, das gegen den Container abgesetzt wird. In unserem Fall wird mit curl die status.php Seite vom Container abgerufen. Durch interval: wird dies alle 30 Sekunden wiederholt. timeout: gibt an, dass max. 10 Sekunden auf ein Ergebnis des Kommandos gewartet werden soll. Mit retries: werden drei Wiederholungen erlaubt. Da der Container beim Start u.U. etwas Zeit benötigt, alles vollständig hochzufahren, verzögern wir mit start_period: den ersten healthcheck Aufruf um eine Minute nach Containerstart.

Das Ergebnis zeigt sich nach einem docker-compose up -d und einer angemessenen Wartezeit.

Mit der healthcheck Konfiguration hat auch der Nextcloud Container das (healthy) im Status.
raspithek.de - Olli Graf
docker-ps-healthyCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Mit der healthcheck Konfiguration hat auch der Nextcloud Container das (healthy) im Status.

health Status abfragen

Der (healthy) soll natürlich nicht nur der Optik auf der Übersichtsseite dienen, wir können ihn auch auswerten. Mit docker inspect nextcloud erhalten wir detaillierte Informationen zum Zustand unseres Containers im JSON Format. Darin befindet sich auch ein Eintrag "Status": "healthy". Da wir den Gesamtzustand überhaupt nicht benötigen, filtern wir uns nur den Wert raus, den wir brauchen.

docker inspect --format='{{.State.Health.Status}}' nextcloud

Dies liefert uns nur den String „healthy“. Um den automatisch auszuwerten habe ich ein kleines bash Script geschrieben

#!/bin/bash
# containerhealth <container-name>

CONTAINER="${1}"

if [ -z "${CONTAINER}" ]; then
    echo "Usage: ${0} <container-name>"
    exit 2
fi

# Health-Status abfragen
STATUS=$(docker inspect --format='{{.State.Health.Status}}' "${CONTAINER}" 2>/dev/null)

# Prüfen, ob Container überhaupt existiert
if [ $? -ne 0 ]; then
    echo "Container '${CONTAINER}' not found"
    exit 2
fi

case "${STATUS}" in
  healthy)
    # exit code 0 wenn healthy
    exit 0
    ;;
  unhealthy|starting)
    # exit code 1 bei unhealthy oder starting
    exit 1
    ;;
  "")
    # Wenn leer -> kein Healthcheck definiert, exit code 3
    exit 3
    ;;
  *)
    # Unerwarteter Status, exit code 2
    exit 2

Das Script liefert nur dann einen exit Code 0, wenn der Status des angegebenen Containers "healthy" ist.

Fazit

Stellt ein Container nicht von sich aus einen Healthcheck zur Verfügung, können wir ihn relativ einfach selber nachrüsten.

Das komplette docker-compose.yml kannst du dir hier runterladen.

Schreibe einen Kommentar

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert
Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
raspithek.de - Olli Graf
WordPress Cookie Hinweis von Real Cookie Banner