Як визначити, чи запустився докер успішно програмно?


83

Я пишу дуже простий скрипт bash, щоб швидко перевірити, чи мій контейнер все ще будується і запускається правильно, і що додаток всередині відповідає на запити.

Іноді docker runне вдається, наприклад, тому що порт, до якого я намагаюсь прив’язати контейнер, уже виділений. Але коли це трапляється docker run, код виходу все ще 0, тому я не можу використовувати код виходу. Як я можу програмно перевірити, чи правильно запущений контейнер?

Рішення, які я розглядаю:

  • проаналізувати вихідні дані щодо помилок
  • docker ps щоб перевірити, чи запущений контейнер

але це обидва здається трохи надмірним і потворним. Чи мені не вистачає кращого способу перевірити, чи docker runвдалося?


1
Я не впевнений, у чому тут проблема. Якщо процес, про який йде мова, веде себе звично, тоді ви можете просто перевірити код виходу. Якщо він видає код виходу 0 навіть для невдалих випадків, спробуйте зрозуміти, чи це помилка. Якщо програма повертає код виходу 0 у будь-якому випадку, то, мабуть, вам не залишається іншого вибору, як проаналізувати вихідні дані.
devnull

Як сказав @devnull, якщо ви не можете довіряти, що docker runповерне ненульовий код повернення при відмові, як ви вказали, тоді все, що ви можете зробити, це проаналізувати висновок (що може бути складним або крихким) або скористатися іншою командою (тобто вашою psпропозицією ), щоб перевірити результат першої команди. Можливо, ви захочете подати квиток у докер, щоб перевірити, чи можуть вони також виправити код повернення run.
Etan Reisner

Переконайтеся, що у вас остання версія.
ooga

Це спеціальний код, який запускається у вашому контейнері? якщо так, ви можете експортувати порт у своєму Dockerfile, коли ваша програма перебуває в стабільному запущеному стані, надішліть на цей порт повідомлення "OK". Ваш код клієнта чекає повідомлення "ОК".
rexposadas

3
Чи можете ви навести приклад того, як ви використовуєте docker і яку версію? Швидкий тест показує код виходу з докера для мене 1docker run -d -p 9010:9010 busybox true ; echo $?
Абель Муйньо

Відповіді:


118

Як пропонував Абель Муйньо в коментарях, можливо, це було виправлено в останніх версіях Docker (зараз я працюю 0.9.1).

Але, якщо ви тимчасово застрягли, як я, зі старою версією, я знайшов гідний обхідний шлях, щоб перевірити, чи запущений контейнер за допомогою docker inspect.

docker inspectповертає об'єкт JSON з великою кількістю інформації про контейнер, а зокрема про те, запущений контейнер на даний момент чи ні. -fПрапор дозволяє легко витягувати біти , необхідні:

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

або

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

повернеться trueабо false.

Зверніть увагу, що ви, мабуть, хочете sleep 1(або більше) між запуском контейнера та перевіркою, чи він запустився. Якщо з вашим налаштуванням щось не так, можливо, воно дуже швидко відображатиметься як «запущене» перед фактичним виходом.


11
Чому б не використовувати docker inspect -f {{.State.Running}} <container-id>і використовувати jqзамість цього? Просто цікаво.
Дхарміт

2
Оскільки я не підозрював, що перевірка дозволяє вам це робити безпосередньо! Дякую @DharmitShah, це чудова пропозиція, я оновлю свою відповідь.
Жуль Оллеон,

2
Щоб придушити повідомлення про помилку, якщо такого контейнера немає, переспрямуйте stderr за допомогою 2> /dev/null.
thSoft

Якщо я присвоюю це var, я отримую помилку під час використання, 2> /dev/nullоскільки вона нічого не оцінює. Як я можу зробити це за замовчуванням, falseякщо контейнер не існує?
Джейк Сенкі,

1
Однак це не вміщує контейнери, які постійно перезавантажуються через політику перезапуску ... Тобто, якщо контейнер отримує політику перезапуску, якщо-не зупинено / завжди, .State.Running завжди поверне true .... Просто щось до втомитися!
geekscrap

22

Щоб уникнути аналізу чого-небудь, ви можете використовувати docker top , який повертає 1, якщо контейнер не запущений:

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

10

Ми могли б використати docker exec $id true 2>/dev/null || echo not running.

Ця команда не записує в stdout, як це робить "docker top". Він пише в stderr, коли контейнер не запущений, те саме повідомлення, що і "docker top".


2

Застосування вищезазначених пропозицій до сценарію.

1 - Створіть скрипт 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 - Потім просто додайте його в cron, щоб ваш скрипт перевіряв, чи час від часу ваш контейнер Docker запущений:

crontab -e

Перейдіть до останнього рядка та додайте файл сценарію. Наприклад:

* * * * * /root/keepMyDockerUp.sh

3 - Збережіть crontab і ніколи не турбуйтеся про те, що ваш контейнер Docker знову не працює.

Сподіваюся, це допоможе ...

;-)


1

Мені довелося використовувати:

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

(контейнер був у стані, але служба всередині контейнера не була повністю запущена.

Частина результатів перевірки:

"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": []

Це не означало б, якщо пробіг був успішним. Оскільки контейнер може запуститися, а потім вийти з ладу.
Vino,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.