Namenode 无法从 Docker 容器外部访问

Posted

技术标签:

【中文标题】Namenode 无法从 Docker 容器外部访问【英文标题】:Namenode not accessible from outside Docker container 【发布时间】:2019-09-03 01:19:59 【问题描述】:

我对一个 Hadoop 应用程序进行了 docker 化,并且出于显而易见的原因尝试从容器外部访问名称节点。

我使用 Dockerfile 暴露了端口:

EXPOSE 2122 9000

我用以下方式启动容器:

$ docker run -dit --rm --privileged --pid=host -p 2122:2122 -p 9000:9000 --name hnode ns/hnode

2122 是我用于 SSH 的端口。我已经安装了 SSH 服务器,试了一下,我能够从容器外部通过 SSH 连接

我还向 Hadoop 添加了使用此 SSH 端口的选项,而不是 ENV HADOOP_SSH_OPTS="-p 2122"


使用以下 core-site.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

当我尝试从容器内部远程登录 9000 时,一切都很好:

[hadoop@1f5c7934fe45 hadoop]$ telnet localhost 9000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

   |��☼►☻↑      ")org.apache.hadoop.ipc.RPC$VersionMismatch*>Server IPC version 9 cannot communicate with client version 130♫: @☺Connection closed by foreign host.

您清楚地看到它是另一端的名称节点。

但是当我尝试使用主机 ip 从容器内部远程登录 namenode 使用的 9000 端口时,我得到:

[hadoop@1f5c7934fe45 hadoop]$ telnet 172.17.0.2 9000
Trying 172.17.0.2...
telnet: connect to address 172.17.0.2: Connection refused

即使 SSH 工作正常:

[hadoop@1f5c7934fe45 hadoop]$ telnet 172.17.0.2 2122
Trying 172.17.0.2...
Connected to 172.17.0.2.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4

Protocol mismatch.
Connection closed by foreign host.

为什么 SSH 可以工作,而不是 Hadoop 的 namenode?​​p>

【问题讨论】:

我添加了 Hadoop 组件的 HTTP 接口的端口,这些端口在外部运行良好。只有namenode不会和陌生人说话。 namenode 日志中也没有什么特别的内容。 我刚刚使用容器的外部 IP 更改了 core-site.xml 属性。 Telnet 有效,很有希望。 【参考方案1】:

我通过编辑fs.default.name 并将另外两个属性添加到配置文件中解决了这个问题。

<property>
    <name>dfs.client.use.datanode.hostname</name>
    <value>true</value>
    <description>Whether clients should use datanode hostnames when connecting to datanodes.</description>
</property>
<property>
    <name>dfs.namenode.rpc-address</name>
    <value>172.17.0.2:9000</value>
</property>
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://172.17.0.2:9000</value>
</property>

【讨论】:

【参考方案2】:

其实我只需要把主机的IP放在core-site.xml而不是localhost:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>fs.default.name</name>
        <value>hdfs://172.17.0.2:9000</value>
    </property>
</configuration>

这样,我就可以通过外部路由从内部远程登录namenode:

[hadoop@1f5c7934fe45 hadoop]$ telnet 172.17.0.2 9000
Trying 172.17.0.2...
Connected to 172.17.0.2.
Escape character is '^]'.

   |��☼►☻↑      ")org.apache.hadoop.ipc.RPC$VersionMismatch*>Server IPC version 9 cannot communicate with client version 100♫: @☺Connection closed by foreign host.

甚至来自外部:

λ curl 192.168.56.1:9000
It looks like you are making an HTTP request to a Hadoop IPC port. This is not the correct port for the web interface on this daemon.

我知道这些是错误,但它们确认守护程序已回答并且可以访问。

【讨论】:

以上是关于Namenode 无法从 Docker 容器外部访问的主要内容,如果未能解决你的问题,请参考以下文章

docker 容器网络绑定端口部署

Kafka Docker - 无法从 docker 容器外部生产或消费

SpringBoot @RestController 无法从 docker 容器外部访问

我无法从容器外部访问 docker [重复]

无法从 Docker 容器连接到外部 SQL Server

Docker 端口 问题排查思路