【问题标题】:Docker overlay network publish only some of listed portsDocker 覆盖网络仅发布一些列出的端口
【发布时间】:2020-05-06 05:05:37
【问题描述】:

在设置 hadoop 集群时,我正在努力在 docker overlay 网络中发布端口。我想使用以下命令发布 hadoop 主容器的一些端口:

docker run -itd --name hadoop-master --hostname hadoop-master --network hadoop \
                                    -p 8088:8088 -p 50070:50070 -p 50090:50090 \
                                    -p 8080:8080 -p 18080:18080 -p 4040:4040 \
                                    hadoop-img

但由于某种原因,只能通过浏览器访问 :18080 端口。我确信所有的服务都在 docker 容器中运行。

当我在 hadoop-master 容器中运行时:

curl -v localhost:18080

curl -v hadoop-master:18080

我得到了相同的肯定响应(控制台上显示了一些 html),但是当我想对端口执行相同操作时,假设:50070(或任何其他已发布)只能通过主机名访问,即:

curl -v hadoop-master:50070 -> displays correct html response

但是当使用 localhost 时:

curl -v localhost:50070

我明白了:

 About to connect() to localhost port 50070 (#0)
*   Trying ::1...
* Connection refused
*   Trying 127.0.0.1...
* Connection refused
* Failed connect to localhost:50070; Connection refused
* Closing connection 0
curl: (7) Failed connect to localhost:50070; Connection refused

所以我的猜测是端口:50070 在 docker 容器内未正确映射到 localhost。我不知道为什么会这样。由于某些原因,端口在不使用覆盖网络的情况下正确发布。你能帮我解决我的问题吗?如果可以访问 Web UI,那就太好了。


我的 hdfs-site.xml 看起来像:

<configuration>

    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///usr/local/hadoop/hdfs/namenode</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///usr/local/hadoop/hdfs/datanode</value>
    </property>

    <!-- HA SETUP -->
    <property>
        <name>dfs.nameservices</name>
        <value>hadoopcluster</value>
    </property>

    <property>
        <name>dfs.ha.namenodes.hadoopcluster</name>
        <value>nn1,nn2</value>
    </property>

    <property>
        <name>dfs.namenode.rpc-address.hadoopcluster.nn1</name>
        <value>hadoop-master-1:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hadoopcluster.nn2</name>
        <value>hadoop-master-2:8020</value>
    </property>

    <property>
        <name>dfs.namenode.http-address.hadoopcluster.nn1</name>
        <value>hadoop-master-1:50070</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hadoopcluster.nn2</name>
        <value>hadoop-master-2:50070</value>
    </property>

    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://hadoop-jn-1:8485;hadoop-jn-2:8485;hadoop-jn-3:8485/hadoopcluster</value>
    </property>

    <property>
        <name>dfs.client.failover.proxy.provider.hadoopcluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>shell(/bin/true)</value>
    </property>

    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/HDPV2/journal/node/local/data</value>
    </property>

    <!-- ZOOKEEPER SETUP -->

     <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

     <property>
        <name>ha.zookeeper.quorum</name>
        <value>zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181</value>
    </property>

</configuration>

到目前为止,我已经创建了一个基本设置,它在分布在两个 docker 主机的单独容器中运行所有服务:

  • 3 个 Zookeeper 容器
  • 3 x 日志节点容器
  • 2 个主容器(资源管理器、namenode、HistoryServer 和 DFSZKFailoverController)
  • 3 个从属容器(datanode 和 nodemanager)

【问题讨论】:

  • 我很难相信有些端口映射正确而有些则没有。它通常是全有或全无。由于它是一个 Web 应用程序,因此可能将 Web 服务器配置为侦听端口和主机名的组合。当您将 curl 运行到 localhost 时,是从容器内部还是外部?当hadoop-master 工作正常时,为什么还需要localhost
  • @Mihai 所有命令都在 docker 容器内运行,我需要将其映射到本地主机,因为我想从我的 docker 守护程序主机访问 hadoop 的 Web 界面。似乎只有将 docker 容器内的主机名映射到 localhost 时它才有效。
  • 你能把 hadoop-master 添加到 /etc/hosts 并指向 127.0.0.1 吗?这会解决您从主机访问 UI 的问题吗?
  • @Mihai 当我将hadoop-master-1指向127.0.0.1时显示相同的通知Connection refused...

标签: docker hadoop networking mapping port


【解决方案1】:

您的 hdfs-site.xml 不应配置为使用本地主机地址或主机名地址。见dfs.namenode.http-address.hadoopcluster.nnX道具

dfs.namenode.http-address 默认绑定到0.0.0.0:50070,因此转发后将在容器外可用。

另外,还有dfs.datanode.http.address=0.0.0.0:50075,也不应该被触碰。

你想添加dfs.namenode.rpc-bind-host=0.0.0.0

如果名称节点没有运行,那么这完全是一个单独的问题。如果没有活动的 Namenode(端口 18080),Spark UI 将正常启动。您只是无法运行需要 HDFS 的 Spark 作业。

注意:NameNode、DataNode+NodeManager、ResourceManager 和 Spark 服务都应该是独立的容器(最好在不同的机器上)。否则,您只是在容器中构建单点故障,还不如使用适当的 VM。

【讨论】:

  • 我故意省略了数据节点端口(UI),而不是在外面发布它们。同样如前所述,我确信名称节点正在运行,因为只需在 hadoop-master-1 容器内键入 jpscurl -v hadoop-master-1 即可确认它们已启动。提交 SparkPI.jar 也成功了。
  • 在这种情况下,明天我将创建自己的 Spark 作业并在 HDFS 中的真实数据上进行尝试。但是在我看来这不是问题,因为当使用 docker bridge 网络而不是覆盖网络时,相同的配置在已发布的端口上产生了两个正常工作的名称节点 Web 界面:50070 和 50069(一个用于活动名称节点,第二个用于备用名称节点) )。当我决定使用 swarm 和覆盖网络的一些优势来组合两个 docker 主机(服务器)时,问题就开始出现了。
  • Spark 中包含一个 TestHDFS 作业。无需自己编写
  • 我对 Swarm 无能为力。我只知道在 k8s 或 nomad(支持 Spark)中运行 Hadoop
最近更新 更多