Introducción a la dockerización y personalización de Apache Airflow 

Introducción

En el mundo de la ingeniería de datos, la organización y estructuración eficiente de los flujos de procesos adquiere un papel crucial. En este punto, Apache Airflow se ha posicionado como una de las herramientas más eficientes para lograr este cometido. Sin embargo, para maximizar todo su potencial es recomendable realizar un proceso de dockerización que permita su encapsulación, logrando una ventaja significativa.

En este artículo aprenderás cómo dockerizar Apache Airflow y como configurarlo en función de las necesidades de tu proyecto.

¿Qué son y qué características tienen Docker y Apache Airflow?

Docker es una plataforma que permite la encapsulación de aplicaciones junto a sus dependencias en entornos aislados llamados contenedores. Cada contenedor se ejecuta de manera independiente, pero compartiendo todos ellos el kernel del sistema operativo de la máquina que los aloja. Como te puedes imaginar, esto es un concepto muy poderoso, ya que esta arquitectura basada en contenedores permite minimizar el consumo de recursos del sistema a la vez que posibilita la autonomía de las dependencias en cada uno de los proyectos.

Por otro lado, Apache Airflow es una plataforma de orquestación de flujos de trabajo que permite la automatización, programación y monitorización de procesos complejos. Esto lo consigue mediante una estructura basada en DAGs (de sus siglas en inglés Directed Acyclic Graphs) en los que se puede definir de manera declarativa y sencilla flujos de trabajos complejos. Además, estos flujos de trabajo se pueden visualizar mediante una interfaz gráfica, simplificando su monitorización y permitiendo identificar los problemas que vayan surgiendo durante la ejecución de manera rápida e intuitiva.

¿Qué ventajas tiene dockerizar Apache Airflow?

Existen infinidad de razones por las que es muy recomendable usar Docker para implementar y gestionar Apache Airflow, y entre las más importantes destacan las siguientes:

Portabilidad
Docker se puede ejecutar en cualquier entorno que tenga docker instalado. Es decir, se puede ejecutar sin importar el sistema operativo que haya en el equipo. Esto, a pesar de que pueda parecer irrelevante, cobra especial importancia si se pretende ejecutar Apache Airflow en diferentes máquinas, ya que permite abstraerse del sistema subyacente y garantizar su ejecución estableciendo, además, una independencia entre diferentes entornos como puede ser, por ejemplo, producción y desarrollo.

Aislamiento y Consistencia
Docker además proporciona aislamiento, esto significa que se pueden encapsular todas las dependencias de Apache Airflow o de cualquier otra aplicación, incluyendo bibliotecas, herramientas y configuraciones específicas. Esto evita que haya conflictos entre dependencias y asegura la coherencia en los diferentes entornos.

Distribución y despliegue rápido y reproducible
Distribuir una imagen de docker es sorprendentemente fácil, ya que basta con empaquetar los componentes y dependencias de la aplicación en una imagen, para posteriormente, almacenarla en un registro privado o subirla a Docker Hub, entre otras opciones. Por lo tanto, bastará con empaquetar Apache Airflow con la configuración deseada en una imagen personalizada y compartirla para que pueda ser desplegada en cualquier sistema.

Escalabilidad
También destaca la escalabilidad que permite Docker. El uso de orquestadores que gestionen Apache Airflow y balanceen la carga del contenedor, permite que éste se pueda adaptar a la demanda de trabajo, haciendo posible una escalabilidad horizontal que garantice un rendimiento óptimo.

Como se puede observar, hay una gran variedad de motivos, y otros muchos que no se han nombrado, por los que es recomendable usar Docker para encapsular Apache Airflow o cualquier otra aplicación. Siendo además, como explicaré a continuación, un proceso relativamente sencillo que no requiere una gran dedicación de tiempo.

¿Cómo se realiza la dockerización de Apache Airflow?

Este proceso es increíblemente sencillo, ya que Airflow ya viene con una configuración predeterminada y podemos descargar el fichero docker-compose.yaml directamente de su página web.

Dicho esto, el primer paso, si vamos a usar Docker y docker compose, es instalar ambos en nuestro sistema. El proceso puede variar dependiendo del sistema operativo en el que te encuentres, sin embargo todos los pasos se encuentran detallados en la documentación oficial tanto de docker como de docker compose.

Una vez instalado, crearemos una carpeta para albergar todos los archivos y poder descargar en ella el docker compose que contiene la imagen oficial de Airflow:

Comandos: 

  • mkdir DockerAirflow
  • cd DockerAirflow
  • curl -LfO 'https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml'

