如何在Docker中安装Hadoop
本教程是在 Docker 的环境下搭建 Hadoop 集群,如果不使用 Docker,可以跳过 Docker 部分。
本教程更新时间为:2021 年 4 月 26 日,在此之后官方版本更新,请酌情参考。
版本
- Docker: version 20.10.6, build 370c289
- JDK: 1.8.0_291
- Hadoop: 3.2.2
Docker
为什么选择 Docker
Docker 相比较于以前使用的虚拟机软件(VMware,VirtualBox),有着更少的抽象层,使用起来更加轻便,占用资源少。

图中从左往右分别是物理机、docker 和虚拟机的计算能力数据。可见 docker 相对于物理机其计算能力几乎没有损耗,而虚拟机对比物理机则有着非常明显的损耗。虚拟机的计算能力损耗在 50%左右。
因此,在计算机资源不足的情况下,需要搭建集群,Docker 是一个不错的选择
缺陷
每次启动,需要手动启动 ssh 服务
Docker 安装方式
Docker 目前有 3 种安装方式
1、Windows 下安装 Docker
2、Windows 10 1903 或更高版本中,使用 WSL2 安装 Docker
3、Linux 下安装 Docker
当然 Linux 使用 Docker 最好,如果是新版本 Win10,推荐使用 WSL 2 搭建一个 Docker
如果是旧版本,可以考虑直接使用虚拟机,直接使用 WSL 1 会出现些许兼容问题
WSL 安装
启用适用于 Linux 的 Windows 子系统
需要先启用“适用于 Linux 的 Windows 子系统”可选功能,然后才能在 Windows 上安装 Linux 分发。
以管理员身份打开 PowerShell 并运行
1 | dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart |
更新到 WSL 2
若要更新到 WSL 2,需要运行 Windows 10。
要求
- 对于 x64 系统: 版本 1903 或更高版本,采用 内部版本 18362 或更高版本。
- 对于 ARM64 系统: 版本 2004 或更高版本,采用 内部版本 19041 或更高版本。
- 低于 18362 的版本不支持 WSL 2。 使用 Windows Update 助手更新 Windows 版本。
若要检查 Windows 版本及内部版本号,选择 Windows 徽标键 + R,然后键入“winver”,选择“确定”。 (或者在 Windows 命令提示符下输入 ver 命令)。 更新到“设置”菜单中的最新 Windows 版本。
启用虚拟机功能
安装 WSL 2 之前,必须启用“虚拟机平台”可选功能。
以管理员身份打开 PowerShell 并运行:
1 | dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart |
重新启动 计算机,以完成 WSL 安装并更新到 WSL 2。
控制面板(启动或关闭 Windows 功能)
当然,这个命令跟你在控制面板中启用“适用于 Windows 的 Linux 子系统”和“启用虚拟机功能”功能是一样的。

下载 Linux 内核更新包
下载最新包:
如果使用的是 ARM64 计算机,请下载 ARM64 包。 如果不确定自己计算机的类型,请打开命令提示符或 PowerShell,并输入:
systeminfo | find "System Type"。运行上一步中下载的更新包。 (双击以运行 - 系统将提示你提供提升的权限,选择“是”以批准此安装。)
安装完成后,请继续执行下一步 - 在安装新的 Linux 分发时,将 WSL 2 设置为默认版本。 (如果希望将新的 Linux 安装设置为 WSL 1,请跳过此步骤。)
将 WSL 2 设置为默认版本
打开 PowerShell,然后在安装新的 Linux 发行版时运行以下命令,将 WSL 2 设置为默认版本:
1 | wsl --set-default-version 2 |
从 WSL 1 更新到 WSL 2 可能需要几分钟才能完成,具体取决于目标分发版的大小。 如果从 Windows 10 周年更新或创意者更新运行 WSL 1 的旧(历史)安装,可能会遇到更新错误。 按照这些说明卸载并删除任何旧分发。
如果 wsl --set-default-version 结果为无效命令,请输入 wsl --help。 如果 --set-default-version 未列出,则表示你的 OS 不支持它,你需要更新到版本 1903(内部版本 18362)或更高版本。
运行命令后如果看到此消息:
1 | WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel |
则需要安装 MSI Linux 内核更新包。
安装所选的 Linux 分发
打开 Microsoft Store,并选择你偏好的 Linux 分发版,推荐使用 Ubuntu。
![image-20201107162422930]()
在分发版的页面中,选择“获取”或“安装”
设置新分发
首次启动新安装的 Linux 分发版时,将打开一个控制台窗口,系统会要求你等待一分钟或两分钟,以便文件解压缩并存储到电脑上。 未来的所有启动时间应不到一秒。
可以在开始菜单搜索 Ubuntu 进入窗口,或者在控制台 PowerShell 或 Terminal 输入wsl,进入 Linux

