Невозможно установить доступ к коду данных, работающему на macOS, из контейнера docker

#macos #docker #hadoop #hdfs

Вопрос:

У меня нет опыта работы с HDFS, и я столкнулся с проблемой, связанной с HDFS, работающими на моем macbook. У меня есть клиент HDFS, который запускается в контейнере docker, и каждый раз, когда я пытаюсь поместить или получить данные в/из HDFS из этого контейнера, я получаю следующую ошибку:

 hdfs dfs -put /core-site.xml hdfs://host.docker.internal:9000/abcs
21/03/02 07:28:47 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
21/03/02 07:28:48 INFO hdfs.DFSClient: Exception in createBlockOutputStream
java.net.ConnectException: Connection refused
    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:530)
    at org.apache.hadoop.hdfs.DFSOutputStream.createSocketForPipeline(DFSOutputStream.java:1610)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.createBlockOutputStream(DFSOutputStream.java:1408)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1361)
    at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:588)
21/03/02 07:28:48 INFO hdfs.DFSClient: Abandoning BP-1485605719-127.0.0.1-1614607405999:blk_1073741832_1008
21/03/02 07:28:48 INFO hdfs.DFSClient: Excluding datanode 127.0.0.1:9866
21/03/02 07:28:48 WARN hdfs.DFSClient: DataStreamer Exception
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /abcs/core-site.xml._COPYING_ could only be written to 0 of the 1 minReplication nodes. There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
 

Ясно видно, что мой клиент(контейнер) получает неправильный IP-адрес кода данных (127.0.0.1:9866), это должно быть что-то вроде 192.168.65.2:9866, т. е. host.docker.internal. или доменное имя моего ноутбука (например, мой ноутбук)

Мой core-site.xml: (конечно, мой ноутбук привязан к 127.0.0.1 в etc/hosts)

 <configuration>
    <property>         
        <name>fs.defaultFS</name>         
        <value>hdfs://my-laptop:9000</value>     
    </property>
    <property>
          <name>hadoop.tmp.dir</name>
          <value>/Users/Ian_Rakhmatullin/localHadoopTmp</value>
  </property>
</configuration>
 

hdfs-site.xml:

 <configuration>
    <property>         
        <name>dfs.replication</name>        
         <value>1</value>    
     </property>
     <property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
     <property>
        <name>dfs.datanode.use.datanode.hostname</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.datanode.address</name>
        <value>my-laptop:9866</value>
    </property>
    <property>
        <name>dfs.datanode.http.address</name>
        <value>my-laptop:9864</value>
    </property>
    <property>
        <name>dfs.datanode.ipc.address</name>
        <value>my-laptop:9867</value>
    </property>
</configuration>

 

Еще одна вещь , которая меня смущает, заключается в том, что через HDFS WebUI я вижу, что работает DataNode localhost:9866 (127.0.0.1:9866) , но я также ожидаю «мой ноутбук:9866».

У кого-нибудь есть какие-либо мысли о том, как решить эту проблему? Спасибо.

Ответ №1:

Похоже, я решил эту проблему, выполнив следующие действия:

  1. Добавьте свойство dfs.datanode.hostname в свои hdfs

hdfs-xml сайта:

     <property>         
        <name>dfs.replication</name>        
         <value>1</value>    
    </property>
    <property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.datanode.use.datanode.hostname</name>
        <value>true</value>
    </property> 
    <property>
        <name>dfs.datanode.hostname</name>
        <value>my-laptop</value>
    </property> 
 

xml основного сайта такой же, как и в моем вопросе.

  1. Добавьте dfs.client.use.datanode.имя хоста в свой hdfs-site.xml для клиента hdfs;
     <property>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
 
  1. Сопоставьте DNS-имя (мой ноутбук в моем случае) с IP-адресом вашего хоста docker (host.docker.internal в моем случае -> 192.168.65.2) в контейнере etc/hosts
 192.168.65.2 my-laptop
 

При таком подходе Namenode вернет имя хоста для вашего кода данных клиенту hdfs, а затем клиент будет использовать ваше сопоставление с host.docker.internal. И это то, что мне было нужно.