Docker Compose运行Airflow DAG时遇UnknownHostException数据库连接错误
解决Airflow DAG中DockerOperator无法连接PostgreSQL主机名的问题
问题描述
执行Airflow DAG时触发以下错误:
Py4JJavaError: py4j.protocol.Py4JJavaError: An error occurred while calling o36.jdbc. : org.postgresql.util.PSQLException: The connection attempt failed. Caused by: java.net.UnknownHostException: test_db_3
核心问题是DockerOperator启动的容器无法解析PostgreSQL的主机名test_db_3,需求是保留DockerOperator实现服务解耦,不在Airflow容器中安装PySpark依赖。
解决方案
1. 让DockerOperator容器加入Compose专属网络
Docker Compose默认会为项目创建一个专属网络,而你的DAG中network_mode='bridge'使用的是Docker默认桥接网络,与Compose专属网络不互通,导致无法解析服务名。
修改DAG中的DockerOperator配置,指定使用Compose的专属网络:
from airflow import DAG from airflow.operators.docker_operator import DockerOperator from datetime import datetime with DAG( dag_id='first_sample_dag', start_date=datetime(2022, 5, 28), schedule_interval=None ) as dag: read_csv_to_table = DockerOperator( task_id='read_csv_to_table', image='airflow-backend:latest', command="python3 /app/main.py", # 替换为你的Compose项目默认网络,格式为[项目目录名]_default # 可通过docker network ls命令查看具体名称 network_mode='your_project_dir_name_default' ) read_csv_to_table
2. 统一使用服务名作为数据库连接主机名
你的backend服务环境变量中使用db作为数据库主机名,但错误中出现的是容器名test_db_3。Compose专属网络中,服务名(即docker-compose.yml中services下的db)是可靠的解析标识,容器名不建议用于连接。
检查并修改PySpark代码中的JDBC连接URL,使用服务名db:
# 示例PySpark连接代码 spark.read.jdbc( url="jdbc:postgresql://db:5432/template_db", table="target_table", properties={"user": "template", "password": "template"} )
3. 验证网络连通性(可选)
如果问题仍存在,可通过以下命令测试容器与数据库服务的连通性:
# 替换为你的Compose专属网络名称 docker run --network=your_project_dir_name_default busybox ping -c 3 db
关键说明
- Docker Compose默认网络名称规则:
[当前项目所在目录的名称]_default,可通过docker network ls命令查询 - 避免使用容器名作为连接主机,容器名可能随容器重启、重建发生变化,服务名是固定的服务标识
内容的提问来源于stack exchange,提问作者km_jsh12
相关产品推荐
相关产品推荐

