Docker搭建hadoop开发测试集群

由于项目需要,最近在研究阿里云的E-Mapreduce,出于开发需要,想搭建一个hadoop集群,
关于Hadoop集群的配置,网上有很多这方面的文章,本文不再赘述。
本文主要讲述通过docker自动化完成一个hadoop的步骤。

本文目标:

  1. 熟悉Docker相关操作
  2. 熟悉hadoop集群的安装配置
  3. 熟练使用Shell去创建自动化脚本初始化hadoop容器,自动互信等

本文使用相关软件版本

  • Centos 7
  • Docker 1.11.2

相关步骤简介:

  1. 构建基础镜像
  2. 配置相应hadoop配置
  3. 基于基础镜像以及配置完全的hadoop2.X.tar.gz构建hadoop镜像
  4. 创建自动化配置脚本,初始化hadoop容器
  5. 提交一个文件到hdfs,运行wordcount的样例Mapreduce

Note:

本文最终会启动三个容器,hadoop0,hadoop1,hadoop2,
设置静态IP,100.10.0.100,100.10.0.101,100.10.0.102,
其中hadoop0是master,hadoop1和2是slave

一、构建基础镜像

基于一个已经存在的centos,由于hadoop集群在启动的时候,需要依赖一些软件,比如建立互信需要ssh相关,在自动化配置的时候需要自动输入expect等。

详细的Dockfile如下:

# 选择一个已有的os镜像作为基础
FROM centos

# 镜像的作者
MAINTAINER xingchuan.qxc

# 安装openssh-server和sudo软件包,并且将sshd的UsePAM参数设置成no
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#安装openssh-clients
RUN yum install -y openssh-clients
# 安装网络相关命令
RUN yum install -y net-tools
# 安装编辑器
RUN yum install -y vim
# 安装which
RUN yum install -y which
# 安装expect
RUN yum install -y expect

# 添加测试用户root,密码root,并且将此用户添加到sudoers里
RUN echo "root:root" | chpasswd
RUN echo "root   ALL=(ALL)   ALL" >> /etc/sudoers
# 下面这两句比较特殊,在centos6上必须要有,否则创建出来的容器sshd不能登录
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

运行 docker build -t "xingchuan/centos" .

docker build 相关的命令,自行google,这里是通过该命令构建一个叫xingchuan/centos的镜像

二、 基于基础镜像,构建Jdk8的镜像

在Oracle官网下载jdk8,我今天下载的是jdk-8u121-linux-x64.tar.gz

构建JDK8的镜像Dockfile如下:

FROM xingchuan/centos
MAINTAINER xingchuan.qxc
ADD jdk-8u121-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_121
ENV PATH $JAVA_HOME/bin:$PATH
RUN echo "export JAVA_HOME=/usr/local/jdk1.8.0_121" >> /etc/profile
RUN echo "export CLASSPATH=.:$JAVA_HOME/lib" >> /etc/profile
RUN echo "export PATH=$JAVA_HOME/bin:$PATH" >> /etc/profile

Note:

Dockerfile的ADD命令,含有解压功能,详细用法可以自行查找相关资料
这个地方我使用ENV发现JDK的环境变量没有自动给配置上(具体原因回头详查),
所以在最后加了三个RUN,手动配置了一下JDK环境变量

运行 docker build -t "xingchuan/jdk8" . 完成JDK8镜像的构建

三、 构建hadoop环境的镜像,基于Jdk8镜像

3.1、基础配置

在hadooop.apache.org下载hadoop,我这里使用的是hadoop-2.7.3.tar.gz,下载后,我做了如下配置。
解压后,修改相关配置

hadoop-env.sh

export JAVA_HOME=/usr/local/jdk1.7

core-site.xml


        
                fs.defaultFS
                hdfs://hadoop0:9000
        
        
                hadoop.tmp.dir
                /usr/local/hadoop/tmp
        
         
                 fs.trash.interval
                 1440
        

hdfs-site.xml


    
        dfs.replication
        1
    
    
        dfs.permissions
        false
    

yarn-site.xml


        
                yarn.nodemanager.aux-services
                mapreduce_shuffle
        
         
                yarn.log-aggregation-enable 
                true 
        
        
            The hostname of the RM.
            yarn.resourcemanager.hostname
            hadoop0
        

mapred-site.xml (不存在则创建)


    
        mapreduce.framework.name
        yarn
    

**slaves **

hadoop1
hadoop2

配置完成后,重新打包成hadoop-2.7.3.tar.gz

3.2 创建互信自动脚本

3.2.1 genSSH.exp

目的:

在容器启动的时候,hadoop三个节点之间需要互信,本文目标就是全部自动化完成,
所以必须借助expect软件(该软件Centos默认没有安装,执行 yum install -y expect可以安装调试)

脚本如下:

