在Docker环境中安装Hadoop cluster

在Docker环境中安装Hadoop cluster 实验报告二

1个namenode, 3个datanodes

级: ++物联网++ ++2303++ 号: 231040700302 **名:**杜子健

  1. (30%) 安装过程
    1. Containers
    2. Hadoop

1.1 Containers 创建与配置

(1)拉取适配镜像

选择 Ubuntu 20.04 镜像(兼容性强,操作简洁),终端执行拉取命令:

bash

运行

docker pull ubuntu:20.04

(2)创建 4 个容器(1 个 NameNode+3 个 DataNode)

通过自定义网络确保容器间通信,同时配置端口映射满足 Web 访问和集群通信需求:

bash

运行

创建Hadoop专用网络

docker network create hadoop-network-2

创建NameNode容器(命名为nn,核心管理节点)

docker run -itd --name nn --network hadoop-network-2 -p 9870:9870 -p 9000:9000 -p 8088:8088 ubuntu:20.04

创建3个DataNode容器(命名为dn1、dn2、dn3,数据存储节点)

docker run -itd --name dn1 --network hadoop-network-2 ubuntu:20.04

docker run -itd --name dn2 --network hadoop-network-2 ubuntu:20.04

docker run -itd --name dn3 --network hadoop-network-2 ubuntu:20.04

命令说明:-p 9870:9870映射 HDFS Web 端口,-p 8088:8088映射 YARN Web 端口,-p 9000:9000映射 NameNode 通信端口,确保本地可访问集群。

(3)容器基础环境初始化(所有容器)

进入每个容器,安装 SSH、Java、vim 等必备工具(以 nn 为例,dn1/dn2/dn3 重复操作):

bash

运行

进入NameNode容器

docker exec -it nn bash

更新软件源并安装工具

apt update && apt install -y openjdk-8-jdk openssh-server vim wget net-tools

1.2 Hadoop 安装与集群配置

(1)SSH 免密登录配置(所有容器)

集群节点间需免密通信,确保 Hadoop 启动时无需手动输入密码:

启动 SSH 服务并设置开机自启:

bash

运行

service ssh start

update-rc.d ssh defaults # 设置开机自启

生成 SSH 密钥(一路回车,不设置密码):

bash

运行

ssh-keygen -t rsa

实现节点间免密登录:

在 nn 容器中,将公钥复制到所有 DataNode 容器:

bash

运行

ssh-copy-id dn1

ssh-copy-id dn2

ssh-copy-id dn3

ssh-copy-id nn # 同时配置自身免密登录

测试免密登录:ssh dn1,无需输入密码即可进入 dn1 容器即配置成功。

(2)Hadoop 下载与环境配置

下载 Hadoop 3.3.4 稳定版(在 nn 容器中操作):

bash

运行

wget https://archive.apache.org/dist/hadoop/core/hadoop-3.3.4/hadoop-3.3.4.tar.gz

解压并配置环境变量:

bash

运行

解压到/usr/local目录

tar -zxvf hadoop-3.3.4.tar.gz -C /usr/local/

mv /usr/local/hadoop-3.3.4 /usr/local/hadoop

配置环境变量

echo "export HADOOP_HOME=/usr/local/hadoop" >> ~/.bashrc

echo "export PATH=\PATH:\\HADOOP_HOME/bin:\$HADOOP_HOME/sbin" >> ~/.bashrc

echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64" >> ~/.bashrc

source ~/.bashrc # 生效配置

同步 Hadoop 到 3 个 DataNode 容器:

退出 nn 容器,在本地终端执行同步命令:

bash

运行

docker cp nn:/usr/local/hadoop dn1:/usr/local/

docker cp nn:/usr/local/hadoop dn2:/usr/local/

docker cp nn:/usr/local/hadoop dn3:/usr/local/

docker cp nn:~/.bashrc dn1:~/.bashrc

docker cp nn:~/.bashrc dn2:~/.bashrc

docker cp nn:~/.bashrc dn3:~/.bashrc

