本文记录了笔者最近基于Helm在K8S上部署airflow2.5.1版本遇到的一系列问题及最终的一键部署脚本,欢迎关注算法小生免费阅读
由于之前在airflow的使用上是单worker节点,为了支持多worker节点以及简化部署流程,特此新增了airflow-plus[命名空间也为此,防止影响目前运行的任务,稳定后任务在切换]
笔者遇到了以下问题,将会为你一一解答
- airflow db init未执行报错问题
- redis连接问题
- 日志无法查看问题
- 多woker不启动问题
- helm upgrade问题
- 缓存问题
- 数据库不存在问题
- 动态安装依赖问题
其中有些问题,官网写的比较模糊,还是直接根据问题查看源码找到对应配置会快些
1. 新建secret.yaml文件
该文件主要存放git与repo访问秘钥
apiVersion: v1
kind: Secret
metadata:
name: git-credentials
type: Opaque
data:
GIT_SYNC_USERNAME: XXXXXXX
GIT_SYNC_PASSWORD: XXXXXXX
---
apiVersion: v1
kind: Secret
type: kubernetes.io/dockerconfigjson
metadata:
name: nexus-registry-secret
namespace: airflow-plus
data:
".dockerconfigjson": "XXXXXXX"
部署该文件到命名空间airflow-plus
kubectl apply -f secret.yaml --namespace airflow-plus
2. 新建values.yaml文件
该文件主要进行一些重写工作,可参照源码values.yaml
config:
core:
# git上dags所在的目录,配置对即可在webserver中看到dags
dags_folder: /opt/airflow/dags/repo/dags
# 根据ip方式通信,默认hostname域名方式,解决访问worker节点日志无法查看问题
hostname_callable: airflow.utils.net.get_host_ip_address
default_timezone: Asia/Shanghai
webserver:
# 重写args方法,执行airflow webserver前执行airflow db init解决初始化报错问题
args:
- "bash"
- "-c"
- |-
exec \
airflow db init \
|-
exec \
airflow webserver
service:
type: NodePort
ports:
- name: airflow-ui
port: 8080
targetPort: 8080
# 浏览器访问端口映射
nodePort: 30120
3. 新建uninstall.sh
主要对airflow进行一键卸载
helm delete airflow --namespace airflow-plus
4. 新建install.sh
一键安装airflow,重点来了
helm repo add apache-airflow https://airflow.apache.org
export RELEASE_NAME=airflow
# upgrade若报错helm list --namespace airflow-plus查看对应release是否存在,不存在则install,并且指定刚才的values.yaml文件
helm upgrade --install $RELEASE_NAME apache-airflow/airflow --namespace airflow-plus -f values.yaml \
# K8S部署选用该Executor
--set executor=CeleryKubernetesExecutor \
--set defaultAirflowRepository=apache/airflow \
--set airflowVersion=2.5.1 \
--set data.metadataConnection.user=airflow \
# pgsql密码
--set postgresql.auth.postgresPassword=XXXXX \
# pgsql连接IP
--set data.metadataConnection.host=192.168.0.XXX \
# pgsql元数据访问密码,一般与密码一致
--set data.metadataConnection.pass=XXXXX \
# pgsql连接端口,根据实际进行修改
--set data.metadataConnection.port=35432 \
# pgsql授权用户名
--set postgresql.auth.username=airflow \
# pgsql授权密码,一般与密码一致
--set postgresql.auth.password=XXXXX \
# 外部redis连接地址,注意格式,否则连接会报错
--set data.brokerUrl=redis://redis-pod.middleware:6379/0 \
# 元数据连接数据库名,不存在则到pgsql中新建,否则报错
--set data.metadataConnection.db=airflow_plus \
# false表示使用外部pgsql
--set postgresql.enabled=false \
# false表示使用外部redis
--set redis.enabled=false \
# 由于直接在新的命名空间与新库部署,所以不需要迁移,设置为false
--set triggerer.waitForMigrations.enabled=false \
--set webserver.waitForMigrations.enabled=false \
--set scheduler.waitForMigrations.enabled=false \
# git工具仓库地址
--set images.gitSync.repository=registry.cn-hangzhou.aliyuncs.com/goojia/k8s \
# git版本
--set images.gitSync.tag=git-sync-v3.3.0 \
# 公司gitlab airflow项目地址
--set dags.gitSync.repo=http://gitlab.XXXX.com/dev0/airflow.git \
# 允许git同步
--set dags.gitSync.enabled=true \
# git同步分支
--set dags.gitSync.branch=master \
# git同步授权秘钥,就是secret.yaml中配置的
--set dags.gitSync.credentialsSecret=git-credentials \
# 其他的一些暂时用不到的先为false
--set createUserJob.applyCustomEnv=false \
--set createUserJob.serviceAccount.create=false \
--set migrateDatabaseJob.applyCustomEnv=false \
--set createUserJob.useHelmHooks=false \
--set migrateDatabaseJob.enabled=false \
--set migrateDatabaseJob.serviceAccount.create=false \
--set migrateDatabaseJob.useHelmHooks=false \
--set cleanup.serviceAccount.create=false \
# workers默认为Stateful Sets,需要设置为false,才会为Deployment部署为Pod
--set workers.persistence.enabled=false \
# workers pod数
--set workers.replicas=3 \
# 开启创建默认用户job
--set webserver.defaultUser.enabled=true \
# 如果有对镜像改造的需求,这里授权访问公司repo
#--set registry.secretName=nexus-registry-secret
至此一切OK了,./install.sh
一键部署吧
5.访问airflow
http://IP:30120/, 默认用户名admin 密码admin
主页面:
日志查看:
K8S妥妥的多worker节点:
6. 总结与其他
在实操的过程中,遇到问题询问ChatGPT会省不少时间,有些ChatGPT也解答不好的话,最好下载下来Helm Chart对应版本源码,及Airflow源码,也可能会很快搜到一些有效信息
其实在用的时候,公司有自己的工具类,目前的话手工到workers中去一个个安装,即使更新也是手工修改,也尝试了通过改写父类方法每次都提前安装的方式不过没成功,任务多起来每次都要安装还不如一个个worker去安装,反正目前worker数也不多,如果你有更好的方式欢迎与我沟通交流
由于airflow任务调度由k8s部署,采用官方推荐的helm操作方式,且对于公司常用的操作封装为工具类,因此对于工具类目前需要pip install,此时发现oracle工具类无法正常服务,错误如下
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory"
显然,是oracle client未进行安装。ok,现在介绍如何在k8s中解决【通过pod内安装客户端实现(暂未找到更好方式,如果有烦请留言)】【当然rpm方式最简单,只是k8s pod内安装yum rpm许久都未成功】
7. 工具类调用oracle client问题总结
7.1 下载oracle client
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
我下载的是Basic Package (ZIP) instantclient-basic-linux.x64-21.7.0.0.0dbru.zip
7.2 上传至airflow-worker pod所在机器并解压
unzip instantclient-basic-linux.x64-21.7.0.0.0dbru.zip
7.3 拷贝oracle client至pod内
# 查看运行中容器,找到airflow-worker容器id
docker container ls
# 将解压好的文件拷贝至airflow-worker容器内
docker cp instantclient_21_7/* da5b702bbcfd:/home/airflow/
7.4 配置实例加载目录
此步骤是为了解决如果问题:
DPI-1047: Cannot locate a 64-bit Oracle Client library: "/home/airflow/instantclient_21_7/lib/libclntsh.so: cannot open shared object file: No such file or directory"
# root权限进入docker容器
docker exec -u 0 -it da5b702bbcfd
echo '/home/airflow/instantclient_21_7' >> /etc/ld.so.conf
# 立即生效
ldconfig
7.5 安装libaio依赖
如果此时执行,报如下错误:
error while loading shared libraries: libaio.so.1: cannot open shared
则仍然在pod内安装依赖即可:
# 配置apt-get源
root@airflow-worker-6d4d8ff54f-jhd24: echo "deb http://mirrors.163.com/debian/ stretch main non-free contrib" >/etc/apt/sources.list && echo "deb http://mirrors.163.com/debian/ stretch-updates main non-free contrib" >>/etc/apt/sources.list && echo "deb http://mirrors.163.com/debian/ stretch-backports main non-free contrib" >>/etc/apt/sources.list && echo "deb-src http://mirrors.163.com/debian/ stretch main non-free contrib" >>/etc/apt/sources.list && echo "deb-src http://mirrors.163.com/debian/ stretch-updates main non-free contrib" >>/etc/apt/sources.list && echo "deb-src http://mirrors.163.com/debian/ stretch-backports main non-free contrib" >>/etc/apt/sources.list && echo "deb http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib" >>/etc/apt/sources.list && echo "deb-src http://mirrors.163.com/debian-security/ stretch/updates main non-free contrib" >>/etc/apt/sources.list
root@airflow-worker-6d4d8ff54f-jhd24:/home/airflow/instantclient_21_7# apt-cache search libaio
libaio-dev - Linux kernel AIO access library - development files
libaio1 - Linux kernel AIO access library - shared library
root@airflow-worker-6d4d8ff54f-jhd24:/home/airflow/instantclient_21_7# apt-get install libaio1
7.6 验证服务
进入airflow pod
airflow@airflow-worker-6d4d8ff54f-jhd24:/opt/airflow$ python
Python 3.7.12 (default, Sep 28 2021, 20:11:10)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from xxx_utils import oracle
>>> oracle.scan_by_sql_to_data_frame("select distinct commid from forsale where rownum < 10")
commid
0 4cfd0b4f84ae3ade546b2619
这样就解决了airflow通过公司自定义工具类连接oracle的问题了,perfect!