读完这篇,你会用 Dockerfile + 外部配置文件的方式,从零构建一个 Hadoop 3.3.6 镜像。
所有 XML 和启动脚本都放在宿主机目录里,修改方便,排错清晰。

一、为什么要把配置文件放在外面?
之前我们把四个 XML 和 entrypoint.sh 全写在 Dockerfile 里,虽然能跑,但修改配置每次都要重新编辑 Dockerfile,维护起来不够直观。
把配置文件独立出来,目录结构清晰,将来换集群、改参数,只需动一两个文件,不用再碰 Dockerfile 主体。
二、最终目录结构
在你的 Mac 上创建一个新文件夹,比如 hadoop-docker,里面放这 6 个文件:
Plain
hadoop-docker/
├── Dockerfile
├── core-site.xml
├── hdfs-site.xml
├── yarn-site.xml
├── mapred-site.xml
└── entrypoint.sh

三、逐个文件内容(直接复制粘贴)
1. Dockerfile
Dockerfile
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
# 安装必要软件
RUN apt-get update && apt-get install -y --no-install-recommends \
wget curl sudo openssh-server openssh-client openjdk-11-jdk net-tools vim \
&& rm -rf /var/lib/apt/lists/*
# 创建 hadoop 用户并授予 sudo 权限
RUN useradd -m hadoop -s /bin/bash && \
echo "hadoop:hadoop" | chpasswd && \
echo "hadoop ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
USER hadoop
WORKDIR /home/hadoop
# 配置 SSH 免密登录
RUN ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa && \
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys && \
chmod 600 ~/.ssh/authorized_keys
# 下载并解压 Hadoop
RUN wget -q https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz && \
tar -xzf hadoop-3.3.6.tar.gz && mv hadoop-3.3.6 hadoop && rm hadoop-3.3.6.tar.gz
# 创建 Hadoop 所需目录
RUN mkdir -p /home/hadoop/hdfs/namenode /home/hadoop/hdfs/datanode /home/hadoop/hadoop/logs
# 拷贝外部配置文件(从构建上下文目录复制进镜像)
COPY core-site.xml /home/hadoop/hadoop/etc/hadoop/
COPY hdfs-site.xml /home/hadoop/hadoop/etc/hadoop/
COPY yarn-site.xml /home/hadoop/hadoop/etc/hadoop/
COPY mapred-site.xml /home/hadoop/hadoop/etc/hadoop/
# 将环境变量写入系统级配置,确保任何登录方式都能加载
# 将环境变量文件拷贝到系统目录,所有用户登录时自动加载
COPY hadoop-profile.sh /etc/profile.d/hadoop.sh
# 硬写入 JAVA_HOME 到 hadoop-env.sh,避免 SSH 启动时找不到
RUN sudo sed -i 's|# export JAVA_HOME=.*|export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-arm64|' /home/hadoop/hadoop/etc/hadoop/hadoop-env.sh
# 提前格式化 NameNode
RUN /home/hadoop/hadoop/bin/hdfs namenode -format -force
# 拷贝启动脚本
COPY entrypoint.sh /home/hadoop/entrypoint.sh
RUN sudo chmod +x /home/hadoop/entrypoint.sh
EXPOSE 9870 9000 9864 8088 8032 22
ENTRYPOINT ["/home/hadoop/entrypoint.sh"]
这个四个配置文件:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml 跟这篇【用 Docker 装 Hadoop,看这篇就够了】的一样,不再啰嗦
2. entrypoint.sh
Bash
#!/bin/bash
sudo service ssh start
sudo -u hadoop bash -c "source /etc/profile.d/hadoop.sh && start-dfs.sh && start-yarn.sh"
tail -f /dev/null
所有文件粘贴好后,你的 hadoop-docker 目录就应该有这 6 个文件。
四、构建镜像
在 hadoop-docker 目录下打开终端,执行:
Bash
docker build -t hadoop-single:v1 .
-t hadoop-single:v1:给镜像起名和打标签。- 最后的
.表示构建上下文为当前目录,Docker 会从这里读取 Dockerfile 和配置文件。
构建过程大约需要几分钟。看到 Successfully tagged hadoop-single:v1 即为成功。

五、启动容器
Bash
docker run -d --name hadoop-prod \
-p 9870:9870 \
-p 8088:8088 \
-p 9000:9000 \
-p 2222:22 \
hadoop-single:v1
参数解释:
-d:后台运行--name hadoop-prod:容器名称-p 宿主机端口:容器端口:映射关键端口,方便从 Mac 访问- 9870:HDFS NameNode Web UI
- 8088:YARN ResourceManager Web UI
- 9000:HDFS RPC 端口(Spark、Flink 等客户端读写用)
- 2222:SSH 端口(避免和 Mac 自身的 22 端口冲突)
检查容器运行状态:
Bash
docker ps
看到 hadoop-prod 状态为 Up 即正常。

六、验证 Hadoop 服务
1. 浏览器访问
打开 Mac 的浏览器,输入:
- HDFS NameNode:
http://localhost:9870 - YARN ResourceManager:
http://localhost:8088
如果页面正常显示,说明 Hadoop 启动成功。

2. 进入容器使用命令行
Bash
docker exec -it hadoop-prod su - hadoop
因为我们在 /etc/profile.d/hadoop.sh 里写了环境变量,所以使用 su - 登录后,HADOOP_HOME 和 PATH 都已经自动生效,直接就能用命令:
Bash
hdfs dfs -mkdir /test
echo "hello hadoop" | hdfs dfs -put - /test/hello.txt
hdfs dfs -cat /test/hello.txt
输出 hello hadoop 即表示 HDFS 读写正常。

七、环境变量为何再也不会丢?
- 我们放弃了仅在
~/.bashrc或~/.profile里设变量,而是把 export 写到了/etc/profile.d/hadoop.sh。 - 这个目录下的脚本会被任何用户的登录 shell (
su -、SSH 登录)自动加载,连非交互式 shell 也能读到。 - 同时还修改了
hadoop-env.sh,显式指定JAVA_HOME,即使通过 SSH 远程启动 Hadoop 脚本,也绝不会再报JAVA_HOME is not set。