分别进入 dn1/dn2/dn3 容器,执行source ~/.bashrc生效环境变量。

(3)Hadoop 核心配置文件修改(nn 容器)

进入配置目录cd /usr/local/hadoop/etc/hadoop/,修改以下关键文件:

hadoop-env.sh:指定 Java 路径

bash

运行

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

core-site.xml:配置 HDFS 主节点地址

xml

<configuration>

<property>

<name>fs.defaultFS</name>

<value>hdfs://nn:9000</value> <!-- nn为NameNode容器名,自动解析IP -->

</property>

<property>

<name>hadoop.tmp.dir</name>

<value>/usr/local/hadoop/tmp</value> <!-- 临时文件存储路径 -->

</property>

</configuration>

hdfs-site.xml:配置副本数与数据存储路径

xml

<configuration>

<property>

<name>dfs.replication</name>

<value>3</value> <!-- 副本数=DataNode数量,确保数据冗余 -->

</property>

<property>

<name>dfs.namenode.name.dir</name>

<value>/usr/local/hadoop/namenode</value> <!-- NameNode元数据路径 -->

</property>

<property>

<name>dfs.datanode.data.dir</name>

<value>/usr/local/hadoop/datanode</value> <!-- DataNode数据存储路径 -->

</property>

<property>

<name>dfs.http.address</name>

<value>0.0.0.0:9870</value> <!-- 允许外部访问HDFS Web界面 -->

</property>

</configuration>

mapred-site.xml:配置 MapReduce 依赖 YARN

xml

<configuration>

<property>

<name>mapreduce.framework.name</name>

<value>yarn</value>

</property>

</configuration>

yarn-site.xml:配置 YARN 资源管理

xml

<configuration>

<property>

<name>yarn.resourcemanager.hostname</name>

<value>nn</value> <!-- YARN资源管理器部署在NameNode -->

</property>

<property>

<name>yarn.nodemanager.aux-services</name>

<value>mapreduce_shuffle</value> <!-- 启用Shuffle服务 -->

</property>

</configuration>

workers:指定 DataNode 节点列表

bash

运行

dn1

dn2

dn3

(4)创建数据存储目录并格式化 NameNode

在所有容器中创建目录:

bash

运行

mkdir -p /usr/local/hadoop/tmp /usr/local/hadoop/namenode /usr/local/hadoop/datanode

在 nn 容器中格式化 NameNode(仅执行一次):

bash

运行

hdfs namenode -format

显示 "successfully formatted" 即格式化成功。

(5)启动 Hadoop 集群

在 nn 容器中执行启动命令,一键启动 HDFS 和 YARN 服务:

bash

运行

start-all.sh

