利用docker部署Hadoop单节点环境

之前早就编译好了几个hadoop镜像,含2.4.1、2.6.0、2.7.0三个版本。但一直未能成功地部署好docker hadoop环境。这个周末终于能静下心来,做成这件小事。
网络上所流传的docker hadoop部署方式,大都是一个容器一个节点(即master或slave)。我这里采用的是一个容器一个服务的方式。
必须要强调,这只是第一步。多节点部署方式还待研究。

先从镜像服务器拉取我制作的hadoop镜像。我所编译的hadoop镜像的hadoop原生库为64位,jdk为openjdk-7-jdk,Dockerfile见这里。这次我使用的版本是2.6.0。
docker pull wencan/hadoop:2.6.0

创建本地配置文件目录,和数据目录
mkdir conf
mkdir data
拷贝hadoop etc/hadoop目录下的全部配置文件到conf目录下,配置几个关键项。如果本地没有hadoop包,可以创建一个hadoop容器,利用docker cp从容器拷贝出默认的配置文件。
主要配置可见这里。另外还需要需要的配置的为namenode的数据目录,和datanode的数据目录,这个可以参考这里

格式化namenode数据目录
这里必须使用默认的桥接网络,否则会出错
docker run –rm -it -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop -v $PWD/data:/data wencan/hadoop:2.6.0 hdfs namenode -format

运行namenode,使用宿主网络,后面相同
docker run -d –name hadoop_namenode -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop -v $PWD/data:/data –net host wencan/hadoop:2.6.0 hdfs namenode

运行datanode
docker run -d –name hadoop_data -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop -v $PWD/data:/data –net host wencan/hadoop:2.6.0 hdfs datanode

可以登陆http://localhost:50070查看,可以看到一个datanode节点。

运行resourcemanager
docker run -d –name hadoop_resourcemanager -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 yarn resourcemanager

运行nodemanager
docker run -d –name hadoop_nodemanager -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 yarn nodemanager

可以登陆http://localhost:8088查看,可以在nodes页面看到一个nodemanager节点

运行historyserver
docker run -d –name hadoop_historyserver -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 mapred historyserver

创建/input/wordcount目录,并将本地配置文件复制过去,作为稍后wordcount的输入文件
docker run –rm -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 /bin/bash -c ‘hdfs dfs -mkdir -p /input/wordcount && hdfs dfs -copyFromLocal /etc/hadoop/* /input/wordcount’

列出刚才复制到hdfs的文件。也可以在50070查看。
docker run –rm -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 hdfs dfs -ls /input/wordcount/

执行wordcount,输入目录为/input/wordcount,输出目录为/output/wordcount
docker run –rm -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar wordcount /input/wordcount /output/wordcount

输出mapreduce的计算结果
docker run –rm -e HADOOP_CONF_DIR=/etc/hadoop -v $PWD/conf/:/etc/hadoop –net host wencan/hadoop:2.6.0 hdfs dfs -cat /output/wordcount/*

参考:
Hadoop MapReduce Next Generation – Setting up a Single Node Cluster.
配置运行hadoop

配置运行hadoop

前面的。hadoop版本依然是2.4.1.

选择一个节点做主节点,运行hdfs的namenode、yarn的resourcemanager,以及jobhistoryserver。主节点的节点名称定为hadoop-master。
剩下的作为从节点,运行hdfs的datanode、yarn的nodemanager。每个从节点的节点名称定位hadoop-slave+编号。
“节点名称”这个词,好像是我发明的……

为每个节点创建hadoop用户。配置主节点的hadoop用户可以免密码登录到各个节点(包含自身)。

su – hadoop //切换到hadoop用户
sudo mkdir /opt/hadoop //创建hadoop主目录
cd /opt/hadoop //切换到hadoop主目录
tar xzvf */hadoop-2.4.1.tar.gz //解压缩hadoop包到当前目录,即hadoop主目录
ln -s hadoop-2.4.1 current //创建current符号链接到当前版本的hadoop目录

echo “export PATH=$PATH:/opt/hadoop/current/bin” | sudo tee /etc/profile.d/hadoop.sh //添加hadoop bin目录到PATH
sudo source /etc/profile //使刚才的修改立即生效

修改每个从节点的/etc/hostname,每个从节点的hostname改为hadoop-slave*。从节点的节点名称,就是主机名。

修改每个节点的/etc/hosts,将集群中所有节点的IP地址到主机名的映射添加到hosts,包含自身。

修改主节点的etc/hadoop/slaves,删除原始的localhost,将所有从节点的主机名添加进去,一行一个。

关闭每个节点的防火墙。实际运行环境不建议这么做。但在弄清楚hadoop各个程序监听的端口前,先这么做。

每个节点创建数据目录:
sudo mkdir /data //创建/data目录
sudo chmod o+wx /data //修改/data目录为其它目录可写可执行
sudo mkdir -p /data/hadoop //创建hadoop数据目录
sudo chown hadoop:hadoop /data/hadoop //修改hadoop数据目录为hadoop用户所有

每个节点创建日志目录:
sudo mkdir /var/log/hadoop
sudo mkown hadoop:hadoop /var/log/hadoop

修改每个节点的hadoop配置文件。配置文件都位于hadoop主目录的etc/hadoop下。

