本文csdn地址
项目地址
docker-centos
背景
在完成几个开源中间件的容器化一键部署之后,和一个同事聊到了关于如何在本地部署 hadoop 集群,方便进行大数据任务相关的测试
后面我们一起搜了一些资料,在知乎[1]上找到有人弄好了一套镜像[2], 功能应该是比较完善的,只是稍微有一点不足是没有支持 arm 版本
所以之后那位同事还是用虚拟机的方式,手动部署 Hadoop 搭建好了本地测试集群,省不了的是一些手动配置的操作,虽然也不会太复杂
而自己的想法是: 既然已经接触了除了 hdfs 之外的上层应用,比如 knox、ranger 等,是否可以按照之前部署 zk 集群的思路[3],把 hadoop 基础集群也写到 docker compose 里面呢?
于是,接近两个月的各种踩坑和实践开始了
效果
服务部署
两种部署方式: 从头开始搭建镜像 再启动服务 or 直接从 dockerhub 拉取镜像并启动服务,通过前者有助于你了解镜像结构,但是如果是想快速部署服务建议参考后者
【建议】直接拉取镜像:
为了方便使用,我已经将镜像提交到 dockerhub (mzsmieli/centos_hdfs_full),直接拉取并启动即可
1 2 3 4 5 6
| # 下载镜像 docker pull mzsmieli/centos_hdfs_full:v1.0.0 docker pull mzsmieli/centos_mysql:v1.0.0
# 运行hdfs集群 REPO=mzsmieli make run_hdfs_cluster
|
构建镜像:
下载工程 docker-centos 后,需要依次准备以下镜像:
- centos_base
- centos_java
- centos_hdfs
- hdfs 基础镜像,包含 hadoop 服务,依赖 java 镜像
- centos_hive
- hive 基础镜像,包含 hadoop、hive 服务,依赖 hdfs 镜像
- centos_knox
- centos_hdfs_full
- 完整 hadoop 镜像,在 hdfs+hive+knox 基础上提供 flink、spark
- centos_minimal
- centos_mysql
镜像整体架构图:
概括来说就是 centos 基础镜像 -> 各语言开发镜像 -> 服务镜像
完整指令:
1 2 3 4 5
| # 构建镜像(首次构建所有镜像大约需要半个小时) make build_hdfs_cluster
# 运行hdfs集群 make run_hdfs_cluster
|
端口和地址说明:
- 8443: knox 网关地址
- 8088: hdfs resourcemanager web 地址(yarn)
- 50070: hdfs namenode web 地址(data)
- 10000: hive server 地址
- 33306: mysql 端口
hdfs
yarn
flink、spark
提交任务这块做了简单的提交验证
提交 flink 任务:
1 2
| cd /opt/modules/flink-1.15.0 ./bin/flink run -m yarn-cluster ./examples/batch/WordCount.jar
|
提交 spark 任务:
1
| /opt/modules/spark/bin/spark-submit --master yarn --deploy-mode cluster --class org.apache.spark.examples.SparkPi /opt/modules/spark/examples/jars/spark-examples_2.12-3.2.2.jar 100
|
hive
hive 可通过 开源数据库客户端工具,dbeaver[4] 直接连接,注意需要填用户名,否则可能会因为权限问题无法执行 SQL
实现
组件版本
hdfs - 3.3.2
knox - 1.6.1
hive - 3.1.2
flink - 1.15
spark - 3.2
其中 knox[5] 是大数据组件通用的网关服务,可以用于配置统一代理、身份认证、单点登录等,一般是刚搭建大数据集群的时候需要装,后续就不需要怎么管了。其他服务比较核心
hadoop
基本的安装和配置,参考网上的教程[6]做就行。为了能在一个镜像中同时支持单点和集群启动,dockerfile 中做了通过识别容器启动环境参数,进行不同的初始化和服务启动的功能:在容器的启动参数中指定 -e HDFS_START=hdfsstart / hdfsstartall,即可区分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # Dockerfiles/emr/hdfs/scripts/hdfs-start.sh # 单点启动 hdfs 服务脚本
## 服务启动指令(本地启动 namenode、datanode、resourcemanager) ./sbin/start-dfs.sh ./sbin/start-yarn.sh
# Dockerfiles/emr/hdfs/scripts/hdfs-start-all.sh # 启动 hdfs 集群脚本
## 配置: /etc/hadoop/conf/workers hadoop2 hadoop3
## 服务启动指令(主节点启动 namenode、resourcemanager,worker 节点启动 datanode、nodemanager) ./sbin/start-all.sh
|
knox
knox 主要是配置需要留意,大体分为 knox 本身的服务配置、网关配置 和 代理的服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| # knox配置 ## /opt/modules/knox/conf/gateway-site.xml ### 禁用 ssl 和 身份认证,方便调试 <property> <name>ssl.enabled</name> <value>false</value> </property>
<provider> <role>identity-assertion</role> <name>Default</name> <enabled>disable</enabled> </provider>
# 网关配置 ## /opt/modules/knox/conf/topologies/sandbox.xml ### hdfs 和 yarn 地址,因为 namenode 和 knox 都部署在主节点,所以这里配的都是 localhost <service> <role>HDFSUI</role> <url>http://localhost:50070</url> <version>2.7.0</version> </service>
<service> <role>YARNUI</role> <url>http://localhost:8088</url> </service>
# 代理服务配置 ## /opt/modules/knox/data/services/hdfsui/2.7.0/rewrite.xml ### 这里需要加个规则: 因为 hdfs 的 index.html 页面实际是一个 跳转页面(<a> 元素),而直接访问 ### 这个地址会被链接到容器环境内部域名(hadoop1),而不是外部域名(localhost:8443)导致在外部访问跳转失败 ### 因此一个最直接的解决方式就是将 index.html 直接链接到 dfshealth.html 让 knox 帮我们做这个跳转,保持外部域名(gateway.url)
<rule dir="OUT" name="HDFSUI/redirect" pattern="/index.html"> <rewrite template="{gateway.url}/hdfs/dfshealth.html"/> </rule>
|
hive
hive 服务启动前,需要做初始化 mysql 的操作,涉及到两个细节:hive 初始化脚本 init-hive.sh 中,需要执行 schematool 进行元数据初始化;compose 文件中也要定义 主节点,也是 hive 启动的节点,需要依赖 mysql 容器(depends_on)
compose
各个组件都准备完成后,对 compose 配置文件的编写主要就是设置容器启动的环境变量了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| version: "3.9" services: hadoop1: image: ${HDFS_FULL_IMAGE} hostname: hadoop1 environment: - DEFAULTFS=hdfs://hadoop1:8020 - DFS_REPLICATION=2 - RESOURCEMANAGER_HOSTNAME=hadoop1 - WORKERS=hadoop2,hadoop3 - HDFS_START=hdfsstartall - KNOX_START=knoxstart - HIVE_START=hivestart - mysql_host=mysql - mysql_port=3306 - mysql_db=hive - mysql_user=root - mysql_pwd=root_HADOOP_123 ports: - "8443:8443" - "8088:8088" - "50070:50070" - "10000:10000" depends_on: - hadoop2 - hadoop3 - mysql hadoop2: image: ${HDFS_FULL_IMAGE} hostname: hadoop2 environment: - DEFAULTFS=hdfs://hadoop1:8020 - DFS_REPLICATION=2 - RESOURCEMANAGER_HOSTNAME=hadoop1 - WORKERS=hadoop2,hadoop3 - HDFS_START=hdfsnotstart hadoop3: image: ${HDFS_FULL_IMAGE} hostname: hadoop3 environment: - DEFAULTFS=hdfs://hadoop1:8020 - DFS_REPLICATION=2 - RESOURCEMANAGER_HOSTNAME=hadoop1 - WORKERS=hadoop2,hadoop3 - HDFS_START=hdfsnotstart mysql: image: ${MYSQL_IMAGE} ports: - "33306:3306" environment: - ROOT_PASSWORD=root_HADOOP_123
|
提交镜像
在实践的过程中发现 基于 Dockerfile 在分享上也不是特别方便,比如新来的同学想使用 dev_full 完整开发镜像,他还需要在自己的电脑上先重新构建一次镜像。更好的方法还是通过镜像仓库直接分享镜像
因此后面把自己的镜像都提交到了 dockerhub 中,包括之前做的 easyconnect[7] 代理镜像、dev_full[8] 包含多种开发语言的开发镜像
构建方式: 通过 buildx[9] 工具构建
1 2
| # 示例: 构建并提交 base 镜像,同时构建 arm 和 amd 版本 docker buildx build --platform linux/arm64,linux/amd64 --no-cache -f ./Dockerfiles/system/centos_base.Dockerfile -t dockerhub账号名/centos_base:v1.0 ./Dockerfiles/system --push
|
在 dockerhub 查看刚提交的镜像:
扩展: 运行 easyconnect 镜像
1 2 3 4 5 6 7 8
| # 使用 easyconnect 镜像 REPO=mzsmieli make run_rc # 将下载 mzsmieli/centos_easyconnect:v1.0.0
# 完整指令 docker pull mzsmieli/centos_easyconnect:v1.0.0 docker run -it -d --privileged=true --platform linux/amd64 --hostname test_ec --name dev_ec -p 3389:3389 -p 7881:7881 mzsmieli/centos_easyconnect:v1.0.0 /usr/sbin/init # vnc 默认密码: root/root_123
|
后言
坚信搞好属于自己的一套开发环境是学习任何新技术的基础,工欲善其事,必先利其器
这篇博客也仅仅是将个人习惯的开发环境 分享一下,每个人肯定都有自己的习惯,不存在谁比谁更好,只要能达到自己想要的学习效果,都是好方法。开发镜像也是,IDE 也是,开发语言也是。总是陷入对 世界上最好语言的争论,真的没必要
当然,在自己整完这些东西之后,再次感觉到 应该喘口气,思考自己想做的下个东西是什么了
资料
[1] 使用 Docker 快速部署 Spark + Hadoop 大数据集群
[2] git-spark-hadoop-docker
[3] 通过 Docker Compose 本地启动 zk 集群
[4] dbeaver
[5] knox官方文档
[6] Hadoop集群的部署(二)
[7] EasyConnect 代理工具容器化运行
[8] dev_full image
[9] docker buildx