在本系列第一篇博客Airflow Architecture中,简述了,Airflow的设计架构,Airflow在部署的时候跟设计架构也是一一对应的,Scheduler进程,WebServer进程和Worker进程需要单独启动。Scheduler和WebServer可以跑在一个操作系统内,也可以分开,而通常Worker需要很多,如果是部署特定的数量的Worker,那就需要特定数量的机器才行;
Airflow On Kubernetes的方案,就可以克服这个缺点,Scheduler和WebServer长期运行,Worker只在有需要任务调度的时候跑起来,如果没有任务要执行,那这个Airflow集群将只有Scheduler和WebServer进程;
Airflow 源码airflow/scripts/ci/kubernetes/kube/文件夹下,列出了Airflow on Kubernetes所需要的配置文件;如果你本地运行的是minikube这样的集群,执行deploy.sh文件,就可以测试了,基本上不会出问题,
IMAGE=registry.cn-zhangjiakou.aliyuncs.com/airflow/airflow
TAG=latest
sudo sh deploy.sh
如果是正式的Kubernetes集群,则需要挨个文件分析一下,
设计Volume
Airflow需要持久化到磁盘的文件一共分为两部分,日志和dags文件;airflow worker pod启动的时候,会挂载一个存储日志的volume,如果dags不使用git clone到本地的话,还需要挂在存储dags的volume,需要注意的是,这两个volume会被Scheduler和WebServer所在的pod和所有的Worker Pod挂在,所以这两个Volume的PV和PVC都需要支持ReadWriteMany;
找一个这样的持久化存储方案并不容易,以阿里云为例,阿里云支持三种扩展Kubernetes外部存储的方式,云盘,NAS和OSS,现阶段
- 云盘稳定,但是只支持ReadWriteOnce
- OSS在ReadWriteOnce模式下很稳定,在ReadWriteMany模式下,第一个挂载的很容易成功,第二个挂载的就一直挂不上;有人提了issue,现在找不到了,找到补上链接;
- NAS的使用门槛相对其他两个有点高,在K8s集群的配置也不如云盘和OSS简单,需要配置VPC,虚拟交换机,需要创建挂载点,但是能用且稳定,阿里云上的集群的话,就可以看看NAS的文档,使用这种方法了;
此外还可以自己在Kubernetes集群内搭建NFS服务器,Kubernetes内置了对NFS的支持,自己搭建NFS服务器,就可以使用稳定的云盘作为存储,将只支持ReadWriteOnce的云盘转为支持ReadWriteMany的存储;
我使用的是阿里云的NAS,排出了云盘,测试了OSS不行之后,毫不犹豫选择了NAS,原因是在这之前我就会用;
Airflow提供的样例中的volumes.yaml文件中定义了三个volume,dags/logs,还有一个test-volume,是用来做测试的,这个我们在前面打包 Docker 镜像的时候已经去掉了最后一行测试当前环境的volume的代码,所以这个可以去掉,我们只需要为airflow准备dags和logs这两个volume就可以了;
除此以外,我们还需要部署一个数据库,数据库的数据文件也是需要持久化的,所以还需要为数据库创建一个volume,这个volume只需要ReadWriteOnce即可。如果使用已有的数据库,这一步就可以省略了;
数据库
官方样例提供的是Postgres数据库的Deployment文件,修改其中的volume为上一步创建的volume配置,即可,如果使用已有数据库,这一步可以省略;
airflow-configmap
airflow.cfg是主要是Scheduler和Worker的配置文件,将其存储早Kubernetes Configmap中,可以方便长时运行的Scheduler所在的pod挂在,也方便短时存在的Worker Pod的挂载,在airflow.cfg的Kubernetes Section有airflow_configmap = airflow-configmap配置,就是配置的Kubernetes集群中用于存储airflow.cfg的ConfigMap的。
Scheduler & WebServer
去掉test_volume相关的内容即可,如果使用了git-sync镜像,这个直接拉不下来,换成能拉取到的地址即可;
KubernetesExecutor & KubernetesOperator
Airflow提供了两种方式运行作业;KubernetesExecutor 和 KubernetesOperator;
Kubernetes Executor和Kubernete Operator是分开用的,是两种不同的方案。
Kubernetes Executor的原理是配置文件中定义好任务,并指明任务运行使用KuberneteExecutor,在配置KubernetesExecutor的时候指定镜像、tag、将要跟k8s集群申请的资源等,接下来,在指定的容器里面直接运行任务,比如下面的例子中,会创建四个镜像AIRFLOW__CORE__EXECUTOR=LocalExecutor,所有的容器都会挂在airflow-logs目录,用于回写任务执行日志,然后调用类似如下的命令,在容器内执行对应的Operator;
airflow
run
example_kubernetes_executor
three_task
2019-04-16T01:36:05.221216+00:00
--local
-sd
/root/airflow/dags/repo/airflow/contrib/example_dags/example_kubernetes_executor.py
KubernetesOperator的原理是使用Airflow镜像床架一个容器,该容器AIRFLOW__CORE__EXECUTOR: LocalExecutor,挂在了airflow_logs pvc,使用如下的命令执行
airflow
run
example_kubernetes_operator
task
2019-04-16T01:23:56.996640+00:00
--local
-sd
/root/airflow/dags/repo/airflow/contrib/example_dags/example_kubernetes_operator.py
此时的task是一个KuberneteOperator,这个Operator的任务就是运行一个执行的镜像,能力跟docker run,或者说kubectl run的能力是一样的;
官方文档中提供了明确的说明和样例,大家可以查看分析。