本镜像基于bitnami/spark:3.5.0
镜像,系统为Debian 11
,执行用户为root
。
docker pull somebottle/haspark
面向本地集群环境测试,即伪分布式。
设计理念是简单配置,快速上线测试,因此配置项较少。
如果有增加配置项的需要,欢迎发Issue亦或者开Pull request!
- 支持 Hadoop HA(高可用)集群 的简单伪分布式环境部署。
- 本镜像配置完成,用
docker compose
部署上线容器后,能自动交换 SSH 公钥实现节点间 SSH 免密登录。 - 依赖于SSH的多节点进程启动同步机制:本镜像在进行多个容器上Hadoop组件部署的时候,可能会等待各节点相应进程全启动完毕再进入下一步。
在启动高可用集群的时候可能需要等待较长的一段时间。 - 本镜像在 WSL(Ubuntu22.04LTS) 上测试完成。
- Hadoop
3.3.6
- Spark
3.5.0
- Zookeeper
3.9.2
环境变量可以写成一个文件,和 docker-compose.yml
配合使用。
在 bitnami/spark
镜像的基础上,本镜像新增如下环境变量:
名称 | 说明 | 默认值 |
---|---|---|
SH_HOSTS |
集群中所有节点的主机名(必填),空格分隔 |
名称 | 说明 | 默认值 |
---|---|---|
HADOOP_LAUNCH_MODE |
Hadoop部署模式 - general (普通分布式)或ha (高可用分布式) |
"general" |
HADOOP_HDFS_REPLICATION |
HDFS副本数 | 2 |
HADOOP_MAP_MEMORY_MB |
为每个Map任务分配的内存量 (以MiB为单位) | 1024 |
HADOOP_REDUCE_MEMORY_MB |
为每个Reduce任务分配的内存量 (以MiB为单位) | 1024 |
名称 | 说明 | 默认值 |
---|---|---|
GN_NAMENODE_HOST |
HDFS NameNode所在主节点主机名 | 无 |
GN_HADOOP_WORKER_HOSTS |
空格分隔的HDFS从节点主机名列表 | 无 |
GN_DATANODE_ON_MASTER |
在HDFS NameNode所在节点上是否启动DataNode | "false" |
GN_SECONDARY_DATANODE_HOST |
Secondary Namenode所在结点的主机名,留空则不启动 | 无 |
GN_RESOURCEMANAGER_HOST |
Yarn ResourceManager所在节点 | 无 |
GN_NODEMANAGER_WITH_RESOURCEMANAGER |
在ResourceManager所在节点是否启动NodeManager | "false" |
GN_NODEMANAGER_WITH_RESOURCEMANAGER |
在ResourceManager所在节点是否启动NodeManager | "false" |
GN_HDFS_SETUP_ON_STARTUP |
是否在容器启动时自动启动HDFS各个节点的守护进程 | "false" |
GN_YARN_SETUP_ON_STARTUP |
是否在容器启动时自动启动Yarn各个节点的守护进程 | "false" |
GN_ZOOKEEPER_START_ON_STARTUP |
是否在容器启动时自动启动Zookeeper各个节点的守护进程 | "false" |
名称 | 说明 | 默认值 |
---|---|---|
HA_HDFS_NAMESERVICE |
HDFS高可用集群的服务名(逻辑地址) | "hacluster" |
HA_HDFS_SETUP_ON_STARTUP |
是否部署高可用 HDFS 集群 | "false" |
HA_NAMENODE_HOSTS |
需要启动NameNode的节点的主机名列表(空格分隔) | 空 |
HA_JOURNALNODE_HOSTS |
需要启动JournalNode的节点的主机名列表(空格分隔) | 空 |
HA_DATANODE_HOSTS |
需要启动DataNode的节点的主机名列表(空格分隔) | 空 |
HA_YARN_SETUP_ON_STARTUP |
是否部署高可用 Yarn 集群 | "false" |
HA_RESOURCEMANAGER_HOSTS |
需要启动ResourceManager的节点的主机名列表(空格分隔) | 空 |
HA_NODEMANAGER_HOSTS |
需要启动NodeManager的节点的主机名列表(空格分隔) | 空 |
除了 bitnami/spark
提供的只读环境变量外,本镜像还提供了:
(可以调用 source /etc/profile
来载入这些环境变量到当前 Shell 中)
名称 | 说明 |
---|---|
ZOOKEEPER_VER |
Zookeeper版本 |
ZOOKEEPER_HOME |
Zookeeper安装目录 |
ZOOKEEPER_CONF_DIR |
Zookeeper配置目录 |
ZOOKEEPER_DATA_DIR |
Zookeeper数据目录(zoo.cfg 中的dataDir 配置) |
HADOOP_VER |
Hadoop版本 |
HADOOP_HOME |
Hadoop安装目录 |
HADOOP_CONF_DIR |
Hadoop配置文件目录 |
HADOOP_LOG_DIR |
Hadoop日志目录 |
HDFS_SERVICE_ADDR |
HDFS 服务地址。示例: 普通分布式-> host:port ; HA 分布式-> mycluster |
ZOOKEEPER_QUORUM |
Zookeeper集群各节点地址,逗号分隔。示例: host1:2181,host2:2181,host3:2181 |
TEMP_PASS_FILE |
SSH 临时密码文件的路径,在 SSH 公钥自动交换完毕后此文件将被自动删除(可用于判断 SSH 服务是否就绪) |
INIT_FLAG_FILE |
容器初始化标记文件,在Hadoop初始化完毕后,此文件会被自动删除 |
在命令行执行jpsall
即可,脚本实际位于/opt/somebottle/haspark/tools/jpsall
。
命令行: zoo <start|stop|status>
脚本实际位于/opt/somebottle/haspark/tools/zoo
。
命令行:
- 启动集群中所有节点的相应守护进程:
start-dfs.sh | stop-dfs.sh | start-yarn.sh | stop-yarn.sh | start-all.sh | stop-all.sh
- 启动本机的相应守护进程:
start-dfs-local.sh | stop-dfs-local.sh | start-yarn-local.sh | stop-yarn-local.sh | start-all-local.sh | stop-all-local.sh
脚本实际位于/opt/somebottle/haspark/tools/
中。
本脚本用于测试Hadoop集群是否能正常工作。
命令行: test-wordcount.sh
脚本实际位于/opt/somebottle/haspark/tools/test-wordcount.sh
。
本脚本用于将某个节点上的文件同步到其他所有节点上(根据上面配置的 $SH_HOSTS
环境变量)。
命令行: xsync <文件名列表>
脚本实际位于/opt/somebottle/haspark/tools/xsync
。
docker pull somebottle/haspark[:tag]
[:tag]可选,默认为
latest
。
要快速部署伪分布式集群,可以使用Docker Compose工具。
示例配置如下,1 master + 2 worker的分配。
==> 展开查看 <==
version: '3'
services:
haspark-main:
image: somebottle/haspark:3.2.0
hostname: shmain
env_file: ./conf.env
environment:
- SPARK_MODE=master
volumes:
- haspark-hdfs-shmain-name:/root/hdfs/name # namenode数据
- haspark-hdfs-shmain-journal:/root/hdfs/journal
- haspark-hdfs-shmain-data:/root/hdfs/data
- ~/docker/spark/share:/opt/share # 三个容器映射到相同的共享目录
ports:
- '8080:8080'
- '8088:8088'
- '4040:4040'
- '8042:8042'
- '9870:9870'
- '19888:19888'
haspark-worker-1:
image: somebottle/haspark:3.2.0
hostname: shworker1
env_file: ./conf.env
environment:
- SPARK_MODE=worker
- SPARK_MASTER_URL=spark://shmain:7077
- SPARK_WORKER_MEMORY=1G
- SPARK_WORKER_CORES=1
volumes:
- ~/docker/spark/share:/opt/share
- haspark-hdfs-worker1-name:/root/hdfs/name # namenode数据
- haspark-hdfs-worker1-journal:/root/hdfs/journal
- haspark-hdfs-worker1-data:/root/hdfs/data # datanode数据
ports:
- '8081:8081'
haspark-worker-2:
image: somebottle/haspark:3.2.0
hostname: shworker2
env_file: ./conf.env
environment:
- SPARK_MODE=worker
- SPARK_MASTER_URL=spark://shmain:7077
- SPARK_WORKER_MEMORY=1G
- SPARK_WORKER_CORES=1
volumes:
- ~/docker/spark/share:/opt/share
- haspark-hdfs-worker2-name:/root/hdfs/name # namenode数据
- haspark-hdfs-worker2-journal:/root/hdfs/journal
- haspark-hdfs-worker2-data:/root/hdfs/data # datanode数据
ports:
- '8082:8081'
- '8089:8088'
- '9871:9870'
volumes:
haspark-hdfs-shmain-name:
haspark-hdfs-shmain-data:
haspark-hdfs-shmain-journal:
haspark-hdfs-worker1-name:
haspark-hdfs-worker1-data:
haspark-hdfs-worker1-journal:
haspark-hdfs-worker2-name:
haspark-hdfs-worker2-data:
haspark-hdfs-worker2-journal:
这其实就是本仓库的docker-compose.yml
,其搭配着conf.env
进行配置。
- 端口映射相关的配置可以参考这里。
本仓库的配置使得容器首次上线时,会创建几个Docker卷。
随后这些Docker卷会保持映射到HDFS的NameNode
和DataNode
目录(在HA集群下还有JournalNode
的数据目录),以实现HDFS数据持久化(除非你移除了这些卷)。
Docker Compose Volume配置文档:
https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose
在docker-compose.yml
所在目录中执行:
docker compose up -d # 守护模式启动
⚠️ 建议你在执行这一步前先在容器内调用stop-all.sh
脚本停止Hadoop集群。
在docker-compose.yml
所在目录中执行:
docker compose stop # 停止容器
docker compose start # 启动容器
在docker-compose.yml
所在目录中执行。
-
下线容器,保留HDFS数据:
⚠️ 建议你在执行这一步前先在容器内调用stop-all.sh
脚本停止Hadoop集群。docker compose down
-
如果你想把HDFS的数据连带清空:
(这个操作会把相关的Docker卷全部移除)
docker compose down -v # v代表volumes
你可以在集群任意一个节点上执行以下脚本。
Hadoop集群启动脚本:
start-all.sh
Hadoop集群停止脚本:
stop-all.sh
以下是本镜像创建的容器内部常用端口,你可以选择性地在docker-compose.yml
中将一些端口映射到宿主机。
注:本镜像采用的大多是默认端口。
端口 | 服务 |
---|---|
9870 |
Namenode WebUI(http) |
8088 |
Yarn ResourceManager WebUI(http) |
8042 |
Yarn NodeManager WebUI(http) |
19888 |
Yarn JobHistory WebUI(http) |
8020 |
fs.defaultFS 绑定到的端口;Namenode的RPC端口 |
8485 |
JournalNode的RPC端口 |
2181 |
Zookeeper对客户端开放的端口 |
更多默认端口可参考官方文档:
- https://hadoop.apache.org/docs/r3.3.6/hadoop-project-dist/hadoop-common/core-default.xml
- https://hadoop.apache.org/docs/r3.3.6/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
- https://hadoop.apache.org/docs/r3.3.6/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml
- https://hadoop.apache.org/docs/r3.3.6/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
- NameNode:
/root/hdfs/name
- DataNode:
/root/hdfs/data
- JournalNode:
/root/hdfs/journal
-> 建议挂载卷(Volume)到NameNode和DataNode以及JournalNode的目录上,可以保留HDFS的数据。
-> 尤其在高可用集群中,要注意根据NameNode和DataNode所在容器决定挂载规则。
-----> 比如在只有NameNode的节点上可以仅挂载NameNode的卷,但若同时还有DataNode,则也要挂载DataNode的卷。
- Hadoop的日志位于
/opt/hadoop/logs
目录。 - 容器启动时初始化的日志位于
/opt/somebottle/haspark/logs
目录,用于调试。
-
Default Ports Used by Hadoop Services (HDFS, MapReduce, YARN)
-
Hadoop 之 高可用不自动切换(ssh密钥无效 Caused by: com.jcraft.jsch.JSchException: invalid privatekey )
Apache License, Version 2.0