Health-check — механизм автоматической проверки работоспособности сервиса: балансировщик нагрузки, оркестратор или внешняя система мониторинга периодически отправляет запрос на специальный эндпоинт и ожидает корректного ответа. Отказ проверки означает, что сервис нужно исключить из ротации или перезапустить.
Типы health-check проверок
- HTTP-проверка
- GET-запрос на эндпоинт (например, /healthz или /health). Ожидаемый ответ — HTTP 200. Самый распространённый тип для веб-сервисов.
- TCP-проверка
- Попытка установить TCP-соединение на порт. Если соединение открылось — сервис считается живым. Используется для не-HTTP сервисов: Redis, MySQL.
- Команда exec
- Выполнение команды внутри контейнера. Код возврата 0 — сервис здоров. Гибко, но медленнее HTTP/TCP.
Liveness vs Readiness в Kubernetes
В Kubernetes различают три вида проб:
- Liveness probe — «жив ли процесс?». При провале Kubernetes перезапускает контейнер. Защищает от дедлоков и бесконечных циклов.
- Readiness probe — «готов ли принимать трафик?». При провале Pod исключается из Service endpoints, но не перезапускается. Используется во время прогрева (warm-up) после деплоя.
- Startup probe — проверяется только при старте контейнера, пока приложение инициализируется. После успеха передаёт управление liveness пробе.
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
Health-check в nginx upstream
Nginx (в коммерческой версии nginx Plus или через модуль ngx_http_upstream_hc_module) поддерживает активные health-check для бэкендов:
upstream backend {
server backend1.example.com;
server backend2.example.com;
keepalive 32;
health_check interval=5s fails=3 passes=2 uri=/health;
}
В open-source nginx пассивные проверки работают автоматически: если бэкенд вернул ошибку N раз подряд — он временно исключается (параметры max_fails и fail_timeout в директиве server).
История
Health-check как концепция появился с первыми балансировщиками нагрузки в 1990-х: аппаратные балансировщики F5 BIG-IP периодически опрашивали бэкенды, исключая недоступные. С распространением микросервисов и Docker в 2013-2015 годах health-check стал обязательным атрибутом каждого сервиса. Kubernetes (2014) формализовал liveness/readiness как стандарт.
Health-check в практике DevOps
Эндпоинт /health должен проверять не только «жив ли процесс», но и зависимости: database connectivity, Redis ping, внешние API (но с осторожностью — внешний сервис мог быть недоступен). Глубокий health check: /health/deep проверяет все зависимости. Поверхностный: /health/live — только базовую жизнеспособность (для liveness probe). Разница важна: liveness failure убивает и перезапускает pod, readiness — только убирает из балансировщика.
HAProxy health checks: option httpchk GET /health HTTP/1.1 — балансировщик проверяет каждый бэкенд и убирает недоступные. fall 3 — помечать как DOWN после 3 неудач, rise 2 — возвращать в ротацию после 2 успехов. Консул (Consul) health checks — distributed health checking в service mesh. Timeout для health-check endpoint: должен быть меньше, чем periodSeconds × failureThreshold, иначе probe никогда не успеет до таймаута.
На что обращать внимание
Не используй один эндпоинт для liveness и readiness — это разные вещи. Liveness проверяет только базовую жизнеспособность процесса; readiness — готовность к трафику (например, выполнены ли миграции БД). Задержку initialDelaySeconds устанавливай с запасом: если приложение стартует 30 секунд, а проверка начинается через 10 — контейнер будет постоянно перезапускаться. Мониторинг состояния health-check эндпоинтов должен быть настроен как внешняя проверка: если упал сам балансировщик — внутренние проверки ничего не покажут.