You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器部署的Airflow如何连接访问HDFS读取文件?

问题根因

两个报错核心是Docker网络隔离+WebHDFS固有重定向机制导致的,没有其他玄学问题:

  • 直接填localhost/127.0.0.1时,容器内回环地址指向容器自身,根本碰不到宿主机或其他容器上的HDFS服务,直接触发No route to host
  • 填host.docker.internal报Cannot assign requested address,一是Linux环境下Docker默认不会自动配置这个域名到宿主机网关的映射,二是WebHDFS本身的逻辑是:你先访问9870端口的namenode请求文件,namenode会返回对应datanode的地址给客户端做二次重定向,如果HDFS配置里绑定的是127.0.0.1或者宿主机本地地址,容器拿到重定向地址后根本没法访问
  • 如果HDFS和Airflow分别跑在独立Docker容器里,默认用bridge网络时容器之间不能直接通过宿主机IP通信,也会触发路由错误
分步解决方案

根据HDFS部署位置选对应方案操作即可。

场景1:HDFS部署在宿主机(本地物理机/虚拟机)

  • 第一步:修改HDFS配置,避免返回不可路由的本地地址
    找到Hadoop配置目录下的hdfs-site.xml,添加/修改如下配置,让HDFS服务监听所有网卡,且给客户端返回可跨网络访问的地址:
    <property>
      <name>dfs.namenode.rpc-bind-host</name>
      <value>0.0.0.0</value>
    </property>
    <property>
      <name>dfs.namenode.servicerpc-bind-host</name>
      <value>0.0.0.0</value>
    </property>
    <property>
      <name>dfs.namenode.http-bind-host</name>
      <value>0.0.0.0</value>
    </property>
    <property>
      <name>dfs.datanode.bind-host</name>
      <value>0.0.0.0</value>
    </property>
    <property>
      <name>dfs.client.use.datanode.hostname</name>
      <value>true</value>
    </property>
    <property>
      <name>dfs.datanode.use.datanode.hostname</name>
      <value>true</value>
    </property>
    
    同时修改core-site.xml里的fs.defaultFS配置,不要写localhost,改成宿主机物理网卡的非回环IP(就是你之前在PyCharm里能正常访问的172.20.80.1这类地址),改完重启HDFS所有服务。
  • 第二步:配置Airflow容器的宿主机访问规则
    如果是用docker run启动Airflow,启动命令加--add-host=host.docker.internal:host-gateway参数;如果是用docker-compose部署,在Airflow对应服务的配置段下加:
    extra_hosts:
      - "host.docker.internal:host-gateway"
    
    重启Airflow容器后,先进入容器执行curl http://host.docker.internal:9870/webhdfs/v1/?op=LISTSTATUS验证能正常返回HDFS目录列表,再把代码里的访问地址改成http://host.docker.internal:9870/webhdfs/v1/hadoop_files/sample_2022_01.parquet?op=OPEN即可。

场景2:HDFS和Airflow都部署在Docker容器中

  • 第一步:创建自定义Docker桥接网络
    执行命令:docker network create hadoop-net
  • 第二步:把HDFS相关容器、Airflow所有服务容器都接入这个自定义网络
    启动namenode容器时指定--network hadoop-net --name hdfs-namenode(固定容器名方便Docker内部DNS解析),datanode容器也接入同一个网络;如果是compose部署,把所有相关服务都放在同一个自定义网络下,不要用默认bridge网络。
  • 第三步:修改HDFS配置
    配置项和场景1一致,把core-site.xml里的fs.defaultFS地址改成hdfs://hdfs-namenode:9000,确保datanode的服务端口在自定义网络内可通。
  • 第四步:验证连通性
    进入Airflow的worker容器执行curl http://hdfs-namenode:9870/webhdfs/v1/?op=LISTSTATUS,返回正常后再修改代码里的访问地址为对应容器名的URL即可。
稳定性优化建议

不推荐直接拼WebHDFS URL用pd.read_parquet读文件,WebHDFS两次重定向的逻辑在容器、跨网络环境下很容易出兼容问题,更稳定的方式是用HDFS原生RPC协议读取,绕开HTTP重定向逻辑:

  1. 先在Airflow镜像里安装pyarrow的HDFS依赖:pip install pyarrow hdfs
  2. 读文件代码改成如下形式:
from pyarrow import fs
import pandas as pd

# 宿主机部署HDFS就填host.docker.internal,容器同网络部署就填namenode容器名
hdfs = fs.HadoopFileSystem('host.docker.internal', port=9000)
with hdfs.open_input_file('/hadoop_files/sample_2022_01.parquet') as f:
    df = pd.read_parquet(f)

另外记得检查宿主机/容器防火墙开放9000(RPC端口)、9870(namenode Web端口)、9864(datanode数据传输端口),避免路由通了但被防火墙拦截。


内容的提问来源于stack exchange,提问作者Val

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:42:17