





















学习Hadoop集群环境搭建是Hadoop入门必经之路。搭建分布式集群通常有两个办法:
那么,问题来了!
提到虚拟化,Docker最近很是火热!不妨拿来在本地做虚拟化,搭建Hadoop的伪分布式集群环境。虽然有点大材小用,但是学习学习,练练手也是极好的。
文章比较长,建议先倒杯水,听我慢慢到来……
先说一下我的思路吧:
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
我使用的是Ubuntu14.04,命令如下:
$ sudo apt-get install apt-transport-https
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
其余系统或其他版本,请参考这里。
docker images:列出所有镜像(images)docker ps:列出正在运行的(容器)containersdocker pull ubuntu:下载镜像docker run -i -t ubuntu /bin/bash:运行ubuntu镜像docker commit 3a09b2588478 ubuntu:mynewimage:提交你的变更,并且把容器保存成Tag为mynewimage的新的ubuntu镜像.(注意,这里提交只是提交到本地仓库,类似git)其他常用命令,参考这里。
在Ubuntu下,在执行Docker时,每次都要输入sudo,同时输入密码,这里把当前用户执行权限添加到相应的docker用户组里面。
# 添加一个新的docker用户组
sudo groupadd docker
# 添加当前用户到docker用户组里,注意这里的king为ubuntu登录用户名
sudo gpasswd -a king docker
# 重启Docker后台监护进程
sudo service docker restart
# 重启之后,尝试一下,是否生效
docker version
#若还未生效,则系统重启,则生效
sudo reboot
docker pull ubuntu:14.04
这条命令的作用是从Docker仓库中获取ubuntu的镜像,参考这里。
下载完成以后,使用docker images,可以列出所有本地的镜像:
king@king:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 5ba9dab47459 4 weeks ago 188.3 MB
ubuntu 14.04.1 5ba9dab47459 4 weeks ago 188.3 MB
ubuntu latest 5ba9dab47459 4 weeks ago 188.3 MB
ubuntu trusty 5ba9dab47459 4 weeks ago 188.3 MB
下面,我们准备以ubuntu镜像作为基准镜像,构建我们的Hadoop运行环境镜像。
先使用命令如下命令启动容器:
docker run -ti ubuntu
注意:我们在不指定Tag的情况下,默认选择Tag为latest的镜像启动容器。 指定Tag启动命令为:
docker run -ti ubuntu:14.04
另外,每次容器启动的时候需要指定一个命令,容器启动后便会执行这个命令。例如执行下面的命令:
king@king:~$ docker run ubuntu /bin/echo 'Hello world'
Hello world
king@king:~$
可以看到,容器启动了马上又退出了,因为容器之做了一件事情:就是打印Hello world,打印完了,自然就退出了。
如果你想做多件事情,可以自己写一个shell脚本,把你要的操作写入进去,然后在run后面指定这个脚本路径。
我们刚刚的docker run -ti ubuntu命令中没有指定执行程序,Docker默认执行/bin/bash。
其他启动参数,大家可以自己在网上查,这里不再陈述了。好了我们回到刚刚docker run -ti ubuntu启动的容器,可以看到容器几乎瞬间就启动起来了,比虚拟机不知快了多少倍!!
king@king:~$ docker run -ti ubuntu
root@009fe5728aba:/#
容器启动起来了,接下来就是安装Java、Hadoop及相关配置了。
依次执行如下命令:
sudo apt-get install software-properties-common python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sodu apt-get update
apt-get install oracle-java7-installer
java -version
注意:
apt-get install oracle-java7-installer为apt-get install oracle-java6-installer另外,大家可以将装好java的镜像保存为一个副本,他日可以在此基础上构建其他镜像。命令如下:
root@122a2cecdd14:~# exit
docker commit -m "java install" 122a2cecdd14 ubuntu:java
上面命令中122a2cecdd14为当前容器的ID, ubuntu:java是为新的镜像指定一个标识,ubuntu为仓库名,java是Tag。
如何获取容器ID:
@后面的那一串字符。这个方法只在容器启动时没有指定hostname时才能用。docker ps列出所有运行的容器,在命令结果中查看渐渐切入正题了O(∩_∩)O~
使用刚刚已经安装了Java的容器镜像启动:
docker run -ti ubuntu:java
启动成功了,我们开始安装Hadoop。这里,我们直接使用wget下载安装文件。
sudo apt-get install -y wget
root@8ef06706f88d:cd ~
root@8ef06706f88d:~# mkdir soft
root@8ef06706f88d:~
注意:这里我们安装的Hadoop版本是2.6.0,如果需要其他版本,请在这里找到链接地址后修改命令即可。
修改~/.bashrc文件。在文件末尾加入下面配置信息:
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export HADOOP_HOME=/root/soft/apache/hadoop/hadoop-2.6.0
export HADOOP_CONFIG_HOME=$HADOOP_HOME/etc/hadoop
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
注意:我们使用apt-get安装java,不知道java装在什么地方的话可以使用下面的命令查看:
root@8ef06706f88d:~# update-alternatives --config java
There is only one alternative in link group java (providing /usr/bin/java): /usr/lib/jvm/java-7-oracle/jre/bin/java
Nothing to configure.
root@8ef06706f88d:~
下面,我们开始修改Hadoop的配置文件。主要配置core-site.xml、hdfs-site.xml、mapred-site.xml这三个文件。
开始配置之前,执行下面命令:
root@8ef06706f88d:~# cd $HADOOP_HOME/
root@8ef06706f88d:~/soft/apache/hadoop/hadoop-2.6.0
这里创建了三个目录,后续配置的时候会用到:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
注意:
hadoop.tmp.dir配置项值即为此前命令中创建的临时目录路径。fs.default.name配置为hdfs://master:9000,指向的是一个Master节点的主机(后续我们做集群配置的时候,自然会配置这个节点,先写在这里)使用命令nano hdfs-site.xml编辑hdfs-site.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
注意:
dfs.replication配置为2。dfs.namenode.name.dir和dfs.datanode.data.dir分别配置为之前创建的NameNode和DataNode的目录路径Hadoop安装文件中提供了一个mapred-site.xml.template,所以我们之前使用了命令cp mapred-site.xml.template mapred-site.xml,创建了一个mapred-site.xml文件。下面使用命令nano mapred-site.xml编辑这个文件:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
这里只有一个配置项mapred.job.tracker,我们指向master节点机器。
使用命令.nano hadoop-env.sh,修改如下配置:
# The java implementation to use.
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
这是很重要的一步,执行命令hadoop namenode -format
搭建集群环境,自然少不了使用SSH。这可以实现无密码访问,访问集群机器的时候很方便。
root@8ef06706f88d:~# sudo apt-get install ssh
SSH装好了以后,由于我们是Docker容器中运行,所以SSH服务不会自动启动。需要我们在容器启动以后,手动通过/usr/sbin/sshd 手动打开SSH服务。未免有些麻烦,为了方便,我们把这个命令加入到~/.bashrc文件中。通过nano ~/.bashrc编辑.bashrc文件(nano没有安装的自行安装,也可用vi),在文件后追加下面内容:
#autorun
/usr/sbin/sshd
root@8ef06706f88d:/# cd ~/
root@8ef06706f88d:~# ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa
root@8ef06706f88d:~
注意: 这里,我的思路是直接将密钥生成后写入镜像,免得在买个容器里面再单独生成一次,还要相互拷贝公钥,比较麻烦。当然这只是学习使用,实际操作时,应该不会这么搞,因为这样所有容器的密钥都是一样的!!
这里我们将安装好Hadoop的镜像保存为一个副本。
root@8ef06706f88d:~# exit
king@king:~$ docker commit -m "hadoop install" 8ef06706f88d ubuntu:hadoop
重点来了!
按照 hadoop 集群的基本要求,其 中一个是 master 结点,主要是用于运行 hadoop 程序中的 namenode、secondorynamenode 和 jobtracker(新版本名字变了) 任务。用外两个结点均为 slave 结点,其中一个是用于冗余目的,如果没有冗 余,就不能称之为 hadoop 了,所以模拟 hadoop 集群至少要有 3 个结点。
前面已经将Hadoop的镜像构建好了,下面就是使用这个镜像搭建Master节点和Slave节点了:
| 节点 | hostname | ip | 用途 | Docker启动脚本 |
| Master | master | 10.0.0.5 |
namenode secondaryNamenode jobTracker |
docker run -ti -h master ubuntu:hadoop |
| Slave | slave1 | 10.0.0.6 |
datanode taskTracker |
docker run -ti -h slave1 ubuntu:hadoop |
| Slave | slave2 | 10.0.0.7 |
datanode taskTracker |
docker run -ti -h slave2 ubuntu:hadoop |
回顾一下,Docker启动容器使用的是run命令:
docker run -ti ubuntu:hadoop
这里有几个问题:
commit命令写入镜像我们搭建集群环境的时候,需要指定节点的hostname,以及配置hosts。hostname可以使用Docker run命令的h参数直接指定。但hosts解析有点麻烦,虽然可以使用run的--link参数配置hosts解析信息,但我们搭建集群时要求两台机器互相能够ping通,其中一个容器没有启动,那么ip不知道,所以--link参数对于我们的这个场景不实用。要解决这个问题,大概需要专门搭建一个域名解析服务,即使用--dns参数(参考这里)。
我们这里只为学习,就不整那么复杂了,就手动修改hosts吧。只不过每次都得改,我Docker知识浅薄,一时还没有解决这个问题。相信肯定有更好的办法。如果有高人能指定一下,感激不尽!!
docker run -ti -h master ubuntu:hadoop
docker run -ti -h slave1 ubuntu:hadoop
docker run -ti -h slave2 ubuntu:hadoop
ifconfig命令获取各节点ip。环境不同获取的ip可能不一样,例如我本机获取的ip如下: 使用sudo nano /etc/hosts命令将如下配置写入各节点的hosts文件,注意修改ip地址:
10.0.0.5 master
10.0.0.6 slave1
10.0.0.7 slave2
下面我们来配置哪些节点是slave。在较老的Hadoop版本中有一个masters文件和一个slaves文件,但新版本中只有slaves文件了。
在master节点容器中执行如下命令:
root@master:~# cd $HADOOP_CONFIG_HOME/
root@master:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop
将如下slave节点的hostname信息写入该文件:
slave1
slave2
在master节点上执行start-all.sh命令,启动Hadoop。
激动人心的一刻……

