Healthcheck для Apache Airflow в Kubernetes кластере
Aug 26, 2021 11:07 · 350 words · 2 minute read
В одной из предыдущих статей мы довольно подробно рассматривали процесс развертывания Apache Airflow в Kubernetes кластере, особенностью которого был запуск веб-сервера и планировщика в одном docker-контейнере. В такой реализации довольно скоро я столкнулся с необходимостью использования кастомного хелсчека для проверки работоспособности сервиса - давайте разберемся!
Прежде всего стоит признать, что текущая реализация отличается от рекомендуемого шаблона проектирования приложений в Docker-контейнерах, который гласит, что следует использовать один процесс на один контейнер. В нашем Docker-контейнере (если не менять инструкцию CMD
) запускаются планировщик (scheduler), воркер (worker) и непосредственно веб-сервер (webserver) - как и описано в entrypoint-скрипте.
В манифесте для запуска Apache Airflow в Kubernetes кластере указаны такие настройки для проверки liveness/readiness:
...
livenessProbe:
failureThreshold: 5
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 5
...
и kubelet честно использует эти настройки чтобы определить когда контейнер должен быть перезапущен (liveness) и когда контейнер готов принимать входящий траффик (readiness). Беда лишь в том, что таким образом проверяется работоспособность веб-сервера, а не всей системы в целом - бывают случаи когда процесс планировщика “зависает” и задачи перестают запускаться.
Примечание. Иногда об этом можно узнать из UI, когда на домашней странице появляется сообщение:
The scheduler does not appear to be running. Last heartbeat was received 1 day ago.
The DAGs list may not update, and new tasks will not be scheduled.
Решить эту задачу можно довольно просто и элегантно. Дело в том, что по пути /health
Airflow также отображает статусы зависимых сервисов, в том числе и планировщика. Выглядит это примерно так:
{
"metadatabase": {
"status": "healthy"
},
"scheduler": {
"status": "healthy",
"latest_scheduler_heartbeat": "2021-08-26T10:39:08.143949+00:00"
}
}
Получать данную информацию будем с помощью утилиты curl
, а обрабатывать утилитой jq
(ее нужно будет установить при сборке Docker-образа).
Создадим простейший bash-скрипт следующего содержания:
Здесь мы получаем json c эндпоинта /health
, сравниваем значение ключа .scheduler.status
и возвращаем код завершения (exit status). Код завершения будет равен 0, если выражение .scheduler.status == "healthy"
истинно.
Нам придется несколько видоизменить наш Dockerfile:
и подправить yaml-манифест для деплоя Airflow в Kubernetes кластере:
Теперь kubelet будет учитывать в своих проверках состояние планировщика и перезапускать его при необходимости.
- Интеграция Apache Airflow и Slack для отправки уведомлений
- Apache Airflow: запуск Kubernetes Pod Operator через API
- Безопасная работа с секретами при сборке docker-образов
- Валидация миграций flyway c помощью testcontainers
- Использование PostStart хука при запуске пода в Kubernetes-кластере