无法连接到docker host

时间:2017-07-24 09:05:39

标签: hadoop docker

我有两个在ubuntu上运行的docker容器,其中一个用于hadoop namenode,另一个用于hadoop datanode。

现在我在Windows上运行我的java代码使用Hadoop FileSystem api将文件从我的windows文件系统复制到远程docker hdfs。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

import java.io.File;

public class HadoopTest {

    @Test
    public void testCopyFileToHDFS() throws Exception {
        Configuration configuration = new Configuration();
        configuration.addResource(getClass().getClassLoader().getResourceAsStream("hadoop/core-site.xml"));
        configuration.addResource(getClass().getClassLoader().getResourceAsStream("hadoop/yarn-site.xml"));
        FileSystem fileSystem = FileSystem.get(configuration);
        FileUtil.copy(new File("c:\\windows-version.txt"),fileSystem,   new Path("/testsa"), false,configuration);
    }
}

但我收到以下错误:

16:57:05.669 [Thread-4] DEBUG org.apache.hadoop.hdfs.DFSClient - Connecting to datanode 172.18.0.2:50010
16:57:15.654 [IPC Client (547201549) connection to /192.168.56.102:9000 from ignis] DEBUG org.apache.hadoop.ipc.Client - IPC Client (547201549) connection to /192.168.56.102:9000 from ignis: closed
16:57:15.655 [IPC Client (547201549) connection to /192.168.56.102:9000 from ignis] DEBUG org.apache.hadoop.ipc.Client - IPC Client (547201549) connection to /192.168.56.102:9000 from ignis: stopped, remaining connections 0
16:57:26.670 [Thread-4] INFO org.apache.hadoop.hdfs.DFSClient - Exception in createBlockOutputStream
java.net.ConnectException: Connection timed out: no further information
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
    at org.apache.hadoop.net.SocketIOWithTimeout.connect(SocketIOWithTimeout.java:206)
    at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:531)
    at org.apache.hadoop.hdfs.DFSOutputStream.createSocketForPipeline(DFSOutputStream.java:1533)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.createBlockOutputStream(DFSOutputStream.java:1309)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1262)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:448)
16:57:26.673 [Thread-4] INFO org.apache.hadoop.hdfs.DFSClient - Abandoning BP-53577818-172.18.0.2-1500882061263:blk_1073741827_1003

您可以看到第一行错误,其中“连接到datanode 172.18.0.2:50010”是一个docker内部ip地址。

我的Java代码在Docker主机之外的真实Windows机器上运行。

我已将Hadoop HDFS端口(例如9000和50010)映射到我的docker主机(ubuntu)。因此,我可以通过docker host ip address和HDFS的端口访问HDFS名称节点。

以下是我的java代码的逻辑:

1)Java代码正在Windows机器上运行

2)Java代码使用FileSystem api将文件从Windows复制到远程HDFS。

3)客户端可以使用docker主机的IP地址和从docker容器映射的端口(例如9000)连接到HDFS名称节点

4)HDFS Namenode服务器将处理从客户端发送的请求并将数据节点的ip地址返回给客户端。

5)客户端尝试使用数据节点的IP地址从本地复制文件

6)客户端收到错误,表示数据节点的IP地址无法访问,因为它是docker容器内的ip地址

enter image description here

1 个答案:

答案 0 :(得分:4)

最后,我通过引入datanode的主机名并在连接到datanode时使hdfs客户端使用主机名而不是ip地址找到解决方案,我的客户端还需要将datanode主机名映射为docker主机ip地址,下面是详细步骤:

  1. 在docker-compose.xml中添加docker datanode容器的主机名

    主机名:datanode.company.com

  2. 启用hdfs(服务器和客户端)以使用主机名而不是ip地址。

  3. <configuration>
        <property>
            <name>dfs.client.use.datanode.hostname</name>
            <value>true</value>
        </property>
        <property>
            <name>dfs.datanode.use.datanode.hostname</name>
            <value>true</value>
        </property>
    </configuration>

    1. 通过在etc / hosts文件中添加条目,将docker datanode主机名映射为docker host ip address

      192.168.1.25 datanode.company.com