Docker搭建hadoop分布式集群
一、环境部署包准备
1、Centos 7版本的操作系统
2、下载最新的jdk-8u131-linux-x64.tar.gz
3、下载hadoop2.7.3,hadoop-2.7.3.tar.gz
4、准备3台宿主机,支持ssh连接。
注:IP地址为生产实际地址
IP | 主机名 | 虚拟机内存分配 | 节点类型 |
---|---|---|---|
192.168.0.149 | hadoop0 | 2G | NameNode |
192.168.0.150 | hadoop1 | 1G | DateNode |
192.168.0.151 | hadoop2 | 1G | DateNode |
注意:由于容器需要启动SSHD服务,这时候如果宿主机也开启了SSHD服务,这样就会出现端口冲突,所以需要将宿主机SSh的默认端口改掉。
vi /etc/ssh/sshd_config 里面Port端口更改。
Port 24
#AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::
重启systemctl restart sshd
5、修改hosts映射地址(在三台计算机上分别执行)
vi changhost.sh
#!/bin/sh
\cp -f /etc/hosts /etc/hosts.temp
echo > /etc/hosts.temp
cat >> /etc/hosts.temp << EOF
192.168.0.149 hadoop0
192.168.0.150 hadoop1
192.168.0.151 hadoop2
EOF
\cp -f /etc/hosts.temp /etc/hosts
执行命令: sh changhost.sh
6、主机名修改(在三台计算机上分别执行如下命令),对应的主机名请参考第4点的主机名
[root@localhost /]#hostname hadoop0
[root@localhost /]su -l
7、 关闭防火墙(在三台计算机上分别执行如下命令)
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
8、关闭SELINUX
setenforce 0(立刻生效,不需要重启操作系统)
修改/etc/selinux/config文件中的SELINUX=disabled ,然后重启系统生效
9、重启系统(reboot -h)
二、Docker安装和部署
三、CentOS 7 中使用NTP进行时间同步
IP | 主机名 | 节点类型 |
---|---|---|
192.168.0.149 | hadoop0 | ntp服务端 |
192.168.0.150 | hadoop1 | ntp客户端 |
192.168.0.151 | hadoop2 | ntp客户端 |
_>注意:先查看时间区是不是在Asia/Shanghai,如果不是请使用以下命令在三台机器中执行:
cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
提示是否覆盖,输入Y回车,_
1、在服务端安装ntp服务
- 使用rpm检查ntp包是否安装
[root@hadoop0 /]# rpm -q ntp
- 如果已经安装则略过此步,否则使用yum进行安装,并设置系统开机自动启动并启动服务
[root@hadoop0 /]# yum -y install ntp
[root@hadoop0 /]# systemctl enable ntpd
[root@hadoop0 /]# systemctl start ntpd
2、设置ntp服务端配置信息
- 相关的配置说明地址
- vi /etc/ntp.conf
在文件最后加入。如下内容
#配置网关与子网码
restrict 192.168.0.1 mask 255.255.255.0 nomodify notrap
#使用本地时间
# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available.
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 1
找到以下的server内容并注释
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
- 修改完成后重启ntpd服务:systemctl restart ntpd
- 使用ntpq -p 查看网络中的NTP服务器,同时显示客户端和每个服务器的关系
- 使用ntpstat 命令查看时间同步状态,这个一般需要5-10分钟后才能成功连接和同步。所以,服务器启动后需要稍等下:
刚启动的时候,一般是:
# ntpstat
unsynchronised
time server re-starting
polling server every 8 s
3、设置ntp客户端
- 定时同步ntp服务器的时间,分别在其他两台客户端上执行如下命令:
# 在客户端只要安装ntpdate 就OK了
[root@hadoop1 /]# yum install -y ntpdate
[root@hadoop1 /]# crontab -e
#新增如下参数,每晚1:00同步
00 01 * * * /usr/sbin/ntpdate 192.168.0.149
#重启
[root@hadoop1 /]# systemctl restart crond
三、创建haddoop基础镜像
1、ssh其中一台登录主机
2、创建centos-sshd-jdk-hadoop镜像,这里提供编写好的一份Dockerfile,可直接下载使用。
注意:先把创建镜像的相关文档放到与Dockerfile文档同一个目录
# 这里是注释
# 设置继承自哪个镜像
FROM centos
# 下面是一些创建者的基本信息
MAINTAINER birdben(529784162@qq.com)
# 注意这里要更改系统的时区设置,因为在 web 应用中经常会用到时区这个系统变量,默认的 CentOS会让你的应用程序发生不可思议的效果哦
ENV DEBIAN_FRONTEND noninteractive
#更新源
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
COPY CentOS7-Base-163.repo /etc/yum.repos.d/
#RUN wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
RUN yum clean all
RUN yum makecache
#ssh server等必备软件
RUN yum install -y openssh-server net-tools
RUN mkdir -p /var/run/sshd
# 将sshd的UsePAM参数设置成no
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#安装openssh-clients witch
RUN yum install -y openssh-clients which
# 添加测试用户admin,密码123456,并且将此用户添加到sudoers里
RUN echo "root:123456" | 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
#jdk
COPY jdk-8u121-linux-x64.tar.gz /usr/local/
WORKDIR /usr/local/src/
RUN tar -xzvf /usr/local/jdk-8u121-linux-x64.tar.gz -C /usr/local
#hadoop
COPY hadoop-2.7.3.tar.gz /usr/local
WORKDIR /usr/local
RUN tar -xzvf /usr/local/hadoop-2.7.3.tar.gz -C /usr/local
#设置JDK环境变量
ENV JAVA_HOME=/usr/local/jdk1.8.0_121
ENV HADOOP_HOME=/usr/local/hadoop-2.7.3
ENV PATH=${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:${PATH}
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#RUN echo "export JAVA_HOME=/usr/local/jdk1.8.0_121" >> /etc/profile
#RUN echo "export HADOOP_HOME=/usr/local/hadoop-2.7.3" >> /etc/profile
#RUN echo '"export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH"' >> /etc/profile
#RUN echo "export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar" >> /etc/profile
#RUN source /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk1.8.0_121" > /etc/profile.d/java_home.sh
RUN echo "export HADOOP_HOME=/usr/local/hadoop-2.7.3" > /etc/profile.d/hadoop_hame.sh
RUN echo "export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin" > /etc/profile.d/env_path.sh
RUN echo $PATH
RUN java -version
RUN hadoop version
#容器需要开放SSH 22端口
EXPOSE 22
#set ENV
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
CMD ["/usr/sbin/sshd", "-D"]
3、创建镜像文件
- 先把Dokerfile导入其中一台到指定的目录下(这里是:hadoop0主机下/opt/dockerfile),并执行如下命令:
docker build -t centos-sshd-jdk-hadoop . (注意最后一个.)
四、镜像同步与hadoop容器启动
1、镜像文件的同步
- 在其中一台生成镜像文件,并同步到其他两台的机器上。有如下两个方法操作:
- 使用是save与load的命令。
- 使用私有仓库(registry)
1、使用save与import进行镜像的操作
1、在hadoop0主机上使用docker save 命令保存成tar归档文件
root@hadoop0 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-sshd-jdk-hadoop latest 95d579d8a6bb 54 seconds ago 2.265 GB
docker.io/centos latest 36540f359ca3 2 weeks ago 192.5 MB
[root@hadoop0 dockerfile]# docker export -o centos-sshd-jdk-hadoop.tar centos-sshd-jdk-hadoop
[root@hadoop0 dockerfile]# ll
total 2614324
-rw-r--r-- 1 root root 1572 May 18 2015 CentOS7-Base-163.repo
-rw-r--r-- 1 root root 2661 Jul 21 15:29 Dockerfile
-rw-r--r-- 1 root root 214092195 Jul 17 14:36 hadoop-2.7.3.tar.gz
-rw------- 1 root root 2279717888 Jul 21 17:29 centos-sshd-jdk-hadoop.tar
-rw-r--r-- 1 root root 183246769 Jul 18 10:30 jdk-8u121-linux-x64.tar.gz
2、在其他两台主机上使用docker import归档文件中创建镜像
* 先把tar文件上传到主机指定的目录下,这里是在/opt/dockerfile/
[root@hadoop1 dockerfile]# docker import centos-sshd-jdk-hadoop.tar centos-sshd-jdk-hadoop
sha256:95d579d8a6bba46f1a2a57f2f98b3733f93c965bc369d213227bf4504f177ecd
[root@hadoop1 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-sshd-jdk-hadoop latest 95d579d8a6bb 54 seconds ago 2.265 GB
docker.io/centos latest 36540f359ca3 2 weeks ago 192.5 MB
2、使用registry进行镜像的操作
1、使用docker registry私有仓库(使用的是hadoop1做registry服务端)
[root@hadoop1 dockerfile]# docker pull registry:2
[root@hadoop1 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/registry 2 751f286bc25e 4 days ago 33.19 MB
[root@hadoop1 dockerfile]# docker run -d -p 4000:5000 --restart=always --name registry registry:2
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0acae83f9d0f registry:2 "/entrypoint.sh /etc/" 20 hours ago Up 17 hours 0.0.0.0:4000->5000/tcp registry
2、上传镜像到仓库
- 客户端添加私有仓库地址
[root@hadoop0 dockerfile]# vi /etc/sysconfig/docker
#添加这一行
ADD_REGISTRY='--add-registry 192.168.0.179:5000'
- 把镜像打tag
[root@hadoop0 ~]# docker tag centos-sshd-jdk-hadoop 192.168.0.150:4000/hadoop
- 把tag上传到私有仓库中
[root@hadoop0 ~]# docker push 192.168.0.150:4000/hadoop
[root@hadoop0 ~]# curl -X GET http://192.168.0.150:4000/v2/_catalog
{"repositories":["hadoop"]}
[root@hadoop0 ~]# curl -X GET http://192.168.0.150:4000/v2/hadoop/tags/list
{"name":"hadoop","tags":["latest"]}
说明push到私有仓库成功。
- 从私有仓库到本地
#删除本地的tag镜像
[root@hadoop0 ~]# docker rmi 192.168.0.150:4000/hadoop
Untagged: 192.168.0.150:4000/hadoop:latest
Untagged: 192.168.0.150:4000/hadoop@sha256:dce28c5d0b892e3503fd9d99a2a111af4c3fac2d489a5d182b88bdc131ecd6ff
#查询镜像是否存在
[root@hadoop0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hadoop-test-proflie latest e911f3725c98 20 hours ago 2.308 GB
centos-sshd-jdk-hadoop-namenode latest 3754892eaf2a 23 hours ago 2.31 GB
centos-sshd-jdk-hadoop latest d88b9d11efeb 3 days ago 2.308 GB
docker.io/centos latest 36540f359ca3 2 weeks ago 192.5 MB
#pull到本地
[root@hadoop0 ~]# docker pull 192.168.0.150:4000/hadoop
Using default tag: latest
Trying to pull repository 192.168.0.150:4000/hadoop ...
latest: Pulling from 192.168.0.150:4000/hadoop
Digest: sha256:dce28c5d0b892e3503fd9d99a2a111af4c3fac2d489a5d182b88bdc131ecd6ff
#查询镜像是否存在
[root@hadoop0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hadoop-test-proflie latest e911f3725c98 20 hours ago 2.308 GB
192.168.0.150:4000/hadoop latest 3754892eaf2a 23 hours ago 2.31 GB
centos-sshd-jdk-hadoop-namenode latest 3754892eaf2a 23 hours ago 2.31 GB
centos-sshd-jdk-hadoop latest d88b9d11efeb 3 days ago 2.308 GB
docker.io/centos latest 36540f359ca3 2 weeks ago 192.5 MB
2、启动hadoop容器
1、启动docker容器(分别在三个机器执行如下命令)
[root@hadoop0 /]# docker run --net=host --name hadoop_console -v /etc/localtime:/etc/localtime -v /opt/hadoop/data:/usr/local/hadoop-2.7.3/data/ -v /opt/hadoop/logs/:/usr/local/hadoop-2.7.3/logs/ -d 192.168.0.150:4000/hadoop
第一个 -v :把宿主机的时间挂载给容器,使时间一样
第二个 -v :把宿主机的data目录挂载给容器的hadoop的data目录中
第三个 -v :把宿主机的logs目录挂载给容器的hadoop的logs目录中
--net :使用宿主机的host
2、查看docker容器进程(分别在三个机器执行如下命令)
[root@hadoop0 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3795c38ce92c centos-sshd-jdk-hadoop "/usr/sbin/sshd -D" 7 seconds ago Up 6 seconds hadoop_console
五、ssh免密操作
1、进入hadoop0
docker exec -it hadoop0 /bin/bash
cd ~
mkdir .ssh(这个文件已经存在 没有必要创建)
cd .ssh
ssh-keygen -t rsa(一直按回车即可)
ssh-copy-id -i hadoop0(密码root)
ssh-copy-id -i hadoop1
ssh-copy-id -i hadoop2
2、进入hadoop1
docker exec -it hadoop1 /bin/bash
cd ~
cd .ssh
ssh-keygen -t rsa(一直按回车即可)
ssh-copy-id -i hadoop1
3、进入hadoop2
docker exec -it hadoop2 /bin/bash
cd ~
cd .ssh
ssh-keygen -t rsa(一直按回车即可)
ssh-copy-id -i hadoop2
4、分别进入hadoop0用ssh root@hadoop1,不需要输入密码,直接进入
六、修改hadoop0的hadoop配置文件
cd /usr/local/hadoop-2.7.3/etc/hadoop/
以下配置文件都在这个目录下
1、hadoop-env.sh
export JAVA_HOME=/usr/local/jdk1.8.0_121
文件内原为这么配置的 export JAVA_HOME=${JAVA_HOME} 我认为不要修改,但是结果告诉我不行
2、core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop0:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop-2.7.3/data/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
</configuration>
3、hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop0:9001</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/${hadoop.tmp.dir}/dfs/name</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>
4、yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>hadoop0:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>hadoop0:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>hadoop0:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>hadoop0:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>hadoop0:8088</value>
</property>
</configuration>
5、修改文件名:cp mapred-site.xml.template mapred-site.xml
vi mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop0:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop0:19888</value>
</property>
</configuration>
6、修改hadoop0中hadoop的一个配置文件etc/hadoop/slaves
删除原来的所有内容,修改为如下
hadoop1
hadoop2
7、格式化(并拷贝,配置文件)
进入到/usr/local/hadoop-2.7.3目录下
执行格式化命令
bin/hdfs namenode -format
8、拷贝到其他两台机器
scp -rq /usr/local/hadoop-2.7.3/etc/hadoop hadoop1:/usr/local/hadoop-2.7.3/etc/
scp -rq /usr/local/hadoop-2.7.3/etc/hadoop hadoop2:/usr/local/hadoop-2.7.3/etc/
9、在namenode上启动hadoop服务(这里的namenode是149这台主机)
sbin/start-all.sh
七、检查集群是否正常
1、查看进程
Hadoop0上需要有这几个进程
[root@hadoop0 hadoop]# jps
4643 Jps
4073 NameNode
4216 SecondaryNameNode
4381 ResourceManager
Hadoop1上需要有这几个进程
[root@hadoop1 hadoop]# jps
715 NodeManager
849 Jps
645 DataNode
Hadoop2上需要有这几个进程
[root@hadoop2 hadoop]# jps
456 NodeManager
589 Jps
388 DataNode
连接 http://[主机IP]:50070/ 查看在线的DataNode
2、使用程序验证集群服务
vi a.txt
hello you
hello me
hdfs dfs -put a.txt /
cd /usr/local/hadoop-2.7.3/share/hadoop/mapreduce
hadoop jar hadoop-mapreduce-examples-2.7.3.jar wordcount /a.txt /out
hdfs dfs -text /out/part-r-00000
八、新加一个datanode节点
IP | 主机名 | 虚拟机内存分配 | 节点类型 |
---|---|---|---|
192.168.0.165 | hadoop3 | 1G | DateNode |
1、安装好基础环境(ssh,host,docker,ntp客户端)
2、使用docker pull 从私有创建中下载镜像
[root@hadoop0 ~]# docker pull 192.168.0.150:4000/hadoop
Using default tag: latest
Trying to pull repository 192.168.0.150:4000/hadoop ...
latest: Pulling from 192.168.0.150:4000/hadoop
Digest: sha256:dce28c5d0b892e3503fd9d99a2a111af4c3fac2d489a5d182b88bdc131ecd6ff
#查询镜像是否存在
[root@hadoop0 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.0.150:4000/hadoop latest 3754892eaf2a 23 hours ago 2.31 GB
3、启动docker容器(192.168.0.165)
[root@hadoop1 dockerfile]# docker run --net=host --name hadoop_console -v /etc/localtime:/etc/localtime -v /opt/hadoop/data:/usr/local/hadoop-2.7.3/data/ -v /opt/hadoop/logs/:/usr/local/hadoop-2.7.3/logs/ -d 192.168.0.150:4000/hadoop
95cb37f298610671de93e8ebee05323ae50234ba1749dc49c85d3185e75ba704
注意: import的镜像在run时要加上COMMAND 的值
[root@hadoop1 dockerfile]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95cb37f29861 192.168.0.150:4000/hadoop "/usr/sbin/sshd -D" 11 seconds ago Up 10 seconds
4、进入hadoop0 修改
#在宿主机上修改hosts
vi /ets/hosts
#新增165的配置
192.168.0.165 hadoop3
#进入hadoop容器中修改
docker exec -it hadoop0 /bin/bash
vi /ets/hosts
#新增165的配置
192.168.0.165 hadoop3
cd ~
mkdir .ssh(这个文件已经存在 没有必要创建)
cd .ssh
ssh-copy-id -i hadoop3
cd /usr/local/hadoop-2.7.3/etc/hadoop/
vi slaves
#新增新的hostname
hadoop3
5、拷贝到新的机器 scp -rq /usr/local/hadoop-2.7.3/etc/hadoop hadoop3:/usr/local/hadoop-2.7.3/etc/
6、启动hadoop03(165)
1、 在新节点上启动服务
[root@hadoop3 /]# hadoop-daemon.sh start datanode
starting datanode, logging to /usr/local/hadoop-2.7.3/logs/hadoop-root-datanode-hadoop2.out
[root@hadoop3 hadoop-2.7.3]# sh sbin/yarn-daemon.sh start nodemanager
starting nodemanager, logging to /usr/local/hadoop-2.7.3/logs/yarn-root-nodemanager-hadoop3.out
2、 HDFS均衡block
这个会非常耗时
1) 如果不balance,那么cluster会把新的数据都存放在新的node上,这样会降低mapred的工作效率
2) 设置平衡阈值,默认是10%,值越低各节点越平衡,但消耗时间也更长
[root@hadoop3 hadoop-2.7.3]# sh sbin/start-balancer.sh -threshold 5
3)设置balance的带宽,默认只有1M/s
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>1048576</value>
</property>
九、重启容器后需要重新设置的项
1、单个datanode的启动加入到集群中
[root@hadoop2 /]# hadoop-daemon.sh start datanode
starting datanode, logging to /usr/local/hadoop-2.7.3/logs/hadoop-root-datanode-hadoop2.out
[root@hadoop2 hadoop-2.7.3]# sh sbin/yarn-daemon.sh start nodemanager
starting nodemanager, logging to /usr/local/hadoop-2.7.3/logs/yarn-root-nodemanager-hadoop3.out