目的:
利用docker容器构建3台虚拟主机,一台为管理节点两台为数据节点以此来构建hadoop伪集群,三台虚拟主机之间使用SSH进行连接
因此整体思路为安装Centos镜像,为镜像安装SSH,Hadoop,Java,根据镜像创建三个容器,这样每个容器其实就相当于一台运行着Centos的主机,选择一个为管理节点配置Hadoop
文章很长,请耐心阅读
操作系统Centos7,安装时最好选择安装GNOME桌面
下载Docker CE[1]
删除旧版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
配置Docker仓库
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装Docker CE
$ sudo yum install docker-ce
启动Docker CE
$ sudo systemctl enable docker
$ sudo systemctl start docker
为Docker创建新的工作组
$ sudo usermod -aG docker $USER
切换至root用户
$ ru test
测试Docker是否正常工作
$ docker run hello-world
$ docker images
拉取Centos镜像
$ docker pull centos
$ docker images
拉取的镜像
为拉取的镜像安装SSH
$ mkdir DockerFile
$ cd DockerFile
$ mkdir CentOS7_SSH
$ cd CentOS7_SSH
$ vi Dockerfile
Dockerfile
FROM centos
MAINTAINER codingstory
#安装SSH
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN yum install -y openssh-clients
#添加用户名为hadoop用户密码为hadoop的用户
RUN useradd hadoop
RUN echo "hadoop:hadoop" | chpasswd
#提升hadoop用户的权限
RUN echo "hadoop ALL=(ALL) ALL" >> /etc/sudoers
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
#开启SSH服务端口为22
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
安装
$ docker build -t centos7_ssh .
安装过程中会出现红色警报可以不用管
构建网络环境
$ docker network create -d bridge hadoop-network
$ docker network ls
测试SSH功能
建立一个容器(此时的容器已经有操作系统和网路了相当于一台虚拟主机了)
$ docker run --network=hadoop-network -itd --name=hadoop_ssh
centos7_ssh
$ docker network inspect hadoop-network
测试SSH连接
$ ssh 172.18.0.2 -l hadoop
解释一下命令的含义
172.18.0.2
代表了我们刚刚创建的容器(虚拟主机)的IP地址,hadoop
代表了我们要连接到容器(虚拟主机)中名为hadoop
的用户
SSH连接测试成功后,要为镜像安装Hadoop和Java
进入到DockerFile文件夹中建立一个新的文件夹
$ mkdir CentOS7_Hadoop
$ cd CentOS7_Hadoop
$ vi Dockerfile
Dockerfile
FROM centos7_ssh
#解压下载的java文件
ADD jdk-8u191-linux-x64.tar.gz /usr/local/
# 更改文件夹名字
RUN mv /usr/local/jdk1.8.0_191 /usr/local/jdk1.8
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $JAVA_HOME/bin:$PATH
# 解压下载的Hadoop文件
ADD hadoop-2.8.5.tar.gz /usr/local
RUN mv /usr/local/hadoop-2.8.5 /usr/local/hadoop
ENV HADOOP_HOME /usr/local/hadoop
ENV PATH $HADOOP_HOME/bin:$PATH
RUN yum install -y which sudo
进入Hadoop官网下载hadoop-2.8.5.tar.gz的二进制文件
进入Java官网下载Linux x64 jdk-8u191-linux-x64.tar.gz
把下载的文件放入DockerFile/CentOS7_Hadoop
目录下
执行Dockerfile
$ docker build -t centos7_hadoop .
$ docker images
现在我们的镜像已经安装了SSH、Hadoop、Java
再根据镜像创建三个容器
$ docker run --network hadoop-network --name hadoop1 --hostname hadoop1 -d -P centos7_hadoop
$ docker run --network hadoop-network --name hadoop2 --hostname hadoop2 -d -P centos7_hadoop
$ docker run --network hadoop-network --name hadoop0 --hostname hadoop0 -d -P -p 50070:50070 -p 8088:8088 centos7_hadoop
对于hadoop0来说,我们希望它能作为管理员,因此把它的端口50070
和8088
映射到我们自己的主机中
打开三个命令行分别进入三个容器
$ docker exec -it hadoop0 /bin/bash
$ docker exec -it hadoop1 /bin/bash
$ docker exec -it hadoop2 /bin/bash
在三个命令行中全部切换为hadoop用户
$ su hadoop
都生成用于SSH连接的公钥和私钥
$ ssh-keygen
都将自己的公钥复制给其它容器
$ ssh-copy-id -i ~/.ssh/id_rsa -p 22 hadoop@hadoop0
$ ssh-copy-id -i ~/.ssh/id_rsa -p 22 hadoop@hadoop1
$ ssh-copy-id -i ~/.ssh/id_rsa -p 22 hadoop@hadoop2
这样我们就可以不需要密码就可以访问其它容器,假设我们现在处于hadoop0容器
我们可以使用
$ ssh -p '22' 'hadoop@hadoop2'
访问hadoop2容器
访问之前
访问之后
下面进行Hadoop的配置
进入hadoop0容器
$ sudo vi /usr/local/hadoop/etc/hadoop/core-site.xml
将下面的代码configuration
部分复制到core-site.xml文件中的configuration
部分
fs.default.name
hdfs://hadoop0:9000
io.file.buffer.size
131072
hadoop.tmp.dir
file:/home/${user.name}/tmp
A base for other temporary directories.
hadoop.proxyuser.hduser.hosts
*
hadoop.proxyuser.hduser.groups
*
fs.trash.interval
1440
$ sudo vi /usr/local/hadoop/etc/hadoop/hdfs-site.xml
将下面的代码configuration
部分复制到hdfs-site.xml文件中的configuration
部分
dfs.namenode.name.dir
file:/usr/local/hadoop/hdfs/name
dfs.datanode.data.dir
file:/usr/local/hadoop/hdfs/data
dfs.replication
2
dfs.namenode.secondary.http-address
hadoop0:9001
dfs.webhdfs.enabled
true
切入到hadoop目录下
$ cd /usr/local/hadoop/etc/hadoop
$ sudo cp mapred-site.xml.template mapred-site.xml
将下面的代码configuration
部分复制到mapred-site.xml文件中的configuration
部分
mapreduce.framework.name
yarn
mapreduce.jobhistory.address
hadoop0:10020
mapreduce.jobhistory.webapp.address
hadoop0:19888
$ sudo vi yarn-site.xml
将下面的代码configuration
部分复制到yarn-site.xml文件中的configuration
部分
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.nodemanager.auxservices.mapreduce.shuffle.class
org.apache.hadoop.mapred.ShuffleHandler
yarn.resourcemanager.address
hadoop0:8032
yarn.resourcemanager.scheduler.address
hadoop0:8030
yarn.resourcemanager.resource-tracker.address
hadoop0:8031
yarn.resourcemanager.admin.address
hadoop0:8033
yarn.resourcemanager.webapp.address
hadoop0:8088
$ sudo vi slaves
删除原来的内容加入
hadoop1
hadoop2
查看JAVA_HOME路径
$ echo $JAVA_HOME
$ sudo vi hadoop-env.sh
找到
export JAVA_HOME=${JAVA_HOME}
将其更改为JAVA_HOME路径,例如
export JAVA_HOME=/usr/local/jdk1.8
现在将修改过后的hadoop文件发送给hadoop1和hadoop2容器[2]
$ sudo scp -r /usr/local/hadoop hadoop@hadoop1:/tmp
$ sudo scp -r /usr/local/hadoop hadoop@hadoop1:/tmp
进入hadoop1和hadoop2删除原来的hadoop文件
$ rm -rf /usr/local/hadoop
从/tmp
文件夹将hadoop复制到/usr/local/hadoop
里面
$ sudo cp -rf /tmp/hadoop /usr/local/hadoop
三个容器中都要增加Hadoop环境变量
$ sudo vi ~/.bashrc
增加环境变量
export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin
执行以下命令,使刚添加的环境变量有效
$ source ~/.bashrc
这样配置就完成了
下面开始启动Hadoop
进入hadoop0容器
$ hdfs namenode -format -force
会出现下面这样的结果
三个容器中都要提升hadoop对hadoop文件夹权限[3]:
$ sudo chown -R hadoop /usr/local/hadoop/
之后在hadoop0容器中运行
$ start-dfs.sh
$ start-yarn.sh
$ mr-jobhistory-daemon.sh start historyserver
检查启动状态
$ hadoop dfsadmin -report
打开http://localhost:50070和http://localhost:8088查看是否正确
创建一个文件试试
$ hdfs dfs -mkdir -p /home/hadoop/input
至此就完成了Docker+Hadoop构建的伪集群
-
Docker在Centos上安装--官方文档 ↩
-
ssh使用scp: /目录: Permission denied ↩
-
“Permission denied” errors whe starting a single node cluster in Hadoop ↩