在Kubernetes部署Airflow 1.8.1时遇只读文件系统权限错误
看起来你碰到的是两个关联的问题:文件系统只读导致sed无法创建临时文件,加上sed替换命令语法不完整,这俩凑一块把Airflow的启动给卡壳了。我来一步步帮你搞定:
1. 先搞定只读文件系统的问题
Pod日志里的sed: couldn't open temporary file /usr/local/airflow/sed18bPUH: Read-only file system是核心问题之一,原因通常有两个:
Pod配置了只读根文件系统:检查你的Deployment/StatefulSet配置,如果
securityContext里写了readOnlyRootFilesystem: true,要么把这个配置删掉,要么给/usr/local/airflow挂载一个可写的卷(比如emptyDir或者PVC),示例配置如下:apiVersion: apps/v1 kind: Deployment metadata: name: airflow spec: template: spec: volumes: - name: airflow-workdir emptyDir: {} # 临时存储,生产环境建议换成PVC containers: - name: airflow image: your-custom-airflow-image:1.8.1 volumeMounts: - name: airflow-workdir mountPath: /usr/local/airflow目录权限不匹配:puckel的Airflow镜像默认用
airflow用户(UID 50000)运行,如果你的Pod用了其他runAsUser,会导致没有写入/usr/local/airflow的权限。可以在Pod的securityContext里指定正确的用户和组:securityContext: runAsUser: 50000 runAsGroup: 50000 fsGroup: 50000
2. 修复sed命令未终止的错误
日志里的unterminated s' command是因为sed的替换命令被特殊字符打断了。举个例子:如果你的Airflow数据库连接字符串是postgres://user:pass@db-host/airflow,里面的/会和sed默认的分隔符冲突,导致sed以为命令到第一个/`就结束了,后面的内容都变成无效语法。
解决办法是换一个sed的分隔符(比如|或者#),修改Airflow启动脚本里的sed命令:
如果是自己构建镜像,找到镜像里的启动脚本(比如entrypoint.sh),把原来的:
sed -e "s/{{ AIRFLOW__CORE__SQL_ALCHEMY_CONN }}/${AIRFLOW__CORE__SQL_ALCHEMY_CONN}/g" \ airflow.cfg.tpl > airflow.cfg
改成:
sed -e "s|{{ AIRFLOW__CORE__SQL_ALCHEMY_CONN }}|${AIRFLOW__CORE__SQL_ALCHEMY_CONN}|g" \ airflow.cfg.tpl > airflow.cfg
如果不想重新构建镜像,也可以在K8s的Pod配置里用command覆盖启动流程,先手动替换配置文件再启动Airflow。
3. 验证数据库初始化
当上面两个问题解决后,重新部署Pod,应该就能正常执行数据库初始化了。如果还是有问题,先检查数据库连接字符串是否正确,Airflow使用的数据库用户是否有创建表的权限。
内容的提问来源于stack exchange,提问作者spaghettifunk

