一口气带你手把手实现Hadoop集群docker部署
既然你都搜docker了,我就默认你已经掌握docker的安装以及docker的基本使用方式了。
1、集群构建前准备工作
#构建docker网络,固定hadoop-docker容器ip
docker network create --driver bridge --subnet 172.16.10.0/24 hadoop-net
#解析
--driver bridge:这指定了网络的驱动类型。在 Docker 中,bridge 驱动创建了一个桥接网络,它会将容器连接到一个虚拟的网络接口上,使得容器之间以及容器与外部网络之间可以进行通信
--subnet 172.16.10.0/24:这指定了网络的子网。子网 172.16.10.0/24 表示网络中可用的 IP 地址范围是 172.16.10.0 到 172.16.10.255。这个范围内的 IP 地址将由 Docker 动态分配给连接到这个网络上的容器。
hadoop-net:这是你为新创建的网络指定的名称。你可以使用这个名称来引用网络,例如在运行容器时将其附加到网络。
2、构建出第一个hadoop-docker
2.1 构建Linux+Java运行环境
#1)首先拉取Centos
docker pull centos
#2)创建一个Centos容器——以主节点为例
docker run --privileged=true --name=hadoop001 --network=hadoop-net --ip=172.16.10.10 -p 1001:9870 -p 1002:8020 -dit hadoop-docker /sbin/init
#解析
--privileged=true 提供了额外的权限,使得容器内的某些特殊功能可以正常工作。
--name=hadoop001 给容器指定了一个名称 hadoop001。
--network=hadoop-net 将容器连接到 hadoop-net 这个自定义网络。
--ip=172.16.10.10 为容器指定了一个固定的 IP 地址 172.16.10.10。
-p 1001:9870 将容器的 9870 端口映射到宿主机的 1001 端口,可以直接在自己的主机通过此接口访问图形化界面。
-dit 表示交互式且后台运行,少了 -it 容器会自动停止
hadoop-docker 是容器使用的镜像名称。
/sbin/init 是容器启动时执行的命令。
上传jdk+hadoop资源文件
#将 jdk 和 hadoop 从主机复制到该容器中
docker cp <jdk路径> <容器id>:<容器路径>
docker cp <hadoop路径> <容器id>:<容器路径>
我选用的版本分别是:
2.2 配置环境变量,保证能运行Java和hadoop相关命令
在 /etc/profile.d/ 下创建文件 mydev.sh,注意:这是在容器中的操作
# 在/etc/profile.d目录下创建mydex.sh
vim /etc/profile.d/mydex.sh
由于docker的centos镜像用于轻量级构建,此时可能会报错xx:command not found
这时就需要我们安装相关软件包,我使用的是yum软件包管理命令行工具
使用之前需要配置国内镜像和更新,否则会报错
yum换源与更新操作:
cd /etc/yum.repos.d/
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
yum clean all && yum makecache
yum update -y
依次输入以上命令之后,我们的yum就可以正常使用了
此时,若没有vim,我们就可以使用命令:
yum install vim
下载vim编辑器
写入mydev.sh文件
# Java
export JAVA_HOME=<jdk在容器的路径>
export PATH=$PATH:$JAVA_HOME/bin
# Hadoop
export HADOOP_HOME=<hadoop在容器的路径>
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
# Constant
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
注意:jdk所在容器路径和hadoop所在容器的路径需要与docker cp命令对应
# 第一第二个是两个环境,最后一个是一些常量,在启动集群的时候,还要用到这些常量,否则可能启动失败
#最后执行使配置文件生效
source /etc/profile
此时,如果修改hadoop的相关配置即可实现伪分布式部署
伪分布式部署
1、配置core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
2、配置hadoop-env.sh
将export JAVA_HOME=${JAVA_HOME}中的${JAVA_HOME}替换为具体路径,这里为export JAVA_HOME={你的jdk路径}
3、配置hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
4、配置mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
5、配置yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
6、格式化namenode
hdfs namenode -format
7、启动HDFS
start-dfs.sh
8、启动YARN
start-yarn.sh
9、查看相关进程是否都启动
jps
#如有以下5个进程,说明启动成功。
#DataNode
#NodeManager
#NameNode
#SecondaryNameNode
#ResourceManager
全分布式部署
我们需要让各个容器产生联系,才能构成集群,但默认情况下,容器并不能被其他容器直接通过 ssh 访问,所以这里需要配置
3、配置允许外界通过ssh连接
#1) 首先需要设置密码(输入以下命令,回车设置密码即可)
passwd root
#大概率会提示没有该命令,就得下载它,然后再设置就好了
yum install passwd
#2) 然后下载 ssh,以下三步(安装了服务端和客户端)
yum install openssh
yum install openssh-server
yum install openssh-clients
#3) 然后检查配置文件,查看以下两个配置是否一样(默认应该都是这样的)
vim /etc/ssh/sshd_config
# PermitRootLogin yes
# PasswordAuthentication yes
#这两个配置允许外网通过 ssh 连接该服务器(容器)
#4) 如果发现不是这样,就修改它,同时需要重启 ssh 是指生效
service sshd restart
#同样该命令可能不存在,就下载它
yum install initscripts
我们可以通过一下操作测试容器能否被外使用ssh连接
#1) 首先在容器内,使用 ifconfig 查看 IP 地址
ifconfig
#没有这个命令的话,就下载他[doge]
yum install net-tools
#2) 在服务器本机中,通过 ssh 访问该 IP 地址尝试连接
ssh <IP>
#然后要求输入密码,就是上面我们已经设置了的密码
4、构建hadoop-docker镜像,用于从节点构建
将该容器打包成镜像,再由该镜像创建出多个容器
#1) 创建镜像
docker commit hadoop001 hadoop-docker
#2) 由该进项克隆多个容器模拟集群(这里以三台服务器的集群为例)
docker run --privileged=true --name=hadoop002 --network=hadoop-net --ip=172.16.10.11 -p 1002:8088t hadoop-docker /sbin/init
docker run --privileged=true --name=hadoop003 --network=hadoop-net --ip=172.16.10.12 -p 1004:9868 -dit hadoop-docker /sbin/init
这样就成功地为每一个容器固定好 IP 地址了,接下来就可以在容器内配置映射了
#1) 在每一台容器中,修改 hosts 文件
vim /etc/hosts
比如说我的,就在文件中增加:
172.16.10.10 hadoop001
172.16.10.11 hadoop002
172.16.10.12 hadoop003
#2) 配置完毕后,我们就可以直接通过名字轻松连接各个容器了,如:
ssh hadoop003
5、为各个容器配置免密登录(集群部署重点)
启动集群的时候,如果没有免密登录,会失败
在 hadoop001 中,可以使用 ssh-key-gen
生成密钥,分为公钥和私钥,私钥保密,公钥可以给别人
然后如果将 hadoop001 的公钥拷贝给 hadoop002,通过命令拷贝,该公钥会保存在 hadoop002 中的 Authorized_keys 中
往后 hadoop001 想要连接 hadoop002,就可以直接通过公钥连接,无需密码
所以我们可以知道,免密登录的实现,就是将目标服务器的公钥拷贝到对方的服务器上,这样对方即可免密登录该目标服务器,而如果两台服务器要互相免密登录,当然就要互相拷贝到对方的公钥
#1) 首先在 hadoop001 中,生成公钥和私钥(一路回车到底就行了,不需要输入内容)
ssh-keygen -t rsa
#其中 id_rsa 为私钥,id_rsa.pub 为公钥
#2) 将 hadoop001 的公钥拷贝到 hadoop002
ssh-copy-id hadoop002
ssh-copy-id hadoop001
出现这个提示说明添加成功了,以后我们可以直接通过 ssh hadoop002
连接 hadoop002
注意:公钥也需要拷贝到本服务器,不然无法自己进行免密登录,这样的话,集群启动还是会报错
6、编写集群配置
正式开始集群的搭建啦,首先是集群的配置:
安排一下集群的部署:
hadoop001 | hadoop002 | hadoop003 | |
---|---|---|---|
HDFS | NameNode DataNode | DataNode | SecondaryNameNode DataNode |
YARN | NodeManager | ResourceManager NodeManager | NodeManager |
hadoop001 兼任主节点,配置 NameNode
hadoop002 兼任资源管理,配置 ResourceManager
hadoop003 兼任备份结点,配置 SecondaryNameNode
接着按照这个规划,修改 hadoop 配置文件
先说明一下各个配置文件及其位置(~
表示 hadoop 所在目录)
系统配置文件:~/share/doc/hadoop
用户自定义配置文件:~/etc/hadoop
我们需要配置的文件全部位于hadoop资源目录的/etc/hadoop下
首先到主节点 hadoop001 里边
配置 core-site.xml
下面是我自己的配置,需要配置两个东西
① 将 hadoop001 设置为主节点,端口推荐为 8020
② 将数据的默认存储位置改为 hadoop 目录下的 data 文件夹(如果不存在的话,会自动创建)
解释<configuration>
<!-- 指定 NameNode 地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop001:8020</value>
</property>
<!-- 指定 hadoop 数据存放的目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/hadoop-3.3.6/data</value>
</property>
</configuration>
配置 hdfs-site.xml
解释<configuration>
<!-- nn web 端访问地址 -->
<property>
<name>dfs.namenode.http-address</name>
<value>hadoop001:9870</value>
</property>
<!-- 2nn web 端访问地址-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop003:9868</value>
</property>
<!-- 添加 web 端访问文件的权限 -->
<!-- 这时后面补充上来的 2333,这里先天坑啦~ -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
</configuration>
配置 yarn-site.xml
解释<configuration>
<!-- 指定 MR 走 shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定 ResourceManager 的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop002</value>
</property>
<!-- 环境变量的继承 -->
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
</configuration>
配置 mapred-site.xml
解释<configuration>
<!-- 指定 MapReduce 程序运行在 Yarn 上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
将编写好的四个配置文件,同步到其他两台服务器上(hadoop002,hadoop003)
只需执行下面这一句,就能将四个配置文件远程复制到另外一个容器中
由于之前设置了免密登录,所以它可以直接远程复制,而不需要输入密码,可以很方便地在哥哥容器之间拷贝文件(hadoop003 也同理)
scp core-site.xml hdfs-site.xml yarn-site.xml mapred-site.xml root@hadoop002:/home/hadoop/hadoop-3.3.6/etc/hadoop
配置 workers
同样是在 hadoop001 中,修改文件 /etc/hadoop/workers
将里边的内容去掉(把 localhost 删掉)然后换成我们的三个容器:
注意:行末不能有空格,以及不能有空行的出现
hadoop001
hadoop002
hadoop003
然后将该文件同步到其他两个容器
scp workers root@hadoop002:/home/hadoop/hadoop-3.3.6/etc/hadoop/
scp workers root@hadoop003:/home/hadoop/hadoop-3.3.6/etc/hadoop/
7、启动集群
第一次启动时,需要进行初始化
hdfs namenode -format
初始化完毕后,在配置文件指定的目录下,就会生成 data
和 logs
两个文件
在 Hadoop001 中操作(配置了 NameNode 的)
启动HFS
start-dfs.sh
#查看Java进程——可以用于查看
jps
然后执行 jps
看是否启动成功,和下图一样说明成功了
启动 YARN
在 Hadoop002 中操作(配置了 ResourceManager的)
start-yarn.sh
图形化界面
动HFS
start-dfs.sh
#查看Java进程——可以用于查看
jps
然后执行 jps
看是否启动成功,和下图一样说明成功了
启动 YARN
在 Hadoop002 中操作(配置了 ResourceManager的)
start-yarn.sh