Mkdir700's Note

Mkdir700's Note

【入门Airflow】 使用Docker在本地快速搭建Airflow

2021-12-16

前言

本文主要参考官方文档编写。我将顺着官方文档的流程在本地安装Airflow ,并且附上安装过程的截图。

其实官方文档步骤写得都是比较详细,奈何这英语能力真的拉跨。

不过还是建议大家在使用过程中遇到的任何问题,优先去查看官方文档,有奇效。

官方文档:

https://airflow.apache.org/docs/apache-airflow/stable/start/docker.html

生产准备

这里Airflow官方建议我们不要使用当前这种“快速入门”的方式用在生产环境。本文的这种方式就供我们在本地学习使用。

如果要在用在生产环境,官方建议使用Kubernetes和Heml Chart部署

开始之前

你需要安装以下必要的工具:

  1. 安装 DockerCommunity Edition
  2. 安装Docker Compose (v1.29.1版本以上)

提示:

在MacOS上经常性会因为内存分配不够,导致无法运行Airflow。如果你没有分足够的内存,将会导致Ariflow WebServer不断的重启。你应该至少分配4G 的内存(推荐8G)。

我们可以运行下方命令,去检查是否有足够的内存:

docker run --rm "debian:buster-slim" bash -c 'numfmt --to iec $(echo $(($(getconf _PHYS_PAGES) * $(getconf PAGE_SIZE))))'

docker-compose.yaml

下载docker-compose.yaml文件

curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.2.2/docker-compose.yaml'

我们可以自己新建一个文件夹,然后将docker-compose.yaml 下载下来。

这个文件定义了以下服务:

  • airflow-scheduler
  • airflow-webserver
  • airflow-worker
  • airflow-init
  • flower
  • postgres
  • redis

所有的服务都允许我们使用CeleryExecutor,关于以上服务的具体解释,可以查看Airflow的架构设计

一些目录在容器中已被挂载,这意味着这些目录下的文件与我们的宿主机共享。

  • ./dags 我们可以将我们写的DAG文件放置到这里。
  • ./logs 存放来源于任务执行器与调度器的日志。
  • ./plugins 存放一些我们自定义的插件。

我们现在使用的镜像文件都是官方做好的,所以如果我们需要安装一些Python的第三方包,则需要自己构建镜像文件

初始化环境

在我们首次运行Airflow的时候,我们需要准备运行环境,例如:创建必要的文件、目录以及初始化数据库。

设置正确的Airflow用户

在Linux中,需要知道user id 以及设置group id0,否则在dags、 logs、 plugins中的文件将由root用户创建。

这里我们需要配置AIRFLOW_UID

mkdir -p ./dags ./logs ./plugins
echo -e "AIRFLOW_UID=$(id -u)" > .env

查看更多Docker Compose 环境变量

对于其他的操作系统,我们会得到“没有设置AIRFLOW_UID”的警告信息,这个我们可以忽略它。我们也可以在docker-compose.yaml同目录下手动创建.env 文件,写入以下内容:

AIRFLOW_UID=50000

初始化数据库

无论在什么操作系统上,我们都需要进行数据库迁移以及创建第一个用户。我们可以运行以下命令:

docker-compose up airflow-init

完成之后,会得到类似以下结果:

airflow-init_1       | Upgrades done
airflow-init_1       | Admin user airflow created
airflow-init_1       | 2.2.2
start_airflow-init_1 exited with code 0

我们第一个用户的用户名和密码都是 airflow

运行Airflow

现在,我们可以通过以下命令运行所有服务:

docker-compose up

等待一会儿后,我们可以在终端查看这些容器的状况,确保这些容器都是healthy状态。

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS                    PORTS                              NAMES
247ebe6cf87a   apache/airflow:2.2.2   "/usr/bin/dumb-init …"   3 minutes ago    Up 3 minutes (healthy)    8080/tcp                           compose_airflow-worker_1
ed9b09fc84b1   apache/airflow:2.2.2   "/usr/bin/dumb-init …"   3 minutes ago    Up 3 minutes (healthy)    8080/tcp                           compose_airflow-scheduler_1
65ac1da2c219   apache/airflow:2.2.2   "/usr/bin/dumb-init …"   3 minutes ago    Up 3 minutes (healthy)    0.0.0.0:5555->5555/tcp, 8080/tcp   compose_flower_1
7cb1fb603a98   apache/airflow:2.2.2   "/usr/bin/dumb-init …"   3 minutes ago    Up 3 minutes (healthy)    0.0.0.0:8080->8080/tcp             compose_airflow-webserver_1
74f3bbe506eb   postgres:13            "docker-entrypoint.s…"   18 minutes ago   Up 17 minutes (healthy)   5432/tcp                           compose_postgres_1
0bd6576d23cb   redis:latest           "docker-entrypoint.s…"   10 hours ago     Up 17 minutes (healthy)   0.0.0.0:6379->6379/tcp             compose_redis_1

访问Airflow

在运行后,我们可以通过以下三种方式访问Airflow:

CLI命令

我们也可以CLI commands,需要每次都指定具体哪个服务运行命令。例如我们插件airflow worker的信息,则运行以下命令:

docker-compose run airflow-worker airflow info

如果运行平台是Linux 或者 MacOS,则可以下载下方的sh脚本:

curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.2.2/airflow.sh'
chmod +x airflow.sh

现在可以更方便的快速运行cli命令。

./airflow.sh info

我们也可以使用bash作为参数进入容器中的终端交互界面或者使用python 容器中的python解释器。

./airflow.sh bash

./airflow.sh python

Web端

这里,我们可以访问http://localhost:8080,查看Web界面

默认用户名和密码都是airflow

REST API

Airflow支持API方式的调用,这意味我们可以使用更多工具去管理Airflow。在请求API时,需要使用用户名和密码验证。

简单的例子:

ENDPOINT_URL="http://localhost:8080/"
curl -X GET  \
    --user "airflow:airflow" \
    "${ENDPOINT_URL}/api/v1/pools"

清理

停止和删除容器,删除数据卷和已下载的容器则运行:

docker-compose down --volumes --rmi all

FAQ:常见问题

ModuleNotFoundError: No module named 'XYZ'

Docker Compose 使用的Airflow最新的官方镜像(apache/airflow)。如果我们需要安装新的Python包或者系统依赖,我们可以自定义及扩展镜像

这个我在后续会写篇文章,总结总结如何安装依赖和自定义镜像。