基于Docker Compose编排一键部署Hadoop集群
1. 为什么需要Docker Compose部署Hadoop?
传统手动部署Hadoop集群就像搭积木时没有说明书——你需要自己组装每个节点,配置网络,处理服务依赖关系。我最早接触Hadoop时,花了整整三天才让一个三节点集群跑起来,期间经历了SSH配置错误、端口冲突、配置文件版本不匹配等各种问题。
Docker Compose的出现彻底改变了这种状况。它就像个智能积木组装机器人,你只需要用YAML文件描述清楚"需要哪些积木块"和"积木块之间如何连接",剩下的工作它会自动完成。去年我在客户现场演示时,用docker-compose.yml文件在15分钟内就拉起了一个完整的Hadoop集群,客户技术总监当场表示"这比我们运维团队传统部署方式快了一个数量级"。
具体来说,Docker Compose解决了几大痛点:
- 环境一致性:所有节点基于同一个镜像启动,彻底杜绝"在我机器上是好的"这类问题
- 依赖管理:自动处理服务启动顺序,比如确保NameNode先于DataNode启动
- 资源隔离:每个服务运行在独立容器中,避免端口冲突和服务抢占资源
- 快速重置:测试完成后一键销毁,再一键重建全新环境
2. 准备工作:搭建你的Docker积木工厂
2.1 基础环境配置
在开始前,我们需要准备好"积木工厂"的基础设施。以Ubuntu 20.04为例:
# 安装Docker引擎
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl enable --now docker
# 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
验证安装:
docker --version # 应显示Docker版本
docker-compose --version # 应显示Compose版本
2.2 Hadoop镜像定制
虽然可以直接使用官方镜像,但我建议自定义镜像以便后续扩展。创建一个Dockerfile:
FROM ubuntu:20.04
# 安装基础工具
RUN apt-get update && apt-get install -y \
openssh-server \
openjdk-8-jdk \
wget \
vim
# 配置SSH
RUN mkdir /var/run/sshd
RUN echo 'root:root' | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN ssh-keygen -A
# 安装Hadoop
ENV HADOOP_VERSION 3.3.4
RUN wget https://archive.apache.org/dist/hadoop/common/hadoop-${HADOOP_VERSION}/hadoop-${HADOOP_VERSION}.tar.gz && \
tar -xzvf hadoop-${HADOOP_VERSION}.tar.gz -C /usr/local/ && \
rm hadoop-${HADOOP_VERSION}.tar.gz && \
mv /usr/local/hadoop-${HADOOP_VERSION} /usr/local/hadoop
# 设置环境变量
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
ENV HADOOP_HOME=/usr/local/hadoop
ENV PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# 创建工作目录
RUN mkdir -p /hadoop/data /hadoop/name /hadoop/tmp
EXPOSE 22 9000 50070 8088
CMD ["/usr/sbin/sshd", "-D"]
构建镜像:
docker build -t my-hadoop:3.3.4 .
3. 编写Docker Compose编排文件
3.1 基础集群配置
创建docker-compose.yml文件,这相当于我们的"积木组装说明书":
version: '3.8'
services:
namenode:
image: my-hadoop:3.3.4
hostname: namenode
ports:
- "50070:50070" # HDFS Web UI
- "9000:9000" # HDFS服务端口
volumes:
- namenode-data:/hadoop/name
environment:
- CLUSTER_NAME=hadoop-cluster
command: >
bash -c "
$HADOOP_HOME/bin/hdfs namenode -format $$CLUSTER_NAME &&
$HADOOP_HOME/sbin/hadoop-daemon.sh start namenode &&
tail -F $HADOOP_HOME/logs/hadoop-root-namenode-*.log
"
datanode1:
image: my-hadoop:3.3.4
hostname: datanode1
depends_on:
- namenode
volumes:
- datanode1-data:/hadoop/data
command: >
bash -c "
$HADOOP_HOME/bin/hdfs datanode &&
tail -F $HADOOP_HOME/logs/hadoop-root-datanode-*.log
"
datanode2:
image: my-hadoop:3.3.4
hostname: datanode2
depends_on:
- namenode
volumes:
- datanode2-data:/hadoop/data
command: >
bash -c "
$HADOOP_HOME/bin/hdfs datanode &&
tail -F $HADOOP_HOME/logs/hadoop-root-datanode-*.log
"
resourcemanager:
image: my-hadoop:3.3.4
hostname: resourcemanager
ports:
- "8088:8088" # YARN Web UI
depends_on:
- namenode
command: >
bash -c "
$HADOOP_HOME/sbin/yarn-daemon.sh start resourcemanager &&
tail -F $HADOOP_HOME/logs/yarn-root-resourcemanager-*.log
"
nodemanager1:
image: my-hadoop:3.3.4
hostname: nodemanager1
depends_on:
- resourcemanager
command: >
bash -c "
$HADOOP_HOME/sbin/yarn-daemon.sh start nodemanager &&
tail -F $HADOOP_HOME/logs/yarn-root-nodemanager-*.log
"
volumes:
namenode-data:
datanode1-data:
datanode2-data:
3.2 关键配置解析
这个配置文件有几个精妙之处值得说明:
- 服务依赖:通过depends_on确保NameNode先于DataNode启动,ResourceManager先于NodeManager启动
- 数据持久化:使用命名卷(namenode-data等)保存HDFS数据,即使容器重启数据也不会丢失
- 日志跟踪:tail -F命令保持容器运行并实时输出日志到控制台
- 集群格式化:仅在NameNode首次启动时执行格式化(通过环境变量控制)
4. 启动与验证集群
4.1 一键启动集群
docker-compose up -d
启动后可以通过以下命令查看服务状态:
docker-compose ps
4.2 集群健康检查
- HDFS检查:
docker-compose exec namenode hdfs dfsadmin -report
应该能看到两个DataNode正常注册
- YARN检查:
docker-compose exec resourcemanager yarn node -list
应该能看到NodeManager节点
- Web UI验证:
- HDFS: http://localhost:50070
- YARN: http://localhost:8088
4.3 运行测试作业
让我们运行一个经典的WordCount示例:
# 创建输入目录
docker-compose exec namenode hdfs dfs -mkdir -p /input
# 上传测试文件
echo "hello docker hadoop hello compose" > test.txt
docker-compose exec namenode hdfs dfs -put test.txt /input/
# 运行WordCount
docker-compose exec namenode hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount /input /output
# 查看结果
docker-compose exec namenode hdfs dfs -cat /output/*
5. 高级配置与优化
5.1 动态扩展节点
增加DataNode非常简单,只需在docker-compose.yml中添加:
datanode3:
image: my-hadoop:3.3.4
hostname: datanode3
depends_on:
- namenode
volumes:
- datanode3-data:/hadoop/data
command: >
bash -c "
$HADOOP_HOME/bin/hdfs datanode &&
tail -F $HADOOP_HOME/logs/hadoop-root-datanode-*.log
"
然后更新volumes部分并运行:
docker-compose up -d
新节点会自动加入集群,可以通过hdfs dfsadmin -report验证。
5.2 资源配置调优
可以通过resources限制容器资源:
namenode:
image: my-hadoop:3.3.4
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
5.3 配置文件挂载
对于需要频繁修改的配置文件,建议挂载到容器中:
volumes:
- ./config/core-site.xml:$HADOOP_HOME/etc/hadoop/core-site.xml
- ./config/hdfs-site.xml:$HADOOP_HOME/etc/hadoop/hdfs-site.xml
6. 常见问题排查
6.1 NameNode无法启动
症状:50070端口无法访问,日志显示格式化错误 解决方法:
- 停止集群:docker-compose down
- 删除数据卷:docker volume prune
- 重新启动:docker-compose up -d
6.2 DataNode无法注册
症状:hdfs dfsadmin -report显示缺少节点 解决方法:
- 检查DataNode日志:docker-compose logs datanode1
- 常见原因是网络连接问题,确保容器间可以互相通信
- 检查NameNode的hosts文件是否包含所有节点
6.3 资源不足错误
症状:作业运行失败,日志显示内存不足 解决方法:
- 调整YARN配置:
<!-- yarn-site.xml -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>2048</value>
</property>
- 或者增加容器资源限制(如5.2节所示)
7. 生产环境建议
经过多个项目的实践验证,我总结出以下几点生产环境注意事项:
- 数据持久化:考虑使用外部存储卷(NFS、云存储等)替代本地Docker卷
- 监控集成:建议配置Prometheus+Grafana监控Hadoop和容器指标
- 安全加固:
- 禁用root登录
- 配置Kerberos认证
- 使用网络策略限制容器间通信
- 备份策略:定期备份NameNode元数据
- 版本控制:将docker-compose.yml和配置文件纳入Git管理
我在金融行业的一个项目中,使用这种方案部署的Hadoop集群已经稳定运行超过18个月,期间仅因硬件故障进行过一次迁移,整个迁移过程只用了不到2小时。
更多推荐
所有评论(0)