Piszę bardzo prosty skrypt bash, aby szybko sprawdzić, czy mój kontener nadal buduje się i uruchamia poprawnie oraz czy aplikacja w środku odpowiada na żądania.
Czasami docker run
kończy się to niepowodzeniem, np. Ponieważ port, z którym próbuję powiązać kontener, jest już przydzielony. Ale kiedy to się dzieje docker run
, kod zakończenia nadal wynosi 0, więc nie mogę użyć kodu zakończenia. Jak mogę programowo sprawdzić, czy kontener został uruchomiony poprawnie?
Rozważane przeze mnie rozwiązania to:
- analizuje dane wyjściowe pod kątem błędów
docker ps
aby sprawdzić, czy kontener jest uruchomiony
ale oba wydają się trochę przesadzone i brzydkie. Czy brakuje mi lepszego sposobu na sprawdzenie, czy się docker run
udało?
docker run
zwróci niezerowy kod powrotny w przypadku niepowodzenia, jak wskazują to wszystko można zrobić, to analizować dane wyjściowe (co może być skomplikowane lub kruche) lub użyć innego polecenia (czyli swojąps
sugestię ), aby sprawdzić wynik pierwszego polecenia. Możesz rozważyć wypełnienie zgłoszenia w dockerze, aby sprawdzić, czy mogą również naprawić kod powroturun
.docker run -d -p 9010:9010 busybox true ; echo $?
Odpowiedzi:
Jak zasugerował Abel Muiño w komentarzach, mogło to zostać naprawione w nowszych wersjach Dockera (obecnie używam 0.9.1).
Ale jeśli tymczasowo utkniesz tak jak ja ze starszą wersją, znalazłem przyzwoite obejście, aby sprawdzić, czy kontener zaczął używać
docker inspect
.docker inspect
zwraca obiekt JSON z dużą ilością informacji o kontenerze, w szczególności o tym, czy kontener jest aktualnie uruchomiony, czy nie.-f
Flaga pozwala łatwo wyodrębnić bity potrzebne:docker inspect -f {{.State.Running}} $CONTAINER_ID
lub
docker inspect -f "{{.State.Running}}" $CONTAINER_ID
zwróci
true
lubfalse
.Zauważ, że prawdopodobnie chcesz
sleep 1
(lub więcej) między uruchomieniem kontenera a sprawdzeniem, czy jest uruchomiony. Jeśli coś jest nie tak z twoją konfiguracją, możliwe, że przez bardzo krótki czas wydawałoby się, że działa ona, zanim faktycznie zakończy działanie.źródło
docker inspect -f {{.State.Running}} <container-id>
ijq
zamiast tego użyć ? Po prostu się zastanawiam.2> /dev/null
.2> /dev/null
ponieważ nie daje to niczego. Jak mogę ustawić go jako domyślny,false
jeśli kontener nie istnieje?Aby uniknąć parsowania czegokolwiek, możesz użyć docker top , który zwraca 1, jeśli kontener nie jest uruchomiony:
id=$(docker run mycontainer) if ! docker top $id &>/dev/null then echo "Container crashed unexpectedly..." return 1 fi
źródło
Przydałoby się
docker exec $id true 2>/dev/null || echo not running
.To polecenie nie zapisuje na stdout, jak robi to „docker top”. Zapisuje na stderr, gdy kontener nie jest uruchomiony, ten sam komunikat co „docker top”.
źródło
Zastosowanie powyższych sugestii do scenariusza.
1 - Utwórz skrypt 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 - Następnie po prostu dodaj go do crona, aby twój skrypt sprawdzał od czasu do czasu, czy twój kontener Docker jest aktywny:
Przejdź do ostatniej linii i dodaj plik skryptu. Na przykład:
3 - Zapisz plik crontab i nigdy nie martw się, że kontener Docker znowu się zepsuje.
Mam nadzieję, że to pomoże...
;-)
źródło
Musiałem użyć:
(kontener był w stanie uruchomionym, ale usługa wewnątrz kontenera nie została w pełni uruchomiona.
Część wyników kontroli:
"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": []
źródło