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

<configuration>
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://hadoop0:9000</value>
        </property>
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/usr/local/hadoop/tmp</value>
        </property>
         <property>
                 <name>fs.trash.interval</name>
                 <value>1440</value>
        </property>
</configuration>

hdfs-site.xml

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
</configuration>

yarn-site.xml

<configuration>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
        <property> 
                <name>yarn.log-aggregation-enable</name> 
                <value>true</value> 
        </property>
        <property>
            <description>The hostname of the RM.</description>
            <name>yarn.resourcemanager.hostname</name>
            <value>hadoop0</value>
        </property>
</configuration>

mapred-site.xml (不存在則創建)

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>

**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

上述文件創建好之后,我都是丟在同一個目錄的,目錄結構如下:


Paste_Image.png

創建一個Dockerfile的軟鏈接

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

鏡像創建成功后,如圖:

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
Paste_Image.png

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、測試驗證:

Paste_Image.png
Paste_Image.png
Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容