从独立Docker容器访问Spark集群遇执行器启动失败求助
解决跨Docker容器访问Spark集群时执行器启动失败的问题
问题核心分析
从日志可以明确:Spark Worker能正常接收启动Executor的指令,但Executor进程启动后立即退出(状态EXITED,退出码1),根本原因是Executor无法反向连接到Jupyter容器内的Spark Driver:
- 你在Jupyter容器中用
host.docker.internal访问Spark Master,Driver能成功注册到Master,但Worker所在容器无法通过host.docker.internal访问Jupyter容器内的Driver端口; - Driver默认绑定容器内部IP,Worker容器处于独立网络环境,无法直接访问该IP。
针对性解决方案
1. 将所有容器加入同一自定义Docker网络
默认Docker bridge网络存在通信限制,创建自定义网络让Spark集群和Jupyter容器可通过容器名直接通信:
# docker-compose.yml 示例 version: '3.8' networks: spark-network: driver: bridge services: spark-master: image: bitnami/spark:3.3.1 container_name: spark-master networks: - spark-network environment: - SPARK_MODE=master - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - "7077:7077" - "8080:8080" spark-worker: image: bitnami/spark:3.3.1 container_name: spark-worker networks: - spark-network environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark-master:7077 - SPARK_WORKER_MEMORY=2G - SPARK_WORKER_CORES=2 - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no jupyter-lab: image: jupyter/pyspark-notebook:ubuntu-20.04 container_name: jupyter-lab networks: - spark-network ports: - "8888:8888" - "4040-4050:4040-4050" # 暴露Driver及UI端口范围 - "36945:36945" # 指定固定Driver端口时需暴露 volumes: - ./data:/data # 共享数据卷,确保Worker能访问/data目录 environment: - PYSPARK_PYTHON=python3
2. 启动PySpark时指定Driver的可访问地址
在Jupyter容器内启动PySpark时,明确指定spark.driver.host为Jupyter容器名称(jupyter-lab),让Spark Worker能通过网络定位到Driver:
pyspark --master "spark://spark-master:7077" \ --conf spark.driver.host=jupyter-lab \ --conf spark.driver.bindAddress=0.0.0.0 \ --conf spark.driver.port=36945 # 指定固定端口,避免随机端口无法暴露
3. 确保数据文件在所有容器中可访问
/data/test.parquet必须挂载到Spark Worker容器中,否则Executor启动后会因找不到数据文件失败。上述docker-compose通过./data:/data实现了卷共享,确保所有容器能访问同一数据目录。
验证步骤
- 启动所有容器:
docker-compose up -d - 进入Jupyter容器:
docker exec -it jupyter-lab bash - 执行上述PySpark启动命令,尝试读取Parquet文件:
df = spark.read.parquet('/data/test.parquet') df.show()
此时查看Spark Worker日志,应能看到Executor成功注册,不再出现EXITED状态。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

