Dockerfile 构建 hadoop 集群
这里构建 hadoop 最新版本的集群 hadoop-3.3.6,只用到 hdfs。
一、构建 Hadoop 基础镜像
1.1 编写 dockerfile
FROM centos:centos7.9.2009
# 更新/安装需要的系统实用程序
# RUN指令用来执行一些命令,这些命令会在构建镜像时运行,并且会影响镜像的内容
RUN apt update && apt install -y arp-scan python3
# 设置需要的 ENV 变量或
# ENV指令用来设置环境变量,这些变量会在构建镜像和运行容器时生效
ENV JDK_VER=11.0.20
ENV HADOOP_VER=3.3.6
ENV JDK_TAR_NAME=jdk.tar.gz
ENV HADOOP_TAR_NAME=hadoop.tar.gz
# WORKDIR 指令就相当于 cd 到指定目录,然后执行后续操作
WORKDIR /opt
# 将 Hadoop 二进制文件和 Java 二进制文件提取到路径并设置环境变量。
# ADD指令用来把本地的文件或者URL的文件复制到镜像中。如果复制的是压缩文件,它会自动解压。
# 注意本地的文件名需要和 JDK_TAR_NAME 环境变量一致
ADD ./assets/${JDK_TAR_NAME} .
ADD ./assets/${HADOOP_TAR_NAME} .
# 将 java 添加到路径中
ENV JAVA_HOME=/opt/jdk-${JDK_VER}
ENV PATH=$PATH:$JAVA_HOME:$JAVA_HOME/bin
# 将 hadoop 添加到路径中
ENV HADOOP_HOME=/opt/hadoop-${HADOOP_VER}
ENV HADOOP_STREAMING_JAR=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-${HADOOP_VER}.jar
ENV PATH=$PATH:$HADOOP_HOME
ENV PATH=$PATH:$HADOOP_HOME/bin
# 将我们在不同文件夹中准备的配置文件复制到最近提取的 Hadoop 路径中。
ADD ./config-files/hadoop-env.sh $HADOOP_HOME/etc/hadoop/
ADD ./config-files/core-site.xml $HADOOP_HOME/etc/hadoop/
1.2 基础镜像的配置
Hadoop 基础镜像的配置文件是 core-site.xml
。这个文件包含了整个 Hadoop 安装的全局配置。你可以在这里或者在它自己的单独配置文件 hdfs-site.xml 中进行 HDFS 的配置。
fs.defaultFS
hdfs://namenode:8020
hdfs://host:port
URI of namenode. need for datanodes to connect to namenode.
hostname is required, IP won't work, spent 3hrs before figuring this out.
ADD SAME HOST AS THE MACHINE WHERE YOU ARE RUNNING YOUR NAMENODE
DEFAULT PORT IS 8020
- fs.defaultFS 是 Hadoop 文件系统的默认 URI,用来指定 NameNode 的位置,让 DataNode 和客户端能够连接到 NameNode。
- value 是 hdfs://namenode:8020,表示 NameNode 的主机名是 namenode,端口号是 8020。注意使用主机名,好维护。
- description 是对这个属性的说明,提醒用户如果在这里修改了 value,也要在启动 Docker 容器的脚本中修改相应的主机名。默认的端口号是 8020。
所有与 YARN 或 Hadoop 核心相关的配置都应该放在这里。
还有一个文件是 hadoop-env.sh
。该文件与 Hadoop 二进制文件一起提供。您只需要取消注释所需的任何内容即可。这里必须指定一件事,即补全并取消注释 export JAVA_HOME
这一行。
1.3 构建镜像
- 我们不会将此镜像直接作为容器运行,因此无需添加
CMD
- 运行:
docker build . -t hadoop-base:3.3.6
二、构建 NameNode 镜像
2.1 编写 dockerfile
要构建 NameNode 镜像,请执行以下操作:
-
我们从之前构建的
hadoop_base:1
映像开始 -
我们需要为 NameNode 创建一个目录来存储它的文件,稍后在 NameNode 的配置文件中指定这个目录
RUN mkdir /opt/hdfs RUN mkdir /opt/hdfs/namenode
-
然后添加配置文件
ADD ./config-files/hdfs-site.xml $HADOOP_HOME/etc/hadoop/
-
此命令应运行一次,以便 NameNode 正常工作
RUN hdfs namenode -format
-
添加要在启动容器时运行的命令。该命令是运行 NameNode 进程
CMD hdfs namenode
这个也可以在启动容器时定义
-
构建
docker build . -t namenode:latest
2.2 NameNode 的配置
如前所述,HDFS(NameNode 和 DataNode)的配置可以在不同的 core-site.xml
文件中完成,或者 hdfs-site.xml
我更喜欢将它们保存在不同的文件中。
dfs.namenode.name.dir
/opt/hdfs/namenode
dfs.blocksize
128
dfs.namenode.handler.count
4
在这里,我们指定 NameNode 存储元数据的目录、块大小和处理线程计数。
三、构建 DataNode 镜像
3.1 编写 dockerfile
要构建数据节点映像,请执行以下操作:
-
DataNode实际上与NameNode相同。唯一的区别是我们必须为此启动一个不同的过程。因此,我们从自身构建
namenode:latest
。FROM namenode:latest RUN mkdir /opt/hdfs/datanode CMD hdfs datanode
-
生成镜像
docker build . -t datanode:latest
3.2 DataNode 的配置
DataNode 如果没有特殊要求,可以使用 NameNode 中配置的 dfs.blocksize
和 dfs.namenode.handler.count
参数,若有就按照 NameNode 的配置进行更改。我这里只指定 datanode
目录。
dfs.datanode.data.dir
/opt/hdfs/datanode
四、总结(赶时间可直接看)
因为 NameNode 和 DataNode 的区别不大,所以把公共部分抽取出来
目录结构:
.
├── assets
│ ├── hadoop.tar-3.3.6.gz
│ └── jdk-11.0.20+8.tar.gz
├── config-files
│ ├── core-site.xml
│ └── hadoop-env.sh
└── Dockerfile
构建基础的 hadoop 镜像
FROM centos:centos7.9.2009
# 更新/安装需要的系统实用程序
# RUN指令用来执行一些命令,这些命令会在构建镜像时运行,并且会影响镜像的内容
RUN yum update -y && yum install -y arp-scan python3
# 设置需要的 ENV 变量或
# ENV指令用来设置环境变量,这些变量会在构建镜像和运行容器时生效
ENV HADOOP_VER=3.3.6
ENV JDK_TAR_NAME=jdk-11.0.20+8.tar.gz
ENV HADOOP_TAR_NAME=hadoop-3.3.6.tar.gz
# WORKDIR 指令就相当于 cd 到指定目录,然后执行后续操作
WORKDIR /opt
# 将 Hadoop 二进制文件和 Java 二进制文件提取到路径并设置环境变量。
# ADD指令用来把本地的文件或者URL的文件复制到镜像中。如果复制的是压缩文件,它会自动解压。
# 注意本地的文件名需要和 JDK_TAR_NAME 环境变量一致
ADD ./assets/${JDK_TAR_NAME} .
ADD ./assets/${HADOOP_TAR_NAME} .
# 将 java 添加到路径中
ENV JAVA_HOME=/opt/${JDK_TAR_NAME}
ENV PATH=$PATH:$JAVA_HOME:$JAVA_HOME/bin
# 将 hadoop 添加到路径中
ENV HADOOP_HOME=/opt/hadoop-${HADOOP_VER}
ENV HADOOP_STREAMING_JAR=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-${HADOOP_VER}.jar
ENV PATH=$PATH:$HADOOP_HOME
ENV PATH=$PATH:$HADOOP_HOME/bin
# 将我们在不同文件夹中准备的配置文件复制到最近提取的 Hadoop 路径中。
ADD ./config-files/hadoop-env.sh $HADOOP_HOME/etc/hadoop/
ADD ./config-files/core-site.xml $HADOOP_HOME/etc/hadoop/
# 创建 NameNode 和 DataNode 存放数据的目录
RUN mkdir /opt/hdfs
RUN mkdir /opt/hdfs/namenode
RUN mkdir /opt/hdfs/datanode
# 此命令应运行一次,以便 NameNode 正常工作
RUN hdfs namenode -format
# 暴露端口
EXPOSE 9870 8020
输入命令:docker build . -t hadoop-base:3.3.6
构建
hadoop-env.sh
只需把 export JAVA_HOME
补全并取消注释
core-site.xml
配置文件
dfs.nameservices
hadoop-cluster
fs.defaultFS
hdfs://namenode:8020
dfs.namenode.name.dir
/opt/hdfs/namenode
dfs.blocksize
64000000
dfs.namenode.handler.count
4
dfs.datanode.data.dir
/opt/hdfs/datanode
创建 compose
namenode:
image: hadoop-base:3.3.6
hostname: namenode
ports:
- 9870:9870
- 8020:8020
volumes:
- ./hadoop/name-node:/opt/hdfs/namenode
env_file:
- ./hadoop.env
command: [ "hdfs", "namenode" ]
datanode1:
image: hadoop-base:3.3.6
hostname: datanode1
volumes:
- ./hadoop/data-node1:/opt/hdfs/datanode
depends_on:
- namenode
command: [ "hdfs", "datanode" ]
env_file:
- ./hadoop.env
datanode2:
image: hadoop-base:3.3.6
hostname: datanode2
volumes:
- ./hadoop/data-node2:/opt/hdfs/datanode
depends_on:
- namenode
command: [ "hdfs", "datanode" ]
env_file:
- ./hadoop.env
注意坑:
- 下载的 jdk 文件名要与 dockerfile 中的环境变量要对应得上
- 环境变量的路径是否正确,ADD 将从本地或从链接下载并解压到构建的镜像中,解压后的目录是压缩包内的目录
- pull 的 centos 系统架构和 jdk 的架构是否对得上