Esto nos descargará un fichero llamado docker-compose.yaml que contendrá toda la configuración necesaria para desplegar Airflow. Este fichero se podrá modificar y adaptar a las diferentes necesidades de cada proyecto, pero eso lo veremos más adelante.

Este fichero nos creará 4 volúmenes (dags, logs, config y plugins) que servirán para sincronizar el contenedor con la máquina local. 

Es decir, todo lo que se incluya en estas carpetas estará automáticamente sincronizado con el contenedor y será en la carpeta dags donde tendremos que guardar los dags que queremos que nuestro Airflow dockerizado reconozca. Por esa razón, una vez tengamos el fichero docker-compose.yaml en nuestra ruta, el siguiente paso será crear estas carpetas en nuestra máquina.

Comandos: 

  • mkdir -p ./dags ./plugins ./logs ./config

Por último, deberemos configurar unas variables de entorno en un fichero `.env` para asegurarnos de que los permisos de usuario en el host y en los contenedores sean los mismos.

Comandos: 

  • echo -e "AIRFLOW_UID=$(id -u)\nAIRFLOW_GID=0" > .env

Y con esto ya tendríamos todo lo necesario para inicializar Apache Airflow con docker compose, con lo que ya solo nos quedaría levantar el contenedor y acceder al localhost en el puerto especificado (por defecto 8080).

Comandos: 

  • Levantar Airflow: docker compose up -d
  • Detener Airflow: docker compose down

Modificaciones y configuración recomendadas

Como he comentado anteriormente, el fichero docker-compose.yaml que nos hemos descargado se puede modificar para adaptarlo a las necesidades de cada proyecto. Para ello, solo tendremos que acceder a él mediante un editor de texto y modificar lo que consideremos oportuno.

A la hora de modificarlo, es necesario tener en cuenta que hay ciertos aspectos que son relativamente importantes de conocer para poder sacarle todo el provecho a Airflow, como puede ser cambiar el usuario y contraseña con los que queremos acceder, los puertos expuestos de la UI o del servicio de Flower (una herramienta de monitoreo y administración para célery).

Sin embargo, la capacidad que nos ofrece Airflow para poder configurar sus servicios no se quedan solo ahí, sino que mediante el fichero de airflow.cfg podemos acceder a una variedad de opciones que nos permitirán personalizar aún más cómo se comportará Airflow una vez desplegado.

Este fichero, que se encuentra en la ruta raíz de nuestro contenedor, es la piedra angular de la configuración de Airflow, ya que, desde él, podremos ajustar diversas opciones que afectan tanto al rendimiento como a la funcionalidad o a la seguridad del sistema.

Para poder acceder al fichero una vez desplegado el contenedor, podremos usar el siguiente comando:

  • docker exec -it <nombre_contenedor> bash

Una vez en el contenedor, podremos editar el fichero con el editor que prefieras.

En cuanto al fichero, algunos de los cambios más relevantes que se pueden realizar son los siguientes:

Dags_folder | plugins_folder | base_log_folder: Estas serán las rutas en las que se guardarán los dags, plugins y logs respectivamente en nuestro contenedor, por lo que es importante que apunten hacia el volumen que hemos creado anteriormente. Por defecto, ya vienen hacia las rutas base, pero si cambiamos la configuración del fichero docker-compose.yaml, se deberá de cambiar las ubicaciones también en este fichero y viceversa.

Default_timezone: Mediante este parámetro se puede configurar la zona horaria predeterminada de Airflow. Esta zona horaria será la que use a la hora de programar y ejecutar las diferentes tareas. La configuración básica de este parámetro es UTC, pero una posible alternativa si quieres que se ejecute en horario español sería configurarlo con “Europe/Madrid”.

Parallelism y max_active_run_per_dag: Estos parámetros aunque son independientes, están bastante relacionados entre sí, ya que la configuración de uno podría afectar al otro y una configuración subóptima de estos parámetros podría hacer que no se utilicen todos los recursos disponibles.

Por un lado, parallelism afecta directamente al rendimiento y la utilización de recursos del sistema, ya que se usa para controlar la cantidad máxima de tareas que pueden ejecutarse simultáneamente en Airflow. Como es lógico, a más número de tareas en paralelo, mayores deberán de ser los recursos disponibles, por lo que es importante realizar este ajuste con precaución, ya que si se restringe demasiado se puede llegar a sobrecargar el sistema o, si por el contrario, se sobredimensiona, se dejarían recursos infrautilizados.

Por otro lado, el parámetro max_active_run_per_dag controla la cantidad máxima de ejecuciones activas que pueden realizarse simultáneamente en un DAG específico. Es decir, mientras que el parámetro de parallelism afectaba a nivel de todo Airflow, este parámetro afecta individualmente a cada DAG, ya que limita la cantidad de instancias de ese DAG que pueden ejecutarse al mismo tiempo.

