基于docker-compose部署的Airflow中DockerOperator使用mounts参数报错
问题根因
你的报错完全是参数格式不匹配导致的,并非你推测的Celery Worker权限问题。错误日志里的json: cannot unmarshal string into Go struct field HostConfig.HostConfig.Mounts of type mount.Mount已经明确说明:Docker API接收到的Mount字段是字符串类型,无法解析为期望的Mount结构体格式。
Airflow 2.x版本的DockerOperator不再支持直接传入字符串数组作为mounts参数值,必须传入docker.types.Mount类的实例列表。
解决步骤
- 首先在DAG文件头部导入Mount类
from docker.types import Mount
- 修改DockerOperator的mounts参数配置
将你原本的mounts=["/airflow/dev/tmp:/airflow/dev/tmp"]替换为以下格式:
mounts=[ Mount( source="/airflow/dev/tmp", target="/airflow/dev/tmp", type="bind", read_only=False # 如果需要只读挂载可以设为True ) ],
- 额外路径校验注意事项
因为你的Celery Worker是通过挂载宿主机/var/run/docker.sock调用宿主机Docker服务,所以Mount的source路径必须是宿主机上的实际路径,而非Celery Worker容器内部路径:
- 先确认宿主机上
/airflow/dev/tmp目录存在 - 保证目录的读写权限对Celery Worker运行用户(默认UID为50000)开放
- 如果你使用的共享盘已经挂载到Celery Worker容器内,需要先将宿主机的共享盘路径同步挂载到Celery Worker容器,同时DockerOperator的source参数填宿主机的共享盘路径
修改后核心代码示例
# 头部新增导入 from docker.types import Mount # 中间DockerOperator部分修改为 t2 = DockerOperator( task_id='docker_command', image='centos:latest', api_version='auto', auto_remove=True, environment={ 'AF_EXECUTION_DATE': "{{ ds }}", 'AF_OWNER': "{{ task.owner }}" }, command="/bin/sleep 5", docker_url='unix://var/run/docker.sock', mounts=[ Mount( source="/airflow/dev/tmp", target="/airflow/dev/tmp", type="bind" ) ], network_mode='bridge' )
内容的提问来源于stack exchange,提问作者MrBronson
相关产品推荐
相关产品推荐

