Istio для Apache Airflow в Kubernetes: проблемы и решения

Автор Категория ,
Istio для Apache Airflow в Kubernetes: проблемы и решения

Запуск Apache Airflow с Kubernetes сегодня стал стандартом де-факто. Однако, при практическом развертывании Airflow с помощью исполнителя Kubernetes и оператора пода в кластере этой платформы оркестрации контейнерных приложений возникает множество препятствий и трудностей. Сегодня рассмотрим, как обойти их с помощью service-mesh проекта с открытым исходным кодом Istio, какие проблемы могут при этом возникнуть и как с ними справиться.

Что такое Istio и почему он не решает проблемы запуска Apache Airflow в кластере Kubernetes

Напомним, при развертывании Apache Airflow в кластере Kubernetes (K8s), исполнитель Kubernetes запускает каждый экземпляр задачи в своем собственном поде, создавая в DAG-цепочке для каждой задачи отдельный под. Образ пода является базовым образом Airflow, где будут запускаться задачи, Python- и Bash-операторы и пр. По сути, он запускает команду запуска задачи Airflow, используя базовый образ этого фреймворка внутри пода. Оператор пода Kubernetes также создает новый под в кластере Kubernetes, но образ определяется пользователем через аргументы в операторе. По сути, здесь выполняется вызов API Kubernetes для запуска пода и пользовательского образа, с записью полученного результата. Если таких вызовов происходит много, как это часто бывает в Big Data проектах, для управления ими нужен специальный уровень обработки всего сетевого трафика, т.к. вся микросервисная архитектура состоит из сотен или тысяч взаимодействующих сервисов. Автоматизировать обработку сетевого трафика помогают так называемые сервисные сетки (service mesh), к которым относится популярный open-source проект Istio. Разработанной инженерами Google, IBM и Lyft, Istio решает следующие проблемы микросервисной архитектуры:

  • управление трафиком, включая таймауты, повторные попытки, балансировка нагрузки;
  • обеспечение безопасности, в т.ч. аутентификация и авторизация конечного пользователя;
  • организация наблюдаемости – трассировка, мониторинг, логирование.

Istio перехватывает весь сетевой трафик и применяет к нему набор правил, вставляя в каждый под интеллектуальный прокси в виде sidecar-контейнера. Но это мешает нормальному рабочему процессу исполнителя Kubernetes и оператора пода Kubernetes, которые определяют статус задачи в DAG на основе фазы жизненного цикла пода (Pod Phase). Поэтому, когда эта фаза будет успешной или неудачной, Airflow считает задачу выполненной. А благодаря дополнению istio-proxy под всегда будет работать, при том, что сам контейнер задачи завершен. В результате фаза жизненного цикла пода станет Not Ready в успешной задаче и Error в невыполненной задаче. А в пользовательском интерфейсе Airflow будет отображаться, что задача всегда выполняется и никогда не заканчивается. Как обойти эту проблему, рассмотрим далее.

5 способов решения проблемы

Проще всего использовать тип жизненного цикла Kubernetes: Sidecar, установив тип жизненного цикла контейнера на sidecar, а Kubernetes сделает все остальное. Но это решение на самом деле не совсем реализовано в Kubernetes 1.18. Альтернативой может стать обертка команды в контейнере, чтобы сперва использовать конечную точку Istio для проверки запуска sidecar. Если sidecar запущен, далее запускается AirFlow. После завершения работы контейнера он использует конечную точку Istio quitquitquit для завершения работы istio-proxy. Эта функция доступна после Istio 1.7.

Но этот способ не решает всех проблем, поскольку не позволяет переопределить команду сгенерированного пода: исполнитель Kubernetes запускает команду запуска задачи Airflow, используя его базовый образ внутри пода. Чтобы добавить собственную обертку, нужно менять исходный код исполнителя Kubernetes. Это целесообразно лишь в некоторых заданиях, связанных с Airflow, или cron, таких как миграция базы данных. При использовании Helm-диаграмм для развертывания Airflow, следует внести изменения в конфигурационные YAML-файлы.

