Deployando airflow en kubernetes con helm, usando un clúster eks en amazon e imágenes de airflow personalizadas
1. Acerca de
El objetivo de este documento es mostrar las secciones clave que hay que modificar para tener un deploy productivo mínimo para airflow.
2. Prerrequisitos
- Tener un clúster eks funcionando en amazon. Si no lo tienes puedes consultar la guía ¿Cómo crear la infraesturctura para un clúster eks? [TBW]
- El clúster eks debe estar configurado con TLS termination con nginx.
- Los nodos del clúster tienen por default asignados el rol para acceder al repositorio ecr.
- Contar con un repositorio ECR donde tus imágenes se darán de alta.
- Tener instaladas y configuradas las herramientas docker, kubectl y helm
3. Obteniendo los charts fuente
Airflow liberó hace tiempo los charts oficiales para el deployment de airflow. De acuerdo a la documentación oficial tendremos que añadir el repositorio y posteriormente descargar los archivos fuete con helm pull.
helm repo add apache-airflow https://airflow.apache.org helm pull apache-airflow/airflow
Haciendo lo anterior ya tendremos los yamls fuente comprimidos en un archivo tar llamado airflow-{version-de-chart}.tgz
Los descomprimimos usando el comando tar
tar xvf airlow-1.5.0.tgz
Y ahora sí tendremos las plantillas yaml para modificarlas e implementarlas con helm.
A partir de ahora, este tutorial está realizado tomando como base las plantillas para airflow en la versión 1.5.0
4. Modificando los charts para hacer un deploy personalizado
A menos que tu deployment sea muy complejo, el único lugar donde haremos las modificaciones será el archivo values.yaml.
4.1. Configurando la imagen de airflow
Airflow realiza varias actividades antes de estar listo como correr migraciones y en algunas ocasiones tu imagen personalizada de airflow puede entrar en conflico con estas tareas. Así que a pesar de que puedes configurar una imagen para todo el deployment, modificando la variable defaultAirflowRepository, te recomiendo que únicamente modifiques la imagen de airflow para la imagen base y actives configures useDefaultImageForMigration. Esto permitirá usar la imagen base de airflow para correr las migraciones y no la tuya, librandote de errores en esta fase del deployment
Tu archivo se verá más o menos así:
images:
airflow:
repository: algún-repositorio-ecr.dkr.ecr.us-east-2.amazonaws.com/airflow
tag: algun-tag-personalizado
pullPolicy: IfNotPresent
# To avoid images with user code, you can turn this to 'true' and
# all the 'run-airflow-migrations' and 'wait-for-airflow-migrations' containers/jobs
# will use the images from 'defaultAirflowRepository:defaultAirflowTag' values
# to run and wait for DB migrations .
useDefaultImageForMigration: true
4.2. Configurando el ingress
Otra cosa que querrás hacer es habilitar el ingress, esto lo haces configurando el valor true, en la sección correspondiente.
También puedes configurar la subsección de host configurando tu dominio.
# Ingress configuration
ingress:
# Enable ingress resource
enabled: true
...
web:
...
host: "airflow.algundominio.com/"
En tus entradas de dns deberás crear un registro de tipo CNAME apuntando al ingress que se genere con este deployment. Después de aplicar el deployment puedes ejecutar el comando kubectl get ingress –namespace airflow para obtener el detalle.
4.3. Configuración para DAGs
La implementación estándar de ariflow es vinculada a un repositorio. Al momento de hacer el deployment se hará un clone de una rama específica al repositorio configurado.
Habilitaremos esta opción en la sección de dags. En mi caso, configuraré el acceso al repositorio ssh y los dags se encuentran en la raís del repositorio, así que mi yaml se ve algo así.
# Git sync
dags:
...
gitSync:
enabled: true
# git repo clone url
repo: https://miempresa.com/repos/dags.git
branch: main
rev: HEAD
depth: 1
...
subPath: ""
...
sshKeySecret: airflow-ssh-secret
La variable sshKeySecret indica el nombre del secreto en el cual se guarda la llave ssh. Tenemos que crear ese secreto en el cluster. Como los charts son justo para definir todo lo necesario para nuestro deployment, podemos crear un archivo yaml en airflow/templates/secrets/aifrlow-ssh-secret.yaml. El archivo se verá más o menos así:
apiVersion: v1 kind: Secret metadata: name: airflow-ssh-secret data: gitSshKey: "cadena-de-llave-reemplazando-interlineado-por-\n"
4.4. Configuración para logging en S3
En esta versión de charts, los logs para S3 se configuran mediante variables de entorno, para ello existe una sección en el archivo de values,
# Environment variables for all airflow containers
env:
# - name: ""
# value: ""
- name: "AIRFLOW__CORE__REMOTE_LOGGING"
value: "True"
- name: "AIRFLOW__CORE__REMOTE_BASE_LOG_FOLDER"
value: "s3://alguna-bucket-para-airflow-logs"
- name: "AIRFLOW__CORE__REMOTE_LOG_CONN_ID"
value: "aws_s3"
El valor de la variable AIRFLOW_CORE_REMOTELOGCONNID debe corresponder con una conexión dada de alta en la consola de airflow; en este ejemplo tendría que existir una conexión con el id awss3
4.5. Configurar Fernet key
4.6. Configurar Postgres
En el chart por default, la base de datos que con la que funciona airflow está dentro de un contenedor, el dejarlo así no está recomendado para producción, así que deshabilitaremos esta opción, modificando esta sección
# Configuration for postgresql subchart # Not recommended for production postgresql: enabled: false ...
Para configurar la nueva base de datos tenemos dos opciones, configurar la conexión en directamente en el archivo values.yaml o bien crear un secret de kubernetes para guardar estos valores. Vamos a optar por crear un secreto con los valores de la conexión
kubectl create secret generic database-secret --from-literal=connection=postgresql://user:pass@host:5432/db --namespace airflow
Una vez creado, podremos configurar el valor del secret de esta manera en values.yaml
# Airflow database & redis config data: # If secret names are provided, use those secrets metadataSecretName: database-secret resultBackendSecretName: ~ brokerUrlSecretName: ~
5. Aplicar deployment
Una vez configuradas todos los valores para el deplyment podrás realizarlo de la siguiente manera:
helm upgrade --install airflow ./airflow --namespace airflow --create-namespace