背景
一台centos ip :172.xx.xxx
一台mac ip :172.xx.xxx
一台 windows ip :172.xx.xxx
网络为公司内网环境,因为开始没法申请机器,需要在三个不同环境下搭建一个hadoop集群,跑一些测试数据,因为hadoop要求各个机器的目录一致,我尝试使用docker搭建,因为docker之前没有用过,我没有使用Dockerfile,使用第三方镜像,并使用端口映射实现跨主机,具体搭建过程如下:
1.获取镜像创建Master
- 获取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/kaibb/hadoop
下载完成后使用 docker images可以查看到这个镜像
注:这个镜像为我们设置好了ssh,和要下载的组件,自己之前下载centos,然后在ssh互信上遇到很多问题,就改成了这种已经设置好ssh的镜像
- 创建容器
docker run -i -t --name Master -h Master registry.cn-hangzhou.aliyuncs.com/kaibb/hadoop /bin/bash
通过上述的命令行创建了Master,此时在容器外使用下面命令
docker inspect Master
可以看到该容器对外暴露的所有端口号如下:
因为要跨主机,端口的暴露是不够的,我又对端口号做了映射,为防止宿主机的22端口其他服务需要使用就把容器的22端口映射到22222,具体操作删除原来的容器,然后重新run一个
docker rm Master
docker run -i -t --name Master -h Master -p 19888:19888 -p 2122:2122 -p 22:22222 -p 49707:49707 -p 50010:50010 -p 8030-8033:8030-8033 -p 8040:8040 -p 8042:8042 -p 8088:8088 -p 50020:50020 -p 50070:50070 -p 50075:50075 -p 50095:50095 registry.cn-hangzhou.aliyuncs.com/kaibb/hadoop /bin/bash
- 配置环境
这个镜像java和hadoop的内容都存放在了/opt/tools目录下使用下面命令行可以确认是否正常:
java --version
hadoop --version
接下来我们来修改/etc/hosts
vi /etc/hosts
添加以下内容
172.XX.XXX1 Slave1 // 另外一台主机ip
172.XX.XXX2 Master // 当前宿主机ip
source /etc/hosts
接下来配置hadoop
1>hadoop-env.sh:修改有关java的环境
cd /opt/tools/hadoop/etc/hadoop
vi hadoop -env.sh
修改默认的ssh端口号
export HADOOP_SSH_OPTS="-p 22222"
2>core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://Master:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/hadoop/tmp</value>
</property>
</configuration>
3>hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/hadoop/data</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/hadoop/name</value>
</property>
</configuration>
4>mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
5>yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.address</name>
<value>Master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>Master:8030</value> </property> <property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>Master:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>Master:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>Master:8088</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
</configuration>
5>slaves
在slaves文件里设置改成如下:
Slave1
- 运行ssh
/etc/init.d/ssh start
2.制作镜像,创建Slave1
退出容器然后导出镜像:
docker export -o master.tar Master
让另外一台主机和当前的宿主机互信后远程拷贝到另外一台主机上
scp master.tar 另外一台主机名@ip:/opt/tools/
然后导入镜像
docker import master.tar newImages
然后docker images 就可以看到我们自己导入的本地镜像,然后我们run一个Slave1:
docker run -i -t --name Slave1 -h Slave1 -p 19888:19888 -p 2122:2122 -p 22:22222 -p 49707:49707 -p 50010:50010 -p 8030-8033:8030-8033 -p 8040:8040 -p 8042:8042 -p 8088:8088 -p 50020:50020 -p 50070:50070 -p 50075:50075 -p 50095:50095 newImages /bin/bash
3.ssh互信
进入容
器后同样编辑/etc/hosts文件,同上面一样设置。并运行ssh
/etc/init.d/ssh start
设置完毕后进行互信。
4.启动hadoop集群
互信成功后回到Master容器内
cd /opt/tools/hadoop/sbin
hadoop namenode -format // 格式化
格式化正常后,启动集群
./start-all.sh
jps后slave1正常,namenode不正常。
5.分析问题
nameNode无法启动,是因为集群启动的时候会互信的时候会ssh 自己的ip 22222端口,但是其实是应该 ssh Master 22222端口,由于hadoop集群的启动是从master上读取的,主从节点要保持一致,所以最终没有启动成功。
6. 结语
写这个的时候,其实和我搭建有段时间了,最后出现的问题大概是这个样子,因为自己对虚拟网桥啥的不是很懂,当时没有选择那个方法,以为端口映射会更简单,其实整个过程下来还是挺复杂的,如果有看到的高人,希望指点这种端口映射是否可以实现跨主机的集群,或者其他方法有什么比较简单的。
这里附上这个镜像的单机集群搭建流程,经测试没有问题。