验证启动状态:在 nn 容器执行jps,显示 NameNode、ResourceManager 等进程;在 dn1/dn2/dn3 执行jps,显示 DataNode、NodeManager 等进程即启动成功。

  1. (15%) Docker Desktop Dashboard docker-hadoop-3-Node 运行截圖。
  1. (15%) Hadoop cluster 运行截圖。
  1. (20%) 过程出现那些问题? 如何解决?

  2. 问题 1:容器间 SSH 连接失败,提示 "Connection refused"

  • 现象:执行ssh dn1时无法连接,提示端口 22 拒绝访问。
  • 解决方法:检查容器内 SSH 服务是否启动,执行service ssh start手动启动;部分容器未安装 openssh-server,重新执行apt install -y openssh-server安装,确保 SSH 服务正常运行。
  1. 问题 2:DataNode 启动失败,jps未显示 DataNode 进程
  • 现象:启动集群后,NameNode 正常运行,但 3 个 DataNode 均未启动,查看日志提示 "Invalid directory in dfs.datanode.data.dir"。
  • 解决方法:检查hdfs-site.xml中配置的数据存储目录是否存在,在所有 DataNode 容器中执行mkdir -p /usr/local/hadoop/datanode创建目录;若已创建仍失败,删除目录下所有文件(rm -rf /usr/local/hadoop/datanode/*),重新格式化 NameNode 后启动。
  1. 问题 3:YARN Web 界面无法访问(localhost:8088打不开)
  • 现象:HDFS Web 界面正常,但 YARN 界面无法访问,jps显示 ResourceManager 未启动。
  • 解决方法:检查yarn-site.xml配置,确保yarn.resourcemanager.hostname设置为 "nn"(与 NameNode 容器名一致);查看 Hadoop 日志($HADOOP_HOME/logs/yarn-root-resourcemanager-nn.log),发现 Java 路径配置错误,重新在hadoop-env.sh中指定正确的 JAVA_HOME 路径,重启集群。
  1. 问题 4:同步 Hadoop 文件到 DataNode 时权限不足
  • 现象:执行docker cp nn:/usr/local/hadoop dn1:/usr/local/时提示 "permission denied"。
  • 解决方法:在本地终端添加sudo提升权限,执行sudo docker cp nn:/usr/local/hadoop dn1:/usr/local/;同步完成后,进入 DataNode 容器执行chmod -R 755 /usr/local/hadoop,确保 Hadoop 目录权限正常。
  1. (20%) 心得与感受

本次实验二在 Docker 环境中搭建 1 个 NameNode+3 个 DataNode 的 Hadoop 集群,相比实验一的基础配置,多节点部署对容器网络、配置同步和节点通信的要求更高,也让我收获了更深入的技术实践经验。

实验初期,我在容器间 SSH 免密登录和 DataNode 启动环节多次遇到问题,这让我意识到集群部署的核心在于 "配置一致性" 和 "环境完整性"。比如 DataNode 启动失败的根源是配置目录未创建,YARN 启动失败是 Java 路径配置错误,这些细节问题需要通过日志排查和逐行核对配置文件解决,极大提升了我的问题排查能力和细心程度。

通过本次实验,我对 Docker 的容器化优势有了更深刻的认识:无需在本地搭建多个 Linux 环境,通过 4 个独立容器即可模拟分布式集群,且容器间网络隔离又互通,既保证了环境纯净,又简化了集群部署流程。同时,我也深入理解了 Hadoop 集群的协同工作机制 ------NameNode 作为 "大脑" 管理元数据,3 个 DataNode 作为 "存储节点" 共同承载数据,YARN 负责资源调度,三者缺一不可。

此外,多节点部署让我体会到 "副本数配置" 的实际意义,将dfs.replication设为 3,确保数据在 3 个 DataNode 上冗余存储,提升了数据安全性。同步 Hadoop 文件和环境变量的过程,也让我学会了高效的多节点配置方法,避免重复操作。

这次实验不仅巩固了 Docker 和 Hadoop 的核心知识点,更让我明白分布式技术的关键在于 "协同" 与 "兼容"。未来,我会尝试在集群中运行实际的 MapReduce 任务,进一步验证集群可用性,同时深入学习容器编排技术,为后续更复杂的分布式系统部署打下基础。

相关推荐
AOwhisky2 小时前
Docker 学习笔记:镜像分发、容器运行与资源限制
笔记·学习·docker
跨境数据猎手3 小时前
反向海淘代购系统 Docker + Kubernetes
docker·容器·kubernetes
冷小鱼3 小时前
从 Docker 到容器编排:框架选型与指令详解实战指南
运维·docker·容器·k8s·docker compose·docker swarm
Cat_Rocky3 小时前
K8S-HPA水平扩缩容
docker·容器·kubernetes
ziqi5224 小时前
Docker容器镜像管理、制作
运维·docker·容器
轻口味6 小时前
AI 时代全栈开发破局:TypeScript 生态实战,从入门到部署一站式通关
前端·mongodb·docker·ai·typescript·react·next.js
hopsky8 小时前
docker 容器文件异常大的问题排查
运维·docker·容器
bloglin999999 小时前
兼容旧版 docker-compose 和新版 docker compose
运维·docker·容器
花生壳儿9 小时前
Docker容器安装MySQL数据库
数据库·mysql·docker