#!/usr/bin/expect
set timeout 10
set username [lindex $argv 0]
set password [lindex $argv 1]
set hostname [lindex $argv 2]
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $username@$hostname
expect {
            #first connect, no public key in ~/.ssh/known_hosts
            "Are you sure you want to continue connecting (yes/no)?" {
            send "yes\r"
            expect "password:"
                send "$password\r"
            }
            #already has public key in ~/.ssh/known_hosts
            "password:" {
                send "$password\r"
            }
            "Now try logging into the machine" {
                #it has authorized, do nothing!
            }
        }
expect eof

3.2.2 startHadoop.exp

目的

容器初始化成功之后,一切配置都ok了,自动启动hadoop集群

脚本如下:

#!/usr/bin/expect
set timeout 30
spawn /usr/local/hadoop/sbin/start-all.sh
expect "Are you sure you want to continue connecting (yes/no)?" {
    send "yes\r"
    }

Note:expect其他高级用法,自行Google

3.3 构建Hadoop镜像

Dockerfile如下:

FROM xingchuan/jdk8

MAINTAINER xingchuan.qxc

ADD hadoop-2.7.3.tar.gz /usr/local
ADD genSSH.exp /root
ADD startHadoop.exp /root
RUN chmod +x /root/genSSH.exp
RUN chmod +x /root/startHadoop.exp
RUN mv /usr/local/hadoop-2.7.3 /usr/local/hadoop
ENV HADOOP_HOME /usr/local/hadoop
ENV PATH $HADOOP_HOME/bin:$PATH
RUN echo "export HADOOP_HOME=/usr/local/hadoop" >> /etc/profile
RUN echo "export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH" >> /etc/profile

上述文件创建好之后,我都是丢在同一个目录的,目录结构如下:


Docker搭建hadoop开发测试集群_第1张图片
Paste_Image.png

创建一个Dockerfile的软链接

运行docker build -t "xingchuan/hadoop:2.7" .

镜像创建成功后,如图:

Docker搭建hadoop开发测试集群_第2张图片
Paste_Image.png

4、构建自动初始化脚本

创建一个startHadoop.sh,脚本内容如下:

#/bin/bash
# hadoop的三个容器名字
hadoop_arr=("hadoop0" "hadoop1" "hadoop2");
# hadoop三个容器对应的ip地址
hadoop_ip=("100.10.0.100" "100.10.0.101" "100.10.0.102");
for((m=0;m<${#hadoop_arr[*]};m++));
do
docker run -tid --name ${hadoop_arr[$m]} -h ${hadoop_arr[m]} --add-host hadoop0:100.10.0.100 --add-host hadoop1:100.10.0.101 --add-host hadoop2:100.10.0.102 --net=HZ --ip=${hadoop_ip[m]} xingchuan/hadoop:2.7
done;
# 创建ssh公钥私钥
for((m=0;m<${#hadoop_arr[*]};m++));
do
docker exec ${hadoop_arr[m]} rm -rf ~/.ssh;
docker exec ${hadoop_arr[m]} mkdir -p ~/.ssh;
docker exec ${hadoop_arr[m]} ssh-keygen -t rsa -f ~/.ssh/id_rsa -P "";
done;

# 建立互信
for((m=0;m<${#hadoop_arr[*]};m++));
do
  for((n=0;n<${#hadoop_arr[*]};n++));
  do
    docker exec ${hadoop_arr[m]} expect -f /root/genSSH.exp root root ${hadoop_arr[n]};
  done;
done;

# format hdfs
docker exec hadoop0 hdfs namenode -format
# 启动hadoop集群
docker exec hadoop0 /root/startHadoop.exp

Note:

--add-host 可以在容器启动的时候自动配置/etc/hosts

在宿主机给startHadoop.sh加上可执行权限

chmod +x startHadoop.sh

运行后,容器启动成功且互信关系创建完成


Paste_Image.png
Docker搭建hadoop开发测试集群_第3张图片
Paste_Image.png

Docker搭建hadoop开发测试集群_第4张图片
Paste_Image.png

检查相应进程是否都启动完成:

hadoop0

[root@hadoop0 ~]# jps
1120 Jps
403 NameNode
596 SecondaryNameNode
756 ResourceManager

hadoop1

[root@hadoop0 ~]# ssh hadoop1
Last login: Sat Feb  4 12:38:35 2017 from hadoop0
[root@hadoop1 ~]# jps
354 NodeManager
547 Jps
252 DataNode

hadoop2

[root@hadoop1 ~]# ssh hadoop2
Last login: Sat Feb  4 12:38:39 2017 from hadoop1
[root@hadoop2 ~]# jps
357 NodeManager
550 Jps
255 DataNode

5、测试验证:

Docker搭建hadoop开发测试集群_第5张图片
Paste_Image.png
Docker搭建hadoop开发测试集群_第6张图片
Paste_Image.png
Docker搭建hadoop开发测试集群_第7张图片
Paste_Image.png

你可能感兴趣的:(Docker搭建hadoop开发测试集群)