Wie kann festgestellt werden, ob der Docker-Lauf programmgesteuert erfolgreich war?

81

Ich schreibe ein sehr einfaches Bash-Skript, um schnell zu überprüfen, ob mein Container noch erstellt und korrekt gestartet wird und ob die darin enthaltene App auf Anforderungen reagiert.

docker runSchlägt manchmal fehl, z. B. weil der Port, an den ich den Container binden möchte, bereits zugewiesen ist. In diesem Fall ist docker runder Exit-Code jedoch immer noch 0, sodass ich den Exit-Code nicht verwenden kann. Wie kann ich programmgesteuert überprüfen, ob der Container korrekt gestartet wurde?

Die Lösungen, die ich in Betracht ziehe, sind:

  • Analysieren Sie die Ausgabe auf Fehler
  • docker ps um zu sehen, ob der Container läuft

aber diese beiden scheinen ein wenig übertrieben und hässlich. Vermisse ich einen besseren Weg, um zu überprüfen, ob dies docker runerfolgreich war?

Jules Olléon
quelle
1
Ich bin mir nicht sicher, wo das Problem liegt. Wenn sich der betreffende Prozess wie gewohnt verhält, können Sie einfach nach dem Exit-Code suchen. Wenn selbst in fehlgeschlagenen Fällen ein Exit-Code von 0 ausgegeben wird, versuchen Sie herauszufinden, ob es sich um einen Fehler handelt. Wenn das Programm in jedem Fall den Exit-Code 0 zurückgibt, bleibt Ihnen wahrscheinlich keine andere Wahl, als die Ausgabe zu analysieren.
devnull
Wie @devnull sagte, wenn Sie nicht vertrauen können, dass docker runbei einem Fehler ein Rückkehrcode ungleich Null zurückgegeben wird, wie Sie angeben, können Sie nur die Ausgabe analysieren (die kompliziert oder fragil sein kann) oder einen anderen Befehl verwenden (dh Ihren psVorschlag) ), um das Ergebnis des ersten Befehls zu überprüfen. Vielleicht möchten Sie ein Ticket bei Docker einreichen, um zu sehen, ob sie auch den Rückkehrcode von Docker korrigieren können run.
Etan Reisner
Stellen Sie sicher, dass Sie die neueste Version haben.
ooga
Wird in Ihrem Container benutzerdefinierter Code ausgeführt? In diesem Fall können Sie einen Port in Ihre Docker-Datei exportieren. Wenn sich Ihr Programm in einem stabilen Betriebszustand befindet, senden Sie eine "OK" -Nachricht an diesen Port. Ihr Client-Code wartet auf die Meldung "OK".
rexposadas
3
Können Sie ein Beispiel dafür geben, wie Docker ausgeführt wird und welche Version? Ein schneller Test zeigt, dass der Docker-Exit-Code für mich 1 istdocker run -d -p 9010:9010 busybox true ; echo $?
Abel Muiño

Antworten:

116

Wie von Abel Muiño in den Kommentaren vorgeschlagen, wurde dies möglicherweise in neueren Docker-Versionen behoben (ich verwende derzeit 0.9.1).

Wenn Sie jedoch vorübergehend wie ich mit einer älteren Version nicht weiterkommen, habe ich eine angemessene Problemumgehung gefunden, um zu überprüfen, ob der Container mit der Verwendung begonnen hat docker inspect.

docker inspectGibt ein JSON-Objekt mit vielen Informationen zum Container zurück, insbesondere, ob der Container gerade ausgeführt wird oder nicht. Mit dem -fFlag können Sie einfach die benötigten Bits extrahieren:

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

oder

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

wird zurückkehren trueoder false.

Beachten Sie, dass Sie wahrscheinlich sleep 1(oder mehr) zwischen dem Starten des Containers und dem Überprüfen, ob er aktiv ist, möchten . Wenn etwas mit Ihrem Setup nicht stimmt, wird es möglicherweise für eine sehr kurze Zeit als "laufend" angezeigt, bevor es tatsächlich beendet wird.

Jules Olléon
quelle
11
Warum nicht stattdessen verwenden docker inspect -f {{.State.Running}} <container-id>und verwenden jq? Ich wundere mich nur.
Dharmit
2
Weil ich nicht bemerkt hatte, dass inspect Sie dies direkt tun lässt! Danke @DharmitShah, das ist ein großartiger Vorschlag. Ich werde meine Antwort aktualisieren.
Jules Olléon
2
Um die Fehlermeldung zu unterdrücken, wenn kein solcher Container vorhanden ist, leiten Sie stderr mit um 2> /dev/null.
ThSoft
Wenn ich dies einer Variablen zuordne, wird bei der Verwendung eine Fehlermeldung angezeigt, 2> /dev/nullda keine Auswertung erfolgt. Wie kann ich festlegen, falsedass der Container nicht vorhanden ist?
Jake Sankey
1
Dies gilt jedoch nicht für Container, die aufgrund der Neustartrichtlinie ständig neu gestartet werden. Wenn einem Container die Neustartrichtlinie "Wenn nicht gestoppt / immer" zugewiesen wird, gibt .State.Running immer "true" zurück. Nur etwas zu sei müde von!
Geekscrap
22

Um zu vermeiden, dass etwas analysiert wird, können Sie Docker Top verwenden , das 1 zurückgibt, wenn der Container nicht ausgeführt wird:

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

Wir könnten gebrauchen docker exec $id true 2>/dev/null || echo not running .

Dieser Befehl schreibt nicht wie "Docker Top" in stdout. Es schreibt in stderr, wenn der Container nicht ausgeführt wird, dieselbe Meldung wie "Docker Top".

simohe
quelle
2

Anwenden der oben genannten Vorschläge auf ein Skript.

1 - Erstellen Sie ein Skript 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 - Fügen Sie es dann einfach zu cron hinzu, damit Ihr Skript von Zeit zu Zeit überprüft, ob Ihr Docker-Container aktiv ist:

crontab -e

Gehen Sie zur letzten Zeile und fügen Sie Ihre Skriptdatei hinzu. Beispielsweise:

* * * * * /root/keepMyDockerUp.sh

3 - Speichern Sie crontab und machen Sie sich keine Sorgen, dass Ihr Docker-Container wieder heruntergefahren wird.

Ich hoffe es hilft...

;-);

Israel
quelle
1

Ich musste verwenden:

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

(Der Container wurde ausgeführt, aber der Dienst im Container wurde nicht vollständig gestartet.

Teil der Inspektionsausgabe:

"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
quelle
Dies würde nicht angeben, ob der Lauf erfolgreich war. Weil ein Container möglicherweise ausgeführt wird und dann ausfällt.
Vino