hadoop-env.sh:
export HADOOP_HOME=/opt/hadoop/current
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_LOG_DIR=/var/log/hadoop //大部分程序的日志目录
export JAVA_HOME=/usr/lib/jvm/default-java

mapred-env.sh:
export HADOOP_MAPRED_LOG_DIR=/var/log/hadoop //jobhistoryserver的日志目录

yarn-env.sh:
export YARN_LOG_DIR=/var/log/hadoop //yarn的日志目录

core-sites.xml:
fs.defaultFS: hdfs://hadoop-master:9000

hdfs-site.xml:
dfs.replication: 1 //数据副本数目。通常为3
dfs.namenode.name.dir: /data/hadoop/hdfs/name //namenode的数据存放目录(真实的本地目录)
dfs.datanode.data.dir: /data/hadoop/hdfs/data //datanode的数据存放目录(真实的本地目录)

mapred-site.xml:
mapreduce.framework.name: yarn

yarn-site.xml:
yarn.resourcemanager.hostname: hadoop-master
从节点yarn-site.xml:
yarn.nodemanager.aux-services: mapreduce_shuffle
yarn.nodemanager.hostname: hadoop-slave*
yarn.nodemanager.address: hadoop-slave*:19000

在默认配置中,很多主机地址为0.0.0.0,即监听所有地址。但程序也会把这个“0.0.0.0“发送给其它节点,然后其它节点向0.0.0.0发起连接……。所以,指定监听的主机地址为主机名/节点名称。
在默认配置中,部分监听端口为0,即随机取一个。但为了方便后面开防火墙端口,端口号0都改为指定的一个端口号。上面的19000就是我瞎取的。

主节点/etc/ssh/ssh_config中StrictHostKeyChecking建议设为no,免除每次连接到一个新的节点时,ssh都询问是否确认key fingerprint。

格式化名称空间:
hdfs namenode -format
开始hdfs和yarn:
sbin/start-sll.sh
开始jobhistoryserver:
sbin/mr-jobhistory-daemon.sh start historyserver

不知道有没有遗漏的地方……

编译Hadoop

写在前面的话:有话题就发一帖,证明这个BLOG是活的。

我安装hadoop,是为了支撑spark。spark当前最新稳定版为1.3.0,需要的hadoop版本为2.4.*。2.4.*最新版为2.4.1。
hadoop官网下载页面已经不提供2.4.1的下载链接。但可以在apache的存档站点找到2.4.1:http://archive.apache.org/dist/hadoop/core/
下载来的hadoop的原生库是32位的,而目前主流机器架构却是64位,我们需要自己手动从源码编译hadoop。

hadoop源码说明文件为的BUILDING.txt。根据说明文件,需要like-unix系统,jdk1.6+,maven 3.0+,Findbugs 1.3.9,protobuf 2.5.0,cmake 2.6+,以及网络连接。
根据我的经验,如果不需要构建文档,Findbugs可无。文档最好有,虽然源码包里的文档只是API文档。帮助文档还得是官方包里才有。但我们可以在这里找到2.4.1的帮助文档。
jdk最好采用Oracle版。Redhat系列下载rpm包,yum localinstall即可。debian系可以下载压缩包,然后借助JavaPackage,将压缩包转为deb包(如果是jdk 1.8,可能需要wheezy-backports版的JavaPackage)。无论哪个系列的发行版,都需要更改默认java软链接到Oracle jdk。如果是debian系,可以借助update-alternatives命令完成这件工作,具体的可见JavaPackage的wiki。安装好jdk后,还需配置JAVA_HOME——我是这么想的,但我编译hadoop时,JAVA_HOME是早已配置好的。执行:
echo ‘export JAVA_HOME=……’ > /etc/profile.d/java.sh
source /etc/profile
protobuf必须2.5.0,还不认2.6.*。我机器上的protobuf刚好2.6,只有下载2.5,重新编译覆盖安装。

protobuf的github页面为https://github.com/google/protobuf
编译安装protobuf,需要先安装automake,然后照官方说明,一步步执行即可:
./autogen.sh
./configure
make
make check
sudo make install
安装protobuf2.5.0后,执行protoc –version检测版本,报:protoc: error while loading shared libraries: libprotobuf.so.8。执行下面的即可解决:
sudo ldconfig
再执行protoc –version检测版本,输出2.5.0,再下一步。

根据protobuf上吃过的亏,Findbugs既然要求1.3.9,而不是1.3.9+,还是严格采用1.3.9好。Findbugs无需安装,解压,环境变量中指定FINDBUGS_HOME。因为Findbugs只用一回,就不配置持久全局环境变量了,直接执行FINDBUGS_HOME=Findbugs路径。也可以在稍候的mvn命令前加上FINDBUGS_HOME=Findbugs路径。

按照BUILDING.TXT,执行编译命令:
mvn package -Pdist,native,docs -DskipTests -Dtar
该命令将会编译产生dist文件(怎么翻译?)、原生库、文档,跳过测试,并将最终文件tar打包
这时会陷入长久的等待……

最后maven输出BUILD SUCCESS,表示你成功了;如果不幸输出BUILD FAILED,检查人品吧。
编译成功后,找到源码目录下的hadoop-dist/target/hadoop-2.4.1.tar.gz,我们需要的就是这个压缩文件。

PS:如果只是要64位的原生库,应该只编译原生库部分就可以了。