Развертывание Apache Airflow в Kubernetes кластере

Jan 28, 2020 07:41 · 556 words · 3 minute read airflow docker kubernetes

В данной статье разберемся с особенностями установки, настройки и эксплуатации Apache Airflow (далее Airflow) в кластере Kubernetes. Давайте разберемся!

Airflow - это инструмент для разработки, планирования и мониторинга batch-процессов обработки данных. Как минимум на Airflow стоит обратить внимание при выборе планировщика для ваших ETL/ELT-процессов.

Существует несколько сценариев использования связки Airflow и Kubernetes:

  • запуск самого Airflow в Kubernetes кластере
  • использование Airflow для запуска задач (jobs) в Kubernetes кластере
  • оба предыдущих варианта одновременно

Рассмотрим эти сценарии по порядку. Airflow состоит из отдельных компонентов, основные из которых планировщик (scheduler), вебсервер (webserver) и воркеры (workers). В зависимости от конкретного случая, требованиям к отказоустойчивости и количества одновременно выполняющихся задач, эти компоненты можно запускать по отдельности или все вместе.

Прежде всего, для запуска Airflow в Kubernetes кластере нам понадобится docker-образ и yaml-манифесты (или Helm чарты).

Примечание. Существует также вариант запуска с использованием Airflow Kubernetes Operator от Google, но на момент написания статьи он находится в alpha-версии и мной не тестировался.

Зачастую для запуска Airflow используют docker-образ puckel/docker-airflow. Это надежный образ, который собирается автоматически и содержит entrypoint скрипт, позволяющий docker-контейнеру работать в роли планировщика/вебсервера/воркера и т. д. Однако, версии образа несколько отстают от релизных версий Airflow, поэтому есть смысл создать docker-образ для production окружения и обновлять его самостоятельно (наш вариант).

Также можно использовать docker-образ astronomerinc/ap-airflow от astronomer.io, но так как мне не удалось найти исходный Dockerfile, то я воздержался от этого решения.

В нашем случае Dockerfile выглядит следующим образом:

Также видоизменился Entrypoint скрипт:

Для деплоя в Kubernetes кластер можно воспользоваться одним из нескольких Helm чартов:

или самостоятельно написанным манифестом (наш случай).

Основным понятием в Airflow является Directed Acyclic Graph (далее DAG) - смысловое объединение одной нескольких задач, которые вследует выполнять в строго определенной последовательности по определенному расписанию.

При написании DAG’а разработчик определяет набор операторов, на которых будут построены задачи внутри DAG’а. Airflow Operator - это еще к одна важная сущность, на основании которой создаются экземпляры заданий, где описывается, что именно будет происходить во время выполнения экземпляра задания. Существует огромное множество как официальных так и созданных сообществом Airflow операторов, кроме того, ориентируясь на свои потребности/способности можно создавать свои операторы.

Существует несколько способов “доставки” написанных DAG’ов в инстанс Airflow, развернутый в Kubernetes кластере:

  • добавление в docker-образ при сборке
  • использование Persistent Volume (PV)
  • git-sync

Первый вариант предполагает добавление DAG’ов в docker-образ в момент сборки, и в большинстве случаев является неприемлимым - пересобирать образы при каждом малейшем изменения DAG’а не самая лучшая идея.

При втором варианте - DAG-файлы хранятся на некотором внешнем томе и монтируются в соответствующие поды (scheduler, webserver, worker) при запуске. Для корректной работы PV с несколькими подами, режим доступа (accessMode) тома должен быть ‘ReadOnlyMany’ или, на худой конец, ‘ReadWriteMany’.

Третий, оптимальный вариант, предполагает использование еще одного сайдкар (sidecar) контейнера git-sync а поде (Pod) для периодической синхронизации DAG-файлов с указанного git-репозитория без рестарта самого Airflow.

С учетом git-sync и RBAC, в нашем случае Kubernetes манифест будет выглядеть так:

Для теста создадим задачу, которая с помощью KubernetesPodOperator запускает в Kubernetes кластере под (Pod) и выполняет внутри него команду

java --version

Тестовый пример DAG’а выглядит так:

Примечание. Согласно документации, для описания KubernetesPodOperator минимально необходимы только четыре поля (name, namespace, image, task_id) но, в нашем случае, при использовании Airflow версии 1.10.7 пришлось также в обязательном порядке добавить in_cluster=True и do_xcom_push=False.

Весь список доступных параметров и их возможных значений находится здесь, а все рассмотренные в статье файлы можно найти в репозитории ealebed/airflow.

tweet Share