返回 导航

Docker / K8s

hangge.com

Docker - 通过容器搭建部署Hadoop环境教程

作者:hangge | 2024-01-23 09:05
    随着大数据技术的不断发展,Hadoop 作为一个开源的分布式存储和计算框架,广泛应用于处理大规模数据。在开发和测试阶段,为了简化部署和管理,我们可以使用 Docker 容器来快速搭建 Hadoop 环境。下面我将介绍如何通过 Docker 容器轻松搭建和部署 Hadoop 环境。

1,拉取镜像

首先执行如下命令将镜像下载到本地:
docker pull sequenceiq/hadoop-docker:2.7.1

2,启动容器

镜像拉取后,我们执行如下命令启动 Hadoop 容器:
各端口作用:
  • -p 8088:8088:映射 Hadoop ResourceManager 8088 端口。ResourceManagerHadoop 集群中的资源管理器。
  • -p 9000:9000:映射 HadoopNameNode9000 端口。这是 Hadoop 分布式文件系统(HDFS)的主要节点。
  • -p 8040:8040:映射 Hadoop NodeManager 8040 端口。这是 Hadoop 集群中的节点管理器。
  • -p 8042:8042:映射 Hadoop NodeManager8042 端口。这是 Hadoop 集群中的节点管理器。
  • -p 49707:49707:映射 Hadoop DataNode 49707 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
  • -p 50010:50010:映射 Hadoop DataNode 50010 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
  • -p 50070:50070:映射 HadoopNameNode50070 端口。这是 Hadoop 分布式文件系统(HDFS)的 Web 界面。
  • -p 50075:50075:映射 Hadoop DataNode 50075 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
  • -p 50090:50090:映射 HadoopSecondary NameNode50090 端口。这是 Hadoop 分布式文件系统(HDFS)的辅助名称节点,用于定期合并 HDFS 的编辑日志。
docker run --name hadoop -it -d \
  -p 8088:8088 \
  -p 9000:9000 \
  -p 8040:8040 \
  -p 8042:8042 \
  -p 49707:49707 \
  -p 50010:50010 \
  -p 50070:50070 \
  -p 50075:50075 \
  -p 50090:50090 \
  sequenceiq/hadoop-docker:2.7.1 \
  /etc/bootstrap.sh -bash

3,查看是否启动成功

(1)使用浏览器访问 yarn 任务监控 web 页面,地址为 http://IP:8088,显示如下内容则说明启动成功。

(2)访问 NameNodeweb 页面,地址为 http://IP:50070,显示如下内容:

(3)访问 DataNodeweb 页面,地址为 http://IP:50075,显示如下内容:

4,使用测试

(1)首先执行如下命令进入容器:
docker exec -it hadoop bash

(2)接着进入 /usr/local/hadoop-2.7.1 目录:
cd /usr/local/hadoop-2.7.1

(3)然后执行如下命令运行一个内置的 MapReduce 样例程序:
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar grep input output 'dfs[a-z.]+'

(4)执行时会实时显示进度:

(5)运行完毕后执行如下命令可以查看输出结果:
bin/hdfs dfs -cat output/*

附:解决外部客户端无法写入HDFS文件内容问题

1,问题描述

(1)服务部署后,我们会发现在容器内部或者在容器所在的宿主服务器上,无论是创建 hdfs 文件夹还是上传文件都是正常的。但如果通过外部服务器进行访问操作时,可以创建文件夹,但是上传文件会报如下错误:
RemoteException: File /test/g1.png could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:1550)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getNewBlockTargets(FSNamesystem.java:3110)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:3034)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:723)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:492)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:616)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:969)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2049)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2045)
at java.security.AccessController.doPrivileged(Native Method)

(2)查看上传的文件,可以看到文件大小为0,内容都是为空,说明文件数据无法正常写入。

(3)即使设置了权限也是同样问题:
./bin/hdfs dfs -chmod 777 /

2,问题原因

(1)如果我们运行容器时不指定 --network,那么创建的容器都会挂到 bridge 网络上。bridge 网络的网关是 172.17.0.1,子网是 172.17.0.0/16docker 会自动从 172.17.0.0/16 中分配一个 IP 给容器。
(2)查看 Datanode 信息也可以发现,DatanodeIP172.17.0.3 这种地址。该地址只有容器内部,以及容器所在的宿主机能够访问到。外部客户端无法访问,自然也就无法写入数据。

3,解决办法1:使用 host 网络

(1)连接到 host 网络的容器共享 Docker host 网络栈,可以直接通过 hostip 地址来访问该容器。我们执行如下命令启动容器,使用 host 网络就不需要端口映射了:
docker run --name hadoop -it -d \
  --network=host \
  sequenceiq/hadoop-docker:2.7.1 \
  /etc/bootstrap.sh -bash

(2)接着进入该容器:
docker exec -it hadoop bash

(3)编辑 core-site.xml 文件:
vi /usr/local/hadoop-2.7.1/etc/hadoop/core-site.xml

(4)将IP地址改成宿主机的地址,否则访问 9000 端口时会被拒绝:
  <configuration>
      <property>
          <name>fs.defaultFS</name>
          <value>hdfs://192.168.60.9:9000</value>
      </property>
  </configuration>

(5)接着编辑 slaves 文件
vi /usr/local/hadoop-2.7.1/etc/hadoop/slaves
(6)将里面的 localhost 改成宿主机的IP地址,否则 DatanodeIP 会显示为 127.0.0.1,外网客户端仍然无法访问。
192.168.60.9

(7)进入 hadoopsbin 目录:
cd /usr/local/hadoop-2.7.1/sbin/

(8)执行如下命令停止所有服务:
./stop-all.sh

(9)待执行完毕后,执行如下命令启动服务:
./start-all.sh

(10)启动后查看 Datanode 信息,可以发现地址已经变成宿主机的 IP 了,这样外部客户端就可以正常上传文件了。

4,解决办法2:创建静态路由

(1)还有种更简单的方法,容器仍然使用 bridge 网络,也不需要修改 hadoop 的配置文件。我们只需要在需要访问 hdfs 的外部电脑上配置一个静态路由指向 172.17.X.X 网段即可。假设容器所在的宿主机 IP192.168.60.9
  • 外部设备如果是 Windows 系统,则执行如下命令:
route add 172.17.0.0 mask 255.255.0.0 192.168.60.9 -p

sudo route -n add -net 172.17.0.0/16 192.168.60.9

sudo ip route add 172.17.0.0/16 via 192.168.60.9

(2)静态路由添加后,该设备就可以正常访问 172.17.X.X 网段地址了,自然也就可以上传 hdfs 文件。
评论

全部评论(0)

回到顶部