Por poner un ejemplo, Airflow viene configurado por defecto con parallelism = 32 y max_active_runs_per_dag = 16. Con esta configuración, significa que solo podremos tener dos dags ejecutándose a máxima capacidad a la vez, dado que la ejecución de un tercer dag haría que se sobrepasaran las 32 tareas simultáneas configuradas en parallelism.

Loggin_level y simple_log_format: Estos parámetros también están muy relacionados entre sí. Por un lado, como su propio nombre indica, loggin_level establece el nivel de detalle con el que queremos que se registren los logs que se vayan generando Airflow. Por defecto viene configurado en “INFO”, lo que nos registraría los mensajes informativos y de los niveles superiores, pero acepta también los niveles “CRITICAL”, “ERROR”, “WARNING” y “DEBUG” , siendo debug el menos restrictivo, ya que registraría todos los logs y el de critical el más restrictivo ya que sólo registraría los logs que fueran críticos para el sistema.

Por otro lado, simple_log_format define el formato en el que se registran los logs cuando el nivel de registro sea igual o superior a “INFO”. Por defecto viene configurado como “%(asctime)s [%(levelname)s] – %(message)s”. Esto incluirá una marca de tiempo (‘asctime’), el nivel de registro (‘levelname’) y el propio mensaje (‘message’). Sin embargo, se puede configurar para que se registren con un formato personalizado en función de las necesidades de cada proyecto o desarrollador.

Job_heartbeat_sec: Este parámetro sirve para que Airflow determine si un trabajo que se está ejecutando ha fallado o se está ejecutando correctamente. Es decir, establece el número de segundos que deberán de transcurrir desde la última recepción de que se está ejecutando correctamente para que Airflow interprete que el trabajo ha fallado. Por defecto viene configurado en 5 segundos, lo que significa que se esperará una señal de que todo se está ejecutando como debería al menos una vez cada 5 segundos y si el trabajador no envía esa señal en ese tiempo, Airflow considerará que el trabajo ha fallado.

Por lo tanto, cuanto mayor sea el número de segundos especificado en este campo, se establecerá una restricción menor, mientras que si se marcara de una manera mucho más restrictiva, como por ejemplo 1 segundo, significa que cada segundo deberá de recibir una señal de que todo está correcto o si no marcará la tarea como fallida.

Por último, hay una serie de parámetros que se pueden ajustar en este fichero airflow.cfg que están más relacionados con la UI de Airflow que con su rendimiento, pero aún así puede ser interesante configurarlos de manera personalizada para tener una experiencia más ajustada a nuestros gustos. En este punto destacan los siguientes parámetros:

Config_file: Este parámetro nos permite establecer el path donde se ubicará el fichero webserver_config.py, con el que podremos configurar los parámetros de webserver, así como establecer diferentes Themes ya configurados que permiten modificar la manera en la que se muestra la UI de Airflow.

Dag_default_view: Permite establecer cuál es la vista que queremos que tengan por defecto los dags en la UI. De forma predeterminada viene con la configuración de “grid”, sin embargo, permite estas otras opciones: “graph”, “duration”, “grantt”, “landing_times”.

Dag_orientation: Por último, y a pesar de que hay muchos más parámetros que permiten personalizar aún más en profundidad Airflow, voy a comentar este parámetro que permite establecer la vista por defecto de los gráficos que se muestran de los DAGs en la UI. Por defecto viene configurado como “LR” que significa Left to Right, es decir, que se visualiza de izquierda a derecha. Sin embargo, también permite “TB” (Top to Bottom), “RL” (Right to Left) y “BT” (Bottom to Top).

Conclusión

Como se ha podido comprobar en este post, existen muchas razones por las que dockerizar Apache Airflow no solo es una buena práctica, sino que además es un proceso sencillo, cómodo y fácilmente configurable. Y si bien es cierto que se puede usar Apache Airflow sin dockerizar, las ventajas asociadas a este proceso son numerosas en comparación con el esfuerzo extra que conlleva su configuración.

También hemos explorado detalladamente cómo configurar Apache Airflow, tanto la implementación en entornos Docker, como la personalización directa en su propia configuración nativa, permitiéndonos no solo tener un control preciso de cómo se ejecutan todas las tareas y de cómo se estructuran los recursos del sistema, sino también poder personalizar y adaptar la interfaz de usuario para que se ajuste a nuestro estilo y necesidades.

¡Esto es todo! Si este artículo te ha parecido interesante, te animamos a visitar la categoría Software para ver todos los posts relacionados y a compartirlo en redes. ¡Hasta pronto!
Luís Galdeano
Luís Galdeano
Artículos: 2