使用Docker容器在独立群集上Spark SPARK_PUBLIC_DNS和SPARK_LOCAL_IP
到目前为止,我只在Linux机器和虚拟机(桥接networking)上运行Spark,但是现在我有兴趣将更多的计算机用作从机。 在计算机上分配一个Spark Slave Docker容器并将它们自动连接到一个硬编码的Spark master ip将会很方便。 这个工作已经很短了,但是在从属容器上configuration正确的SPARK_LOCAL_IP(或者–start-slave.sh的–host参数)时有问题。
我想我正确地configuration了SPARK_PUBLIC_DNS envvariables来匹配主机的networking可访问IP(从10.0.xx地址空间),至less它在Spark主Web UI上显示,并且可以被所有机器访问。
我也按照http://sometechshit.blogspot.ru/2015/04/running-spark-standalone-cluster-in.html中的说明设置了SPARK_WORKER_OPTS和Docker端口,但在我的情况下,Spark主服务器正在运行机器,而不是在Docker里面。 我从networking中的其他机器启动Spark作业,可能也运行从机本身。
我试过的东西:
- 从根本上不configurationSPARK_LOCAL_IP,从属绑定到容器的IP(如172.17.0.45),不能从主设备或驱动程序连接,计算大部分时间仍然工作,但并不总是
- 绑定到0.0.0.0,奴隶跟主人说话,build立连接但是死了,另外一个奴隶出现,消失,继续这样循环
- 绑定到主机IP,启动失败,因为该IP在容器内不可见,但是由于configuration了端口转发,其他人可以访问
我想知道为什么在连接到从站时没有使用configuration的SPARK_PUBLIC_DNS? 我以为SPARK_LOCAL_IP只会影响本地绑定,但不会被透露给外部的电脑。
在https://databricks.gitbooks.io/databricks-spark-knowledge-base/content/troubleshooting/connectivity_issues.html上,他们指示“将SPARK_LOCAL_IP设置为驱动程序,主服务器和工作进程的集群可寻址主机名”这是唯一的select? 我会避免额外的DNSconfiguration,只需使用ips来configuration计算机之间的stream量。 还是有一个简单的方法来实现呢?
编辑:总结当前的设置:
- Master正在Linux上运行(使用桥接networking的Windows上的VirtualBox上的VM)
- 驱动程序从其他Windows机器提交作业,效果很好
- 用于启动从站的Docker映像以“saved”.tar.gz文件forms发布,并加载(curl xyz | gunzip | docker load),并在networking中的其他机器上启动,具有私有/公共ipconfiguration
我在我的机器上运行3种不同types的Docker容器,当我们需要的所有软件都添加到他们的时候,我们打算将它们部署到云中:Master,Worker和Jupyter笔记本(包含Scala,R和Python内核)。
以下是我迄今为止的观察结果:
主:
- 我无法将其绑定到Docker主机IP。 相反,我传递了一个域名:
-h "dockerhost-master" -e SPARK_MASTER_IP="dockerhost-master"
。 我找不到一种方法使Akka绑定在容器的IP上,但接受主机IP的消息。 我知道Akka 2.4是可能的,但也许不是Spark。 - 我正在传递
-e SPARK_LOCAL_IP="${HOST_IP}"
,导致Web UI绑定到该地址而不是容器的IP,但Web UI工作正常。
工人:
- 我给工作者容器一个不同的主机名,并将其作为
--host
传递给Sparkorg.apache.spark.deploy.master.Worker
类。 它不能和主人一样,或者Akka集群不起作用:-h "dockerhost-worker"
- 我正在使用Docker的
add-host
因此容器能够将主机名parsing为主机的IP:–--add-host dockerhost-master:${HOST_IP}
- 需要传递的主URL是
spark://dockerhost-master:7077
Jupyter:
- 这需要主URL和
add-host
才能解决它 -
SparkContext
存在于笔记本中,这是Spark应用程序的Web UI启动的地方,而不是主机。 默认情况下,它绑定到Docker容器的内部IP地址。 要改变我必须传入:-e SPARK_PUBLIC_DNS="${VM_IP}" -p 4040:4040
。 笔记本的后续申请将在4041,4042等。
通过这些设置,三个组件可以相互通信。 我正在使用spark-class
自定义启动脚本来启动前台的类,并保持Docker容器不在此刻退出。
还有一些其他的端口可以被暴露,比如我还没有遇到的历史服务器。 使用--net host
似乎更简单。
我想我find了一个解决scheme,我的用例(一个Spark容器/主机操作系统):
- 使用
--net host
与docker run
=>主机的eth0是在容器中可见 - 将
SPARK_PUBLIC_DNS
和SPARK_LOCAL_IP
设置为主机的IP,忽略docker0的172.xxx地址
Spark可以绑定到主机的IP地址,其他机器也可以和其他机器通信,其余的端口转发处理。 DNS或任何复杂的configuration不需要,我还没有彻底的testing,但迄今如此好。
编辑:请注意,这些指令是针对Spark 1.x,在Spark 2.x只有SPARK_PUBLIC_DNS
是必需的,我认为SPARK_LOCAL_IP
已被弃用。
我也运行不同docker主机上的容器中的火花。 用这些参数启动工作容器为我工作:
docker run \ -e SPARK_WORKER_PORT=6066 \ -p 6066:6066 \ -p 8081:8081 \ --hostname $PUBLIC_HOSTNAME \ -e SPARK_LOCAL_HOSTNAME=$PUBLIC_HOSTNAME \ -e SPARK_IDENT_STRING=$PUBLIC_HOSTNAME \ -e SPARK_PUBLIC_DNS=$PUBLIC_IP \ spark ...
其中$PUBLIC_HOSTNAME
是主机可访问的主机名。
缺less的部分是SPARK_LOCAL_HOSTNAME
,一个未SPARK_LOCAL_HOSTNAME
的选项AFAICT。