使用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作业,可能也运行从机本身。

我试过的东西:

  1. 从根本上不configurationSPARK_LOCAL_IP,从属绑定到容器的IP(如172.17.0.45),不能从主设备或驱动程序连接,计算大部分时间仍然工作,但并不总是
  2. 绑定到0.0.0.0,奴隶跟主人说话,build立连接但是死了,另外一个奴隶出现,消失,继续这样循环
  3. 绑定到主机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传递给Spark org.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容器/主机操作系统):

  1. 使用--net hostdocker run =>主机的eth0是在容器中可见
  2. SPARK_PUBLIC_DNSSPARK_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。

https://github.com/apache/spark/blob/v2.1.0/core/src/main/scala/org/apache/spark/util/Utils.scala#L904