第一次进入会提示你输入用户名和密码,密码会隐藏不是显示,直接输入 2 次密码即可
如果你不想使用用户名,想直接使用 root 账户,可直接关闭该窗口,跳过用户名和密码的设置即可。
参考命令
检查分配给每个已安装的 Linux 分发版的 WSL 版本:wsl -l -v
1 | wsl --list --verbose |
若要将分发版设置为受某一 WSL 版本支持,请运行:
1 | wsl --set-version <distribution name> <versionNumber> |
请确保将 <distribution name> 替换为你的分发版的实际名称,并将 <versionNumber> 替换为数字“1”或“2”。 可以随时更改回 WSL 1,方法是运行与上面相同的命令,但将“2”替换为“1”。
此外,如果要使 WSL 2 成为你的默认体系结构,可以通过此命令执行该操作:
1 | wsl --set-default-version 2 |
这会将安装的任何新分发版的版本设置为 WSL 2。
WSL 换源
WSL 系统操作跟 Ubuntu 操作一致,只是与桌面版相比,没有界面,全程需要使用终端命令
跟 ubuntu 一眼,第一步换源,保证软件更新迅速
清华大学开源软件镜像站:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/
使用命令编辑源
1 | sudo nano /etc/apt/sources.list |
按i进行编辑,删除所有内容,粘贴以下 ubuntu 版本20.04的源,如果不是同样版本,请点击上面链接,自行选择
1 | # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 |
粘贴完毕后使用按键esc退出编辑模式,使用命令:wq保存退出
更换源后,我们需要刷新源的 meta,以及更新软件,请使用以下命令
1 | sudo apt update |
运行完毕后,换源结束
Docker 安装
首先安装依赖:
1 | sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release |
信任 Docker 的 GPG 公钥:
1 | curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg |
使用以下命令设置稳定的存储库
1 | echo \ |
安装
1 | sudo apt-get update |
最后一个步骤,启动 Docker daemon。但是此处有一个问题,WSL2 经过测试无法直接使用使用systemctl命令,因此我们使用service命令启动 Docker daemon。命令如下所示:
1 | sudo service docker start |
1 | sudo service docker status |
至此,Docker 在 WSL2 下安装完毕。
Docker 换源
编辑/etc/docker/daemon.json文件,将一下配置放入其中
1 | { |
阿里云的镜像加速,你可以自己申请一个,也可以直接用我的
Docker 测试
到此,您已经安装完毕 Docker,可以使用命令docker --version查看 docker 版本
1 | docker --version |
可以使用命令sudo docker run hello-world运行你的第一个容器
1 | sudo docker run hello-world |
Portainer
我们会使用一个 Portainer,一个轻量级的 Docker 环境管理 UI,来方便新手来下载镜像,创建容器
搜索 Portainer
我们可以使用sudo docker search portainer来搜索该镜像
1 | sudo docker search portainer |
我们一般会下载第一个镜像来使用,毕竟用的人最多
但是根据 description 可以看到,该镜像已经过期了,推荐使用 ce 版本,那我们就是用推荐的版本即可
使用sudo docker pull portainer/portainer-ce来下载镜像,你可以把镜像理解成一个安装包,下载下来后,你还需要解压安装
安装 Portainer
根据 protainer 官方的例子,运行以下命令启动 portainer
1 | sudo docker volume create portainer_data |
-d表示后台运行-p表示端口映射
其他参数含义可以自己去搜索,至此我们就安装完毕 Portainer
使用 Portainer
使用浏览器打开网址http://localhost:30000打开 Portainer 网页,设置管理员账号和密码

选择 Local 模式,Connect 连接
支持 Portainer 配置完毕
Ubuntu
下载镜像
接下来我们就需要使用 Portainer 搭建 Hadoop 集群,首先我们需要准备一个 ubuntu,作为 master 节点
首先点击左侧菜单,选择 Images,输入ubuntu,选择 Pull the Image,拉取一个镜像下来

稍等片刻后,我们就可以看到镜像已经下载下来了,十分小巧,只有 72.7M

设置网络
为了让 3 个节点的 linux 都在一个局域网内,以便之后更方便的搭建集群,我们先创建一个网络,点击左侧的 Networks,点击Add network,添加新网络

随意输入一个网络名,将Enable manual container attachment设置为 True,其他选择默认的 bridge 网络即可

创建完毕后,可以看到这个HadoopCluster的网段是 172.18.0.0,这个记一下,之后会用
创建容器
我们首先来创建集群中的第一个节点,主节点(master)

选择左侧菜单Container,点击Add container按钮

按照下图的参数填写信息,命名这个容器为 master,使用 ubuntu:lastest 镜像
然后往下翻,在Command & logging中,设置 Command 为tail -f /dev/null,保证容器挂起,而不是每次启动后自动关机,控制端使用Interactive & TTY模式

在Network中,选择 Network 为我们刚才创建的网络HadoopCluster,输入 hostname 为master,固定 Ip 为 172.18.0.100,因为 docker 容器每次启动都会重新生成 hosts,所以我们在创建的时候,就需要直接编辑好 Hosts file entries,否则每次启动后都要手动编辑 hosts 文件。

在Runtime & Resources中,进行下图设置,保证容器内的容器可以拿到真实权限,并可以进行资源占用设置,可以 unlimited 无限制,或者限制内存

在Capabilities中,设置SYS_TEM为 True,保证容器能够拥有足够的权限

最后,点击Deploy the container按钮,部署该容器
配置容器

容器创建好后,我们就可以在 Containers,选择刚创建的 master 容器,点击Console按钮,连接到 Ubuntu 进行配置
运行命令apt update && apt install openssh-server iputils-ping net-tools nano更新并安装必要工具

安装过程中,需要选择时区,分别输入 6 和 70,选择亚洲和上海
运行完毕后,使用命令nano /etc/apt/sources.list编辑源,Ctrl+K删除所有内容,然后将以下文本替换其中
1 | # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 |
使用Ctrl+X退出,输入 Y 保存,并确定保存路径
使用命令apt update && apt dist-upgrade更新源,并更新系统所有软件
使用命令passwd设置 root 用户登录密码
准备自己子节点
按照同样的步骤,我们再次创建 2 台 ubuntu,作为 slave1 节点和 slave2 节点
记得修改 ip 和主机名即可,可以不用端口映射,之后使用 master 节点连接另外 2 台节点即可
Host
Hosts 是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的 IP 地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从 Hosts 文件中寻找对应的 IP 地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交 DNS 域名解析服务器进行 IP 地址的解析。
为了机器能够快速识别自己以及其他机器,我们可以做一下域名和 IP 的 hosts 映射,这样在之后的操作中,我们就可以直接用域名来代替 IP 地址
然后根据命令ifconfig查看每一台机器的 IP,并依次记录下来
如果之前创建容器的时候,没有编辑 host 文件
那么每次启动后,需要手动编辑 hosts 文件
使用命令nano /etc/hosts,将以下信息编辑进去,方便互相通信
1 | 172.18.0.100 master |
Hostname
如果之前创建容器的时候,hostname 主机名设置错误
需要手动编辑主机名文件,使用命令nano /etc/hostname,将以下信息编辑进去
1 | master |
设置完毕后,务必记得重新启动虚拟机
SSH
简介
SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。
修改 OpenSSH-server
因为 root 默认情况下不允许 SSH 登录,所有我要修改一下 ssh-server 的配置,普通用户除外
使用命令nano /etc/ssh/sshd_config编辑 SSH 的设置,修改为一下配置
1 | PermitRootLogin yes |
使用命令service ssh restart重启 SSH 服务,这样我们就可以可以使用 XShell 工具远程登录 root 账户了
生成密钥对
使用命令ssh-keygen -t rsa,生成密钥对,一直回车,当出现以下信息,表示生成成功
1 | ssh-keygen -t rsa |
该命令将在~/.ssh 目录下面产生一个密钥 id_rsa 和一个公钥 id_rsa.pub
将你的计算机(B)中的公钥传给别的计算机(A),A 计算机才能免密码登录计算机 B
免密登录本机
首先使用下面的命令,将公钥发放给自己
1 | cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys |
你可以使用命令cd ~/.ssh/,进去.ssh路径下,更方便的进行操作
也可以手动建立authorized_keys文件,手动将公钥粘贴进去,需要保证是 644
你可以使用命令ll查看文件夹下所有文件的权限

如果权限不正确,请使用下面的命令修改权限
1 | chmod 600 authorized_keys |
然后使用下面的命令,免密连接本机,测试是否成功
1 | ssh localhost |
第一次登录需要进行一次验证,输入 yes 即可,当出现下图的提示,表示免登录成功

然后可通过 exit,退出登录,返回之前的页面
集群免密登录
接下来在每一台节点上,重复运行命令ssh-keygen -t rsa,生成密钥对
使用命令cat ~/.ssh/id_rsa.pub,查看公钥


将内容复制到主机 master 节点上的~/.ssh/authorized_keys文件中,复制成功后,可通过命令cat ~/.ssh/authorized_keys,查看所有节点的公钥,应如下图所示

然后使用下面的命令,将 authorized_keys 文件传给,其他节点的相同位置,这次传输,因为还没有免密成功,所以还是需要输入密码
1 | scp ~/.ssh/authorized_keys root@slave1:~/.ssh/ |
这样子,我们就让每一台机器都持有了集群中所有节点的公钥,任意机器都可以通过 ssh 登录到任意节点

可以使用 ssh 尝试登录别的节点,正常情况下,不会出现提示,直接登录

JDK
https://cwiki.apache.org/confluence/display/HADOOP/Hadoop+Java+Versions
Apache Hadoop 3.3 and upper supports Java 8 and Java 11 (runtime only)
Please compile Hadoop with Java 8. Compiling Hadoop with Java 11 is not supported:
HADOOP-16795 - Java 11 compile support OPEN
Apache Hadoop from 3.0 to 3.2 now supports only Java 8
Apache Hadoop from 2.7.x to 2.x support Java 7 and 8
所以我们选择 JDK 8
下载
首先打开 JDK 的下载页面

选择 Linux 版本的 JDK 下载即可
解压
使用下面的命令解压 jdk 压缩包,我们统一放到路径/opt下
1 | tar -xvzf jdk-8u291-linux-x64.tar.gz -C /opt |
此时 jdk 的文件结构为
1 | ls /opt/jdk1.8.0_291 |
环境变量
使用命令nano /etc/profile编辑系统环境变量文件,将下面的文本添加进环境变量
1 | # JAVA |
运行命令source /etc/profile,更新系统变量
然后运行命令java -version,查看 JDK 是否安装成功
1 | java -version |
Hadoop
下载
首先点击这里,进入 Hadoop 官网下载页面。

选择 3.2.2(stable)稳定版本进行下载,然后点击 binary 地址进行下载

选中官方推荐的地址即可下载,其他地址也可用(建议采用迅雷等下载工具下载,速度比较会快很多,上传至 UBUNTU 系统)
或者在 ubuntu 中使用wget命令进行下载
1 | wget https://apache.website-solution.net/hadoop/common/hadoop-3.2.2/hadoop-3.2.2.tar.gz |
解压
使用下面的命令解压 jdk 压缩包,我们统一放到路径/opt下
1 | tar -xvzf hadoop-3.2.2.tar.gz -C /opt |
此时 hadoop 的文件结构为
1 | ls /opt/hadoop-3.2.2 |
环境变量
使用命令nano /etc/profile编辑系统环境变量文件,将下面的文本添加进环境变量
1 | # HADOOP |
运行命令source /etc/profile,更新系统变量
配置
hadoop 的部署分为 3 种模式,分别为单机模式 伪分布模式(单节点) 全分布模式三种
无论部署哪种模式,我们都需要先配置环境变量,我们选择配置系统变量,无论是否是当前路径都可以使用
首先打开/opt/hadoop-3.2.2/etc/hadoop这个目录,分别编辑下面几个文件,根据个人需求更改参数:
core-site.xml
1 | <configuration> |
master 在 hosts 文件中做了映射,可以替换成本机 IP
hdfs-site.xml
1 | <configuration> |
如果你只有 3 个 datanode,但是你却指定副本数为 4,是不会生效的,因为每个 datanode 上只能存放一个副本。
hadoop 有时候并不能自己创建 namenode 和 datanode 文件夹,可以运行下面的命令手动创建这 2 个文件夹
1 | mkdir -p /opt/data/namenode |
yarn-site.xml
1 | <configuration> |
mapred-site.xml
1 | <configuration> |
hadoop-env.sh
在任意地方添加 JAVA_HOME
1 | export JAVA_HOME=/opt/jdk1.8.0_291 |
workers
1 | master |
配置的是所有的从节点,用 IP 也可以,所有配置文件修改完毕后,进入 hadoop 初始化步骤
同步环境到其他节点
到此一个节点上的配置就已经全部配置完毕了
接下来,我们可以使用下面的命令,将 JDK 和 Hadoop 传输到其他节点
1 | scp /etc/profile slave1:/etc/ |
Hadoop 初始化
允许 root 账户运行
使用下面的命令进入 hadoop 脚本路径
1 | cd $HADOOP_HOME/sbin/ |
使用vi编辑start-dfs.sh和stop-dfs.sh顶部添加
1 | HDFS_DATANODE_USER=root |
使用vi编辑start-yarn.sh和stop-yarn.sh顶部添加
1 | YARN_RESOURCEMANAGER_USER=root |
HDFS 初始化
集群模式下,需要对每一台机器进行初始化
接下来到各个节点运行下面的命令
1 | hdfs namenode -format |
格式化完毕后,如图所示,则表示初始化成功

如果初始化失败,需要用下面的命令手动清空 namenode 和 datanode 文件夹,调整配置后,重新初始化
1 | rm -rf /opt/data/namenode/* |
启动 Hadoop
Namenode
1 | hdfs --daemon start namenode |
Datanode
1 | hdfs --daemon start datanode |
你可以使用上面的命令挨个启动 namenode 和 datanode,如果已配置好 workers 和 ssh 免密登录,你可以使用下面的命令调用脚本直接启动所有 hdfs 进程
1 | start-dfs.sh |
ResourceManager
1 | yarn --daemon start resourcemanager |
NodeManager
1 | yarn --daemon start nodemanager |
你可以使用上面的命令挨个启动 resourcemanager 和 nodemanager,如果已配置好 workers 和 ssh 免密登录,你可以使用下面的命令调用脚本直接启动所有 yarn 进程
1 | start-yarn.sh |
启动成功
启动完毕后可以使用jps命令查看启动的 hadoop 进程
master 节点
1 | jps |
slave 节点
1 | jps |
可以访问 http://localhost:9870 ,查看 HDFS 运行情况


可以访问 http://localhost:8088 查看所有 Yarn 任务的运行情况

至此整个 hadoop 就搭建好了
案例测试
PI 值计算
我们可以使用一个简单的例子来测试一下 hadoop 是否能够正常运行
我们从 hadoop 安装文件夹,启动一个终端,使用下面的命令,计算 pi 值
1 | hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar pi 10 10 |
如图所示,我们计算量比较少导致不够精确,但是已经可以成功运算出 pi 值了

附件
相关链接
