Docker - 通过容器搭建部署Hadoop环境教程
随着大数据技术的不断发展,Hadoop 作为一个开源的分布式存储和计算框架,广泛应用于处理大规模数据。在开发和测试阶段,为了简化部署和管理,我们可以使用 Docker 容器来快速搭建 Hadoop 环境。下面我将介绍如何通过 Docker 容器轻松搭建和部署 Hadoop 环境。
(2)接着进入 /usr/local/hadoop-2.7.1 目录:
(3)然后执行如下命令运行一个内置的 MapReduce 样例程序:
(4)执行时会实时显示进度:
(5)运行完毕后执行如下命令可以查看输出结果:
(2)查看上传的文件,可以看到文件大小为0,内容都是为空,说明文件数据无法正常写入。
(3)编辑 core-site.xml 文件:
(4)将IP地址改成宿主机的地址,否则访问 9000 端口时会被拒绝:
(5)接着编辑 slaves 文件
(6)将里面的 localhost 改成宿主机的IP地址,否则 Datanode 的 IP 会显示为 127.0.0.1,外网客户端仍然无法访问。
(7)进入 hadoop 的 sbin 目录:
(8)执行如下命令停止所有服务:
(9)待执行完毕后,执行如下命令启动服务:
(10)启动后查看 Datanode 信息,可以发现地址已经变成宿主机的 IP 了,这样外部客户端就可以正常上传文件了。
(1)还有种更简单的方法,容器仍然使用 bridge 网络,也不需要修改 hadoop 的配置文件。我们只需要在需要访问 hdfs 的外部电脑上配置一个静态路由指向 172.17.X.X 网段即可。假设容器所在的宿主机 IP 为 192.168.60.9
(2)静态路由添加后,该设备就可以正常访问 172.17.X.X 网段地址了,自然也就可以上传 hdfs 文件。
1,拉取镜像
首先执行如下命令将镜像下载到本地:
docker pull sequenceiq/hadoop-docker:2.7.1
2,启动容器
镜像拉取后,我们执行如下命令启动 Hadoop 容器:各端口作用:
- -p 8088:8088:映射 Hadoop ResourceManager 的 8088 端口。ResourceManager 是 Hadoop 集群中的资源管理器。
- -p 9000:9000:映射 Hadoop 的 NameNode 的 9000 端口。这是 Hadoop 分布式文件系统(HDFS)的主要节点。
- -p 8040:8040:映射 Hadoop NodeManager 的 8040 端口。这是 Hadoop 集群中的节点管理器。
- -p 8042:8042:映射 Hadoop NodeManager 的 8042 端口。这是 Hadoop 集群中的节点管理器。
- -p 49707:49707:映射 Hadoop DataNode 的 49707 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
- -p 50010:50010:映射 Hadoop DataNode 的 50010 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
- -p 50070:50070:映射 Hadoop 的 NameNode 的 50070 端口。这是 Hadoop 分布式文件系统(HDFS)的 Web 界面。
- -p 50075:50075:映射 Hadoop DataNode 的 50075 端口。这是 Hadoop 分布式文件系统(HDFS)中的数据节点。
- -p 50090:50090:映射 Hadoop 的 Secondary NameNode 的 50090 端口。这是 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)访问 NameNode 的 web 页面,地址为 http://IP:50070,显示如下内容:
(3)访问 DataNode 的 web 页面,地址为 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)执行时会实时显示进度:
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)即使设置了权限也是同样问题:
(2)接着进入该容器:
./bin/hdfs dfs -chmod 777 /
2,问题原因
(1)如果我们运行容器时不指定 --network,那么创建的容器都会挂到 bridge 网络上。bridge 网络的网关是 172.17.0.1,子网是 172.17.0.0/16。docker 会自动从 172.17.0.0/16 中分配一个 IP 给容器。
(2)查看 Datanode 信息也可以发现,Datanode 的 IP 为 172.17.0.3 这种地址。该地址只有容器内部,以及容器所在的宿主机能够访问到。外部客户端无法访问,自然也就无法写入数据。
3,解决办法1:使用 host 网络
(1)连接到 host 网络的容器共享 Docker host 网络栈,可以直接通过 host 的 ip 地址来访问该容器。我们执行如下命令启动容器,使用 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
192.168.60.9
(7)进入 hadoop 的 sbin 目录:
cd /usr/local/hadoop-2.7.1/sbin/
(8)执行如下命令停止所有服务:
./stop-all.sh
(9)待执行完毕后,执行如下命令启动服务:
./start-all.sh
(10)启动后查看 Datanode 信息,可以发现地址已经变成宿主机的 IP 了,这样外部客户端就可以正常上传文件了。
4,解决办法2:创建静态路由
外部设备如果是 Windows 系统,则执行如下命令:
route add 172.17.0.0 mask 255.255.0.0 192.168.60.9 -p
- 外部设备如果是 MacOS 系统,则执行如下命令:
sudo route -n add -net 172.17.0.0/16 192.168.60.9
- 外部设备如果是 linux 系统,则执行如下命令:
sudo ip route add 172.17.0.0/16 via 192.168.60.9
(2)静态路由添加后,该设备就可以正常访问 172.17.X.X 网段地址了,自然也就可以上传 hdfs 文件。