如何配置Docker部署的Spark独立集群接收跨机器容器任务?
Spark独立集群跨机器容器提交任务的网络配置问题
我正尝试使用以下docker-compose.yaml配置Spark独立集群:
spark: image: bitnami/spark:3.3.2 environment: - SPARK_MODE=master ports: - '8081:8080' - '7077:7077' spark-worker: image: bitnami/spark:3.3.2 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark:7077 - SPARK_WORKER_MEMORY=4G - SPARK_EXECUTOR_MEMORY=4G - SPARK_WORKER_CORES=4 ports: - '8082:8081'
需求
- 机器A通过
docker-compose up部署集群 - 机器B创建Spark容器,用
spark-submit --master spark://<机器AIP>:7077提交Python任务 - 机器C的Airflow Worker容器通过
spark-submit提交任务 - Jupyter Notebook容器创建Spark会话执行交互式计算
问题现象
集群在机器A上运行正常,master能识别worker,集群内部提交任务没问题。但跨机器容器提交任务时,任务在master UI中显示,但executor反复创建、销毁,日志如下:
23/04/16 22:06:39 INFO BlockManagerMaster: Removal of executor 9 requested 23/04/16 22:06:39 INFO CoarseGrainedSchedulerBackend$DriverEndpoint: Asked to remove non-existent executor 9 23/04/16 22:06:39 INFO BlockManagerMasterEndpoint: Trying to remove executor 9 from BlockManagerMaster. 23/04/16 22:06:39 INFO StandaloneSchedulerBackend: Granted executor ID app-20230416220604-0001/11 on hostPort 10.18.0.130:45783 with 1 core(s), 1024.0 MiB RAM 23/04/16 22:06:39 INFO StandaloneAppClient$ClientEndpoint: Executor updated: app-20230416220604-0001/11 is now RUNNING 23/04/16 22:06:45 INFO StandaloneAppClient$ClientEndpoint: Executor updated: app-20230416220604-0001/10 is now EXITED (Command exited with code 1) 23/04/16 22:06:45 INFO StandaloneSchedulerBackend: Executor app-20230416220604-0001/10 removed: Command exited with code 1 23/04/16 22:06:45 INFO StandaloneAppClient$ClientEndpoint: Executor added: app-20230416220604-0001/12 on worker-20230416220203-10.18.0.73-36107 (10.18.0.73:36107) with 1 core(s) 23/04/16 22:06:45 INFO StandaloneSchedulerBackend: Granted executor ID app-20230416220604-0001/12 on hostPort 10.18.0.73:36107 with 1 core(s), 1024.0 MiB RAM 23/04/16 22:06:45 INFO BlockManagerMaster: Removal of executor 10 requested 23/04/16 22:06:45 INFO BlockManagerMasterEndpoint: Trying to remove executor 10 from BlockManagerMaster.
尝试过的方法及错误
- 尝试在任务提交容器和Spark Worker中暴露10001-10005端口,设置
spark.driver.port、spark.blockManager.port、spark.driver.blockManager.port,无效。 - 尝试将
spark.driver.host设为任务提交容器所在机器IP,出现错误:
23/04/27 17:47:10 ERROR SparkContext: Error initializing SparkContext. java.net.BindException: Cannot assign requested address: Service 'sparkDriver' failed after 16 retries (starting from 10003)!
- 同一机器运行集群和任务提交容器,设
spark.driver.host为机器IP,错误依然存在。
解决方案
1. 修正Spark集群的网络可见性配置
在机器A的docker-compose.yaml中,需要让Spark节点对外暴露正确的物理IP,避免容器内部IP导致的通信障碍:
spark: image: bitnami/spark:3.3.2 environment: - SPARK_MODE=master - SPARK_MASTER_HOST=<机器A物理IP> # 指定Master对外的IP ports: - '8081:8080' - '7077:7077' spark-worker: image: bitnami/spark:3.3.2 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://<机器A物理IP>:7077 # 用机器IP替代容器名 - SPARK_WORKER_MEMORY=4G - SPARK_EXECUTOR_MEMORY=4G - SPARK_WORKER_CORES=4 - SPARK_WORKER_HOST=<机器A物理IP> # 指定Worker对外的IP ports: - '8082:8081' - '10000-10010:10000-10010' # 暴露Executor通信端口范围
2. 任务提交时的Driver配置
跨机器提交任务时,必须明确指定Driver的对外地址和端口,同时确保容器端口映射正确:
spark-submit命令示例:
spark-submit \ --master spark://<机器A物理IP>:7077 \ --conf spark.driver.host=<任务提交机器物理IP> \ --conf spark.driver.port=10002 \ --conf spark.driver.bindAddress=0.0.0.0 \ # 让Driver绑定容器内部所有地址 --conf spark.blockManager.port=10004 \ your_pyspark_script.py
任务提交容器启动命令示例:
docker run -d \ -p 10002:10002 \ -p 10004:10004 \ -p 4040:4040 \ # 可选,暴露Driver UI端口便于调试 <你的容器镜像>
3. 解决BindException错误的核心逻辑
出现端口绑定错误,是因为容器内部无法直接绑定到机器物理IP。通过spark.driver.bindAddress=0.0.0.0让Driver绑定容器内部的所有地址,再通过端口映射将该端口暴露到机器物理IP,同时spark.driver.host指定机器物理IP,确保Worker能反向连接到Driver。
4. 验证网络连通性
- 确保机器A的7077、8081、10000-10010端口能被其他机器访问
- 确保任务提交机器的10002、10004端口能被机器A访问
- 在机器A执行
telnet <任务提交机器IP> 10002验证端口可达性
内容的提问来源于stack exchange,提问作者João
相关产品推荐
相关产品推荐

