Вопрос или проблема
Я могу быть немного сбит с толку, но я хочу, чтобы проверка состояния выполнялась вне контейнера, например, на хосте. Я не понимаю, почему сам Docker не может сделать curl к контейнеру, чтобы определить, здоров ли он.
healthcheck:
test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep '\"status\":\"green\"'"]
interval: 10s
retries: 10
start_period: 30s
timeout: 5s
Но в коробке нет curl, и я читал, что добавление curl никогда не является хорошей идеей; так как я могу запустить эту проверку без curl на коробке? Могу ли я каким-то образом запустить это из приложения Docker или из другого контейнера, который может установить статус здоровья этой коробки в Docker?
Простой ответ состоит в том, что вы не можете определить тест в вашем файле компоновки, который выполняется вне контейнера, поэтому то, что вы спрашиваете, невозможно.
Вместо этого подумайте о том, какие команды у вас есть внутри контейнера, когда он работает.
Если curl
недоступен, возможно, доступен wget
или, как я использовал недавно, pidof
.
pidof
можно использовать для определения PID (идентификатора процесса) работающего процесса. Если процесс не запущен, значит, служба нездорова. Я не знаю, какой http-демон вы используете, но пример ниже ищет идентификатор процесса nginx и сообщает, какой он.
healthcheck:
test: ["CMD", "pidof", "nginx"]
interval: 30s
timeout: 10s
retries: 3
pidof
вернёт код завершения 0
, когда найдёт PID или PIDs искомого процесса, и код завершения 1
, когда не найдёт PID.
Однако предупреждение: если вы пытаетесь получить статус веб-страницы или приложения, которое может генерироваться динамически (PHP, Node, Python, .NET и т.д.), и только код не работает, но nginx всё еще запущен, использование pidof для проверки работы nginx, очевидно, не скажет вам, что ваш код/веб-сайт не работает.
pidof
также имеет другие опции, которые могут помочь, если использование его в исходном виде не подходит для ваших обстоятельств. Я не собираюсь пересказывать руководство для него, поэтому вот ссылка: https://man7.org/linux/man-pages/man1/pidof.1.html
Если вам просто нужно знать, что служба работает и вы не зависите от статуса здоровья Docker, вы можете использовать что-то вроде Uptime Kuma, чтобы проверить этот HTTP-эндпоинт для вас, но, конечно, вам нужно будет открыть HTTP-порт на хосте, чтобы Uptime Kuma мог его проверить – а затем вам может понадобиться проверка состояния Docker на Uptime Kuma… и тогда… начинается режим Инсепшн.
Ответ или решение
Чтобы выполнить проверку состояния (healthcheck) приложения Docker, находясь вне контейнера, необходимо учитывать некоторые ограничения и возможности. Docker, как платформа, не позволяет прямую реализацию проверок состояния контейнеров на уровне хоста. Вместо этого проверки состояния должны быть определены внутри контейнера. Однако есть несколько стратегий, которые могут помочь в решении вашей проблемы.
1. Использование pidof
для проверки процесса
Если внутри контейнера отсутствует curl
, но доступна команда pidof
, вы можете использовать ее для проверки состояния запущенного процесса. Например, если вы используете Nginx, вы можете настроить healthcheck следующим образом:
healthcheck:
test: ["CMD", "pidof", "nginx"]
interval: 30s
timeout: 10s
retries: 3
Команда pidof
возвращает статус 0, если процесс найден, и 1, если процесс не запущен. Этот метод прост и эффективен, но, обратите внимание, что он не проверяет работоспособность вашего приложения на уровне HTTP. Это означет, что, если Nginx работает, но ваше приложение возвращает ошибку, проверка пройдет успешно, что может создать ложное чувство уверенности.
2. Использование других средств проверки состояния
Если нужно проверить именно HTTP-ответ вашего приложения, и curl
недоступен, вы можете рассмотреть возможность использования других инструментов, таких как wget
или busybox
, если они установлены. Если ваше приложение доступно через HTTP, вы можете использовать следующий healthcheck:
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://localhost:9200/_cluster/health && grep '\"status\":\"green\"'"]
interval: 10s
timeout: 5s
retries: 10
Этот подход позволит проверить, доступен ли ваш HTTP-сервис и соответствует ли он ожиданиям.
3. Внедрение внешних решений для мониторинга
Если вы хотите провести мониторинг приложения на уровне хоста, рассмотрите возможность использования сторонних инструментов, таких как Uptime Kuma или Prometheus. Эти инструменты могут быть запущены в Docker-контейнере или установлены напрямую на хост-систему.
Например, Uptime Kuma позволяет проверять различные HTTP-эндпоинты и будет сообщать вам о любых сбоях, что может служить дополнением к вашим проверкам состояния контейнеров.
4. Запуск проверки из другого контейнера
Как вариант, вы можете создать еще один контейнер, в котором будет установлен curl
или другой инструмент для проверки. Этот "контейнер-контролер" может регулярно отправлять запросы к вашему приложению и проверять состояние. Это решение позволит вам обеспечить уровень абстракции и избежать установки дополнительных пакетов на основной контейнер.
Пример запуска такого контейнера:
version: '3'
services:
my_app:
image: my_app_image
healthcheck:
test: ["CMD", "pidof", "nginx"]
health_checker:
image: appropriate/curl
depends_on:
- my_app
entrypoint: ["sh", "-c", "while sleep 10; do curl -f http://my_app:9200/_cluster/health; done"]
Заключение
Выбор подхода к проверке состояния контейнера зависит от ваших требований и возможностей. Лучшая практика заключается в том, чтобы использовать доступные инструменты для мониторинга состояния приложения и, если необходимо, использовать внешние решения для обеспечения надежности и мониторинга. Убедитесь, что ваше решение соответствует архитектуре вашего приложения и эффективно в вашей рабочей среде.