Компания Astronomer, которая активно продвигает и коммерциализирует Airflow, подобно тому, как Confluent работает с Kafka, а Databrics со Spark, для решения рассматриваемой проблемы создали совершенно новый класс Istio с конечной точкой API для отключения istio-proxy после завершения работы. Но решение Astronomer работает только с прокси-сервером Istio.

Можно развернуть Cron-задание, чтобы использовать API Kubernetes для проверки состояния модуля и уничтожения sidecar’ов, если задача завершена. Для этого нужно добавить небольшую проверку состояния контейнера, чтобы выполнить выхода для терминированных контейнеров и завершить их. Это решает проблему sidecar и предотвращает изменение кодовой базы Airflow Kubernetes Executor. Однако, Kubernetes Pod Operator может развернуть под в произвольном пространстве имен. Поэтому не рекомендуется использовать Cron-задание для уничтожения sidecar’ов в каждом пространстве имен, поскольку это может случайно уничтожить и другие полезные поды. Поэтому лучшим способом обойти проблему с запуском AirFlow в Kubernetes с помощью Istio будет реализация пользовательского оператора пода, что мы и рассмотрим далее.

Архитектура Istio, Kubernetes, микросервисы
Архитектура Istio

Пользовательский оператор пода K8s

Чтобы решить проблему с выключением пода, следует реализовать пользовательский оператор пода Kubernetes, который выключает под, когда базовый контейнер, где выполняется задача, завершен. Это включает в себя создание пользовательской панели запуска пода через изменение исходного кода оператора Kubernetes Pod, который создает под (метод get_or_create_pod()) и ждет его запуска (метод await_pod_start()). Затем он ожидает завершения пода с помощью метода await_pod_completion() менеджера подов. Это метод следует переопределить в пользовательском менеджере подов, чтобы считал под завершенным, когда базовый контейнер завершен. Для этого нужно добавить простую проверку. Если фаза жизненного цикла пода еще выполняется, поскольку вспомогательный прокси-сервер Istio все еще работает, но базовый контейнер завершен, его можно считать завершенным.

Если контейнер завершен, то container_status.state.terminated в полезной нагрузке ответа API Kubernetes будет иметь информацию о завершении в поле exit_code. Выход пода из строя рассматривается только в том случае, если базовый контейнер не был успешным. Таким образом, можно запустить Airflow, используя исполнитель и оператор пода Kubernetes с включенным Istio!

На практике можно столкнуться с проблемой сбоя создания пода, если имя пользовательской задачи AirFlow слишком длинное, т.к. фреймворк добавляет случайный суффикс после имени задачи, чтобы сформировать имя пода. Хотя Airflow автоматически обрабатывает длинное имя задачи и безопасно создает создание модуля, Istio добавит дополнительную метку service.istio.io/canonical-name, в которой используется имя пода. Часто длина этого имени метки превышает 63 символа, поэтому под не может создать его.

Чтобы обойти это ограничение, можно назначить рабочим процессам конкретную метку в app.kubernetes.io/name или в шаблоне пода. При использовании Helm-диаграмм для развертывания Airflow это можно установить в поле метки app.kubernetes.io/name: some_name. Для оператора пода Kubernetes нужно снова изменить клиента, добавив поле метки в под через kwargs в пользовательском методе оператора __init__. Далее все передается исходному конструктору.

Таким образом, пользовательский оператор, унаследованный от Kubernetes Pod Operator с cron-заданием для завершения побочных эффектов, можно успешно развернуть Airflow в кластере Kubernetes с поддержкой Istio. Теперь прокси-сервер Istio не будет мешать нормальному рабочему процессу исполнителя и оператора пода Kubernetes, а Airflow будет знать, что задача завершена. О том, как автоматизировать создание CLI-интерфейсов для AirFlow с библиотекой Python Fire вместо использования PythonOperator, читайте в нашей новой статье

Все подробности администрирования и эксплуатации Apache AirFlow для организации ETL/ELT-процессов в аналитике больших данных вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://betterprogramming.pub/running-airflow-using-kubernetes-executor-and-kubernetes-pod-operator-with-istio-d5aa7af16ef5
  2. https://habr.com/ru/company/flant/blog/438426/
  3. https://istio.io/latest/docs/