如果看到如下信息,则说明启动成功了:
root@master:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop# start-all.sh
This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
Starting namenodes on [master]
master: starting namenode, logging to /root/soft/apache/hadoop/hadoop-2.6.0/logs/hadoop-root-namenode-master.out
slave1: starting datanode, logging to /root/soft/apache/hadoop/hadoop-2.6.0/logs/hadoop-root-datanode-slave1.out
slave2: starting datanode, logging to /root/soft/apache/hadoop/hadoop-2.6.0/logs/hadoop-root-datanode-slave2.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /root/soft/apache/hadoop/hadoop-2.6.0/logs/hadoop-root-secondarynamenode-master.out
starting yarn daemons
starting resourcemanager, logging to /root/soft/apache/hadoop/hadoop-2.6.0/logs/yarn
在个节点上执行jps命令,结果如下:
root@master:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop# jps
1223 Jps
992 SecondaryNameNode
813 NameNode
1140 ResourceManager
root@slave1:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop# jps
258 NodeManager
352 Jps
159 DataNode
root@slave2:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop# jps
371 Jps
277 NodeManager
178 DataNode
下面,我们在master节点上通过命令hdfs dfsadmin -report查看DataNode是否正常启动:
root@master:~/soft/apache/hadoop/hadoop-2.6.0/etc/hadoop# hdfs dfsadmin -report
Configured Capacity: 167782006784 (156.26 GB)
Present Capacity: 58979344384 (54.93 GB)
DFS Remaining: 58979295232 (54.93 GB)
DFS Used: 49152 (48 KB)
DFS Used%: 0.00%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0
-------------------------------------------------
Live datanodes (2):
Name: 10.0.0.7:50010 (slave2)
Hostname: slave2
Decommission Status : Normal
Configured Capacity: 83891003392 (78.13 GB)
DFS Used: 24576 (24 KB)
Non DFS Used: 54401331200 (50.67 GB)
DFS Remaining: 29489647616 (27.46 GB)
DFS Used%: 0.00%
DFS Remaining%: 35.15%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Sat Feb 28 07:27:05 UTC 2015
Name: 10.0.0.6:50010 (slave1)
Hostname: slave1
Decommission Status : Normal
Configured Capacity: 83891003392 (78.13 GB)
DFS Used: 24576 (24 KB)
Non DFS Used: 54401331200 (50.67 GB)
DFS Remaining: 29489647616 (27.46 GB)
DFS Used%: 0.00%
DFS Remaining%: 35.15%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Sat Feb 28 07:27:05 UTC 2015
还可以通过Web页面看到查看DataNode和NameNode的状态:http://10.0.0.5:50070/ (由于我宿主机器上没有配置master的hosts解析,所以只能用ip地址访问,大家将ip改为各自的master节点容器的ip即可):

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。