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 关键配置解析

这个配置文件有几个精妙之处值得说明:

  1. 服务依赖:通过depends_on确保NameNode先于DataNode启动,ResourceManager先于NodeManager启动
  2. 数据持久化:使用命名卷(namenode-data等)保存HDFS数据,即使容器重启数据也不会丢失
  3. 日志跟踪:tail -F命令保持容器运行并实时输出日志到控制台
  4. 集群格式化:仅在NameNode首次启动时执行格式化(通过环境变量控制)

4. 启动与验证集群

4.1 一键启动集群

docker-compose up -d

启动后可以通过以下命令查看服务状态:

docker-compose ps

4.2 集群健康检查

  1. HDFS检查
docker-compose exec namenode hdfs dfsadmin -report

应该能看到两个DataNode正常注册

  1. YARN检查
docker-compose exec resourcemanager yarn node -list

应该能看到NodeManager节点

  1. 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端口无法访问,日志显示格式化错误 解决方法:

  1. 停止集群:docker-compose down
  2. 删除数据卷:docker volume prune
  3. 重新启动:docker-compose up -d

6.2 DataNode无法注册

症状:hdfs dfsadmin -report显示缺少节点 解决方法:

  1. 检查DataNode日志:docker-compose logs datanode1
  2. 常见原因是网络连接问题,确保容器间可以互相通信
  3. 检查NameNode的hosts文件是否包含所有节点

6.3 资源不足错误

症状:作业运行失败,日志显示内存不足 解决方法:

  1. 调整YARN配置:
<!-- yarn-site.xml -->
<property>
  <name>yarn.nodemanager.resource.memory-mb</name>
  <value>2048</value>
</property>
  1. 或者增加容器资源限制(如5.2节所示)

7. 生产环境建议

经过多个项目的实践验证,我总结出以下几点生产环境注意事项:

  1. 数据持久化:考虑使用外部存储卷(NFS、云存储等)替代本地Docker卷
  2. 监控集成:建议配置Prometheus+Grafana监控Hadoop和容器指标
  3. 安全加固
    • 禁用root登录
    • 配置Kerberos认证
    • 使用网络策略限制容器间通信
  4. 备份策略:定期备份NameNode元数据
  5. 版本控制:将docker-compose.yml和配置文件纳入Git管理

我在金融行业的一个项目中,使用这种方案部署的Hadoop集群已经稳定运行超过18个月,期间仅因硬件故障进行过一次迁移,整个迁移过程只用了不到2小时。

更多推荐