作者在服务器中成功手动搭建了 hadoop 集群,服务器系统是 centos 7.9,内核是 3.10.0-1127.el7.x86_64 。在搭建期间查了很多博客,但是很多博客中存在着问题,前前后后花了我大概一天多的时间,查资料,debug可以成功的运行了。在这里,我将我的安装总结一下,供需要的人进行参考。

参考文章:Docker中Hadoop集群搭建

一、安装docker

# 安装需要的软件包
yum install -y yum-utils
# 设置阿里云镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum安装包索引
yum makecache fast
# 安装Docker引擎
yum -y install docker-ce docker-ce-cli containerd.io
# 启动Docker
systemctl start docker
# 运行docker(查看是否安装成功)
docker version
docker run hello-world

二、拉取 centos 镜像

我安装的是 centos7。centos8 已经不提供后续支持。

docker pull daocloud.io/library/centos:7

三、配置固定 ip 的容器

创建的网络结构如下:

hostname

ip

cluster-master

172.18.0.2

cluster-slave1

172.18.0.3

cluster-slave2

172.18.0.4

cluster-slave3

172.18.0.5

1、创建固定 ip 的子网

docker network create --subnet=172.18.0.0/16 netgroup

2、创建固定 ip 的容器

-p 指定了端口号

# cluster-master
docker run -d --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name cluster-master -h cluster-master -p 18088:18088 -p 9870:9870 --net netgroup --ip 172.18.0.2 daocloud.io/library/centos:7 /usr/sbin/init
#cluster-slaves
docker run -d --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name cluster-slave1 -h cluster-slave1 --net netgroup --ip 172.18.0.3 daocloud.io/library/centos:7 /usr/sbin/init
docker run -d --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name cluster-slave2 -h cluster-slave2 --net netgroup --ip 172.18.0.4 daocloud.io/library/centos:7 /usr/sbin/init
docker run -d --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name cluster-slave3 -h cluster-slave3 --net netgroup --ip 172.18.0.5 daocloud.io/library/centos:7 /usr/sbin/init

四、配置容器主机的 openSSH

进入到不同主机的方法,退出时使用快捷键 ctrl+p+q,不要用 exit,否则会关闭容器。

docker exec -it 主机名 /bin/bash

1、yum 换源

在安装 ssh 过程中,如果没速度,可以先对要安装的主机 yum 进行换源。

yum -y install wget
mv /etc/yum.repos.d/CentOS-Base.repo  /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
yum makecache

2、配置 cluster-master 的 ssh,设置免密登录

首先,配置 cluster-master,并进行免密登录配置。

# 安装 OpenSSH
docker exec -it cluster-master /bin/bash
yum -y install openssh openssh-server openssh-clients
systemctl start sshd
# master 设置 ssh 登录自动添加 kown_hosts,配制免密登录
vi /etc/ssh/ssh_config # 注意:将原来的 StrictHostKeyChecking 的 ask 改为 no!
systemctl restart sshd

3、配置 cluster-slaves 的ssh

然后,配置 slave 的 ssh

docker exec -it cluster-slave1 /bin/bash
yum -y install openssh openssh-server openssh-clients
systemctl start sshd

这里需要注意的是,后续会使用 scp命令,需要输入从节点的密码。这里,我用了比较简单的方法,在配置从结点的时候,顺便为其添加统一的简单密码:

passwd root

五、cluster-master 公钥分发

进入主节点中,分发公钥

docker exec -it cluster-master /bin/bash
# 生成公钥
ssh-keygen -t rsa
# 将生成的公钥id_rsa.pub,重定向到文件authorized_keys
cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
# 修改权限
chmod 600 ~/.ssh/authorized_keys
# 用scp将公钥文件分发到所有的slaves主机上(重复下面操作)
ssh root@cluster-slave1 'mkdir ~/.ssh'
scp ~/.ssh/authorized_keys root@cluster-slave1:~/.ssh

六、Ansible 的安装和使用

1、安装 Ansible

进入到主节点中,安装 Ansible

docker exec -it cluster-master /bin/bash
yum -y install epel-release
yum -y install ansible

编辑 ansible 的 hosts 文件

vi /etc/ansible/hosts

编辑内容如下:

[cluster]
cluster-master
cluster-slave1
cluster-slave2
cluster-slave3

[master]
cluster-master

[slaves]
cluster-slave1
cluster-slave2
cluster-slave3

2、配置Docker容器host

/etc/hosts 文件中的内容在容器启动时被重写,所以需要在容器重启后自动获取集群的hosts,修改本地服务器的.bashrc文件

vi ~/.bashrc

添加信息

:>/etc/hosts
cat >>/etc/hosts<<EOF
127.0.0.1   localhost
172.18.0.2  cluster-master
172.18.0.3  cluster-slave1
172.18.0.4  cluster-slave2
172.18.0.5  cluster-slave3
EOF

重启.bashrc

source ~/.bashrc

3、用 Ansible 分发 .bashrc 至集群slave下

ansible cluster -m copy -a "src=~/.bashrc dest=~/"

七、配置 hadooop 运行环境

1、集群中搭建 jdk

ansible cluster -m yum -a "name=java-1.8.0-openjdk,java-1.8.0-openjdk-devel state=latest"

2、安装 hadooop

这里安装的是清华镜像里的hadoop-3.3.0,可以根据自己的需要去择清华镜像选择安装。这里我也选择将其安装到 /opt 目录下

wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.3.0/hadoop-3.3.0.tar.gz
tar -xzvf hadoop-3.3.0.tar.gz
ln -s hadoop-3.3.0 hadoop

3、配置环境变量

修改 .bashrc

vi ~/.bashrc

添加内容如下,注意根据自己的实际安装情况来,不要照搬:

# hadoop,选择自己的hadoop安装目录
export HADOOP_HOME=/opt/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

#java,选择自己的jdk安装目录
export JAVA_HOME=/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.el7_9.x86_64
export PATH=$HADOOP_HOME/bin:$PATH

重启

source ~/.bashrc

八、配置 hadoop 的运行配置文件

这里的修改,照搬就行。

cd $HADOOP_HOME/etc/hadoop/

1、修改 core-site.xml 文件

<configuration>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/tmp</value>
        <description>A base for other temporary directories.</description>
    </property>
    <!-- file system properties -->
    <property>
        <name>fs.default.name</name>
        <value>hdfs://cluster-master:9000</value>
    </property>
    <property>
    <name>fs.trash.interval</name>
        <value>4320</value>
    </property>
</configuration>

2、修改 hdfs-site.xml 文件

<configuration>
	<property>
	   <name>dfs.namenode.name.dir</name>
	   <value>/home/hadoop/tmp/dfs/name</value>
	 </property>
	 <property>
	   <name>dfs.datanode.data.dir</name>
	   <value>/home/hadoop/data</value>
	 </property>
	 <property>
	   <name>dfs.replication</name>
	   <value>3</value>
	 </property>
	 <property>
	   <name>dfs.webhdfs.enabled</name>
	   <value>true</value>
	 </property>
	 <property>
	   <name>dfs.permissions.superusergroup</name>
	   <value>staff</value>
	 </property>
	 <property>
	   <name>dfs.permissions.enabled</name>
	   <value>false</value>
	 </property>
 </configuration>

3、修改 mapred-site.xml 文件

<configuration>
	<property>
	  <name>mapreduce.framework.name</name>
	  <value>yarn</value>
	</property>
	<property>
	    <name>mapred.job.tracker</name>
	    <value>cluster-master:9001</value>
	</property>
	<property>
	  <name>mapreduce.jobtracker.http.address</name>
	  <value>cluster-master:50030</value>
	</property>
	<property>
	  <name>mapreduce.jobhisotry.address</name>
	  <value>cluster-master:10020</value>
	</property>
	<property>
	  <name>mapreduce.jobhistory.webapp.address</name>
	  <value>cluster-master:19888</value>
	</property>
	<property>
	  <name>mapreduce.jobhistory.done-dir</name>
	  <value>/jobhistory/done</value>
	</property>
	<property>
	  <name>mapreduce.intermediate-done-dir</name>
	  <value>/jobhisotry/done_intermediate</value>
	</property>
	<property>
	  <name>mapreduce.job.ubertask.enable</name>
	  <value>true</value>
	</property>
	<property>
	  <name>yarn.app.mapreduce.am.env</name>
	  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
	<property>
	  <name>mapreduce.map.env</name>
	  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
	<property>
	  <name>mapreduce.reduce.env</name>
	  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
</configuration>

4、修改 yarn-site.xml 文件

<configuration>
	 <property>
	   <name>yarn.resourcemanager.hostname</name>
	   <value>cluster-master</value>
	 </property>
	 <property>
	   <name>yarn.nodemanager.aux-services</name>
	   <value>mapreduce_shuffle</value>
	 </property>
	 <property>
	   <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
	   <value>org.apache.hadoop.mapred.ShuffleHandler</value>
	 </property>
	 <property>
	   <name>yarn.resourcemanager.address</name>
	   <value>cluster-master:18040</value>
	 </property>
	 <property>
	   <name>yarn.resourcemanager.scheduler.address</name>
	   <value>cluster-master:18030</value>
	 </property>
	 <property>
	   <name>yarn.resourcemanager.resource-tracker.address</name>
	   <value>cluster-master:18025</value>
	 </property> <property>
	   <name>yarn.resourcemanager.admin.address</name>
	   <value>cluster-master:18141</value>
	 </property>
	 <property>
	   <name>yarn.resourcemanager.webapp.address</name>
	   <value>cluster-master:18088</value>
	 </property>
	 <property>
	   <name>yarn.log-aggregation-enable</name>
	   <value>true</value>
	 </property>
	 <property>
	   <name>yarn.log-aggregation.retain-seconds</name>
	   <value>86400</value>
	 </property>
	<property>
	   <name>yarn.log-aggregation.retain-check-interval-seconds</name>
	   <value>86400</value>
	 </property>
	<property>
	   <name>yarn.nodemanager.remote-app-log-dir</name>
	   <value>/tmp/logs</value>
	 </property>
	<property>
	   <name>yarn.nodemanager.remote-app-log-dir-suffix</name>
	   <value>logs</value>
	 </property>
</configuration>

5、向slave分发 hadoop

打包 hadoop,返回 hadoop 安装目录 /opt,打包文件。

tar -cvf hadoop-dis.tar hadoop hadoop-3.3.0

创建为 hadoop-dis.yaml文件,并添加内容如下:

---
- hosts: cluster
  tasks:
    - name: copy .bashrc to slaves
      copy: src=~/.bashrc dest=~/
      notify:
        - exec source
    - name: copy hadoop-dis.tar to slaves
      unarchive: src=/opt/hadoop-dis.tar dest=/opt

  handlers:
    - name: exec source
      shell: source ~/.bashrc

使用 ansible-playbook 分发 .bashrchadoop-dis.tar 至 slave 主机。

ansible-playbook hadoop-dis.yaml

九、Hadoop 启动和常见的问题

在启动集群时,我遇到了下面两个问题,先把问题和解决问题的方法列在下面,供读者参考。

问题1:Attempting to operate on hdfs namenode as root

这是由于用 root 用户来操作集群产生的问题,需要在 $HADOOP_HOME/etc/hadoop/hadoop-env.sh,添加内容:

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

问题2:ERROR: Cannot set priority of datanode process

这是由于在修改hadoop运行配置文件时,<configuration></configuration>设置错误导致的。这个根据错误信息定位产生错误的文件,小心粘贴。

启动 hadoop 集群

在解决了上述问题后,就可以启动集群了

cd $HADOOP_HOME/sbin
# 格式化namenode
hadoop namenode -format
# 启动集群
./start-all.sh

jps 可以看到运行进程信息,也可以远程进行访问。

http://ip地址:端口号/ # ip是你的主机(服务器)的ip,端口号设置的是18088