基于 Dockerfile 的 Hadoop 生态集成镜像(bigdata)
平台源码里已经把整套 Hadoop 生态(Spark / Flink / Hive / Hadoop / Maven / JDK8)打进了 bigdata 镜像,开箱即用。源码目录:images/jupyter-notebook/bigdata/。
本文内容已与当前源码核实(
images/jupyter-notebook/bigdata/Dockerfile、init.sh、build.sh)。原始教程基于旧版hadoop/Dockerfile-ubuntu-hadoop与run-jupyter.sh,相关命名/版本已更新如下。
一、Dockerfile 与启动脚本
1.1 Dockerfile(节选,以源码为准)
当前 images/jupyter-notebook/bigdata/Dockerfile 通过 ARG 统一管理版本,并直接安装 Hadoop / Hive / Spark / PyFlink:
FROM ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-base
ARG TARGETARCH
ARG SPARK_HADOOP_VERSION=3
ARG SPARK_VERSION=3.4.3
ARG FLINK_VERSION=1.17.0
ARG MAVEN_VERSION=3.8.8
ARG APACHE_MIRROR=https://mirrors.aliyun.com/apache
ARG JDK_VERSION=8
RUN apt update -y && apt install -y lsof
# 安装大数据 python 包(爬虫 / 数据库查询 / 数据挖掘 / 可视化等,详见源码)
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
# ... pip install pymysql/pyhive/presto-python-client/clickhouse-driver/pandas/scikit-learn/... ...
# 安装 java8
RUN rm -rf /usr/lib/jvm/ && apt-get install -y openjdk-${JDK_VERSION}-jdk
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-${TARGETARCH}
WORKDIR /opt/third/
# 安装 maven
RUN wget ${APACHE_MIRROR}/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
&& tar -xvzf apache-maven-${MAVEN_VERSION}-bin.tar.gz && mv apache-maven-${MAVEN_VERSION} maven \
&& rm -rf apache-maven-${MAVEN_VERSION}-bin.tar.gz
ENV M2_HOME=/opt/third/maven
# 安装 hadoop 3.3.6
RUN wget ${APACHE_MIRROR}/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz \
&& tar -zxvf hadoop-3.3.6.tar.gz -C /opt/third/ && rm hadoop-3.3.6.tar.gz \
&& mv /opt/third/hadoop-3.3.6 /opt/third/hadoop
ENV HADOOP_HOME=/opt/third/hadoop
ENV HADOOP_CONF_DIR=/opt/third/hadoop/etc/hadoop
ENV YARN_CONF_DIR=/opt/third/hadoop/etc/hadoop
# 安装 hive 3.1.3
RUN wget ${APACHE_MIRROR}/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz \
&& tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /opt/third/ && rm apache-hive-3.1.3-bin.tar.gz \
&& mv apache-hive-3.1.3-bin /opt/third/hive
ENV HIVE_HOME=/opt/third/hive
ENV HIVE_CONF_DIR=/opt/third/hive/conf
# 下载 apache spark 安装包
RUN wget ${APACHE_MIRROR}/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz \
&& tar -xvzf spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz \
&& mv spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION} spark \
&& rm -rf spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz
ENV SPARK_HOME=/opt/third/spark
# 安装 pyflink
RUN pip install apache-flink==${FLINK_VERSION}
# 拷贝 examples 与示例的 hadoop/hive/spark/flink 配置
COPY examples/* /examples/
COPY maven/conf/settings.xml /opt/third/maven/conf/settings.xml
COPY conf/hive/* /opt/third/hive/conf/
COPY conf/hadoop/* /opt/third/hadoop/etc/hadoop/
COPY conf/spark/* /opt/third/spark/conf/
COPY conf/flink/flink-dep.xml /opt/third/flink/
# 设置环境变量到全局
ENV PATH=${PATH:-}:$JAVA_HOME/bin:$M2_HOME/bin:$HADOOP_HOME/bin:$HIVE_HOME/bin:$SPARK_HOME/bin
ENV PYTHONPATH=${SPARK_HOME}/python:${SPARK_HOME}/python/lib/py4j-0.10.9.7-src.zip:${SPARK_HOME}/python/lib/pyspark.zip:${PYTHONPATH:-}
# 环境初始化配置
COPY init.sh /init.sh
主要变化(相对旧版教程):
- 基础镜像
notebook→notebook-enterprise; - 版本升级:Spark 3.4.3 / Flink 1.17.0 / Hadoop 3.3.6 / Hive 3.1.3 / Maven 3.8.8;
- 各组件 HOME 与
PATH、PYTHONPATH全部用ENV固化进镜像,无需再手动findspark.init()或改 python 软链; - 配置文件目录从源码
conf/{hadoop,hive,spark,flink}直接COPY进镜像,可启动后再覆盖。
1.2 启动脚本 init.sh(以源码为准)
旧版 run-jupyter.sh 接收宿主机 IP 作为 $1 并硬编码端口 32788/32789;当前 images/jupyter-notebook/bigdata/init.sh 改为读取由 notebook 控制器注入的环境变量(PORT1、PORT2、SERVICE_EXTERNAL_IP、NOTEBOOK_NAME、USERNAME、SSH_PORT):
#!/bin/bash
# 配置 spark-defaults.conf(端口与 driver host 由控制器注入的环境变量决定)
echo "spark.ui.enabled=false" >> ${SPARK_HOME}/conf/spark-defaults.conf
echo "spark.driver.port=${PORT1}" >> ${SPARK_HOME}/conf/spark-defaults.conf
echo "spark.blockManager.port=${PORT2}" >> ${SPARK_HOME}/conf/spark-defaults.conf
echo "spark.driver.bindAddress=0.0.0.0" >> ${SPARK_HOME}/conf/spark-defaults.conf
echo "spark.driver.host=${SERVICE_EXTERNAL_IP}" >> ${SPARK_HOME}/conf/spark-defaults.conf
# (另含配置 ssh、软链 /examples 等,详见源码)
说明(与源码核对):旧教程里
docker run ... <镜像> xxx.xxx.xxx.xxx(把宿主机 IP 作为参数传给 run-jupyter.sh)的用法已不适用——当前init.sh不再接收位置参数,而是依赖平台 notebook 控制器注入的PORT1/PORT2/SERVICE_EXTERNAL_IP等环境变量(见images/jupyter-notebook/bigdata/init.sh)。该镜像主要作为平台 notebook 镜像使用;若要docker run独立启动,需要自行提供这些环境变量。
1.3 构建命令
依据 images/jupyter-notebook/bigdata/build.sh:
# 在 images/jupyter-notebook/bigdata 目录下
hubhost=ccr.ccs.tencentyun.com/cube-studio
TARGETARCH=amd64
docker build --network=host -t $hubhost/notebook-enterprise:jupyter-ubuntu-bigdata-$TARGETARCH -f Dockerfile .
docker push $hubhost/notebook-enterprise:jupyter-ubuntu-bigdata-$TARGETARCH
该镜像的构建/管理也可走平台的在线构建能力,参见 04-镜像构建与仓库 / 镜像在线构建和管理 与 06-二次开发 段。
二、使用集成镜像
2.1 上传集群配置文件
/opt/third/hadoop/etc/hadoop 和 /opt/third/hive/conf 已自带默认配置文件(源码 conf/ 目录),可以直接修改其中参数,或按下面步骤上传覆盖。
上传 Hadoop 配置文件:在 Web 界面中上传 core-site.xml、hdfs-site.xml、yarn-site.xml 到 /opt/third/hadoop/etc/hadoop 目录下。注意检查 yarn-site.xml 一定要有 yarn.resourcemanager.address 配置项,否则默认值 0.0.0.0:8032 会导致作业无法提交到 Yarn:
<property>
<name>yarn.resourcemanager.address</name>
<value>xxx.xxx.xxx.xxx:8032</value>
</property>
上传 Hive 配置文件:在 Web 界面中上传 hive-site.xml 到 /opt/third/hive/conf 目录下。
2.2 测试 Spark
因为镜像启动时已设置好相关环境变量,代码中无需再设置环境变量或使用 findspark。/examples 目录下已内置示例(pyspark_local.ipynb、pyspark_local_hive.ipynb、pyspark_yarn.ipynb),可直接运行。
本地运行 pyspark_local.ipynb:
from random import random
from operator import add
from pyspark.sql import SparkSession
if __name__ == "__main__":
spark = SparkSession \
.builder \
.appName("PythonPi-Local") \
.master("local") \
.getOrCreate()
n = 100000 * 2
def f(_):
x = random() * 2 - 1
y = random() * 2 - 1
return 1 if x ** 2 + y ** 2 <= 1 else 0
count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add)
print("Pi is roughly %f" % (4.0 * count / n))
spark.stop()
本地运行访问 Hive pyspark_local_hive.ipynb:
from pyspark.sql import SparkSession
if __name__ == "__main__":
spark = SparkSession.builder \
.appName('spark-hive-demo') \
.config("hive.metastore.uris", "thrift://xxx.xxx.xxx.xxx:9083") \
.enableHiveSupport() \
.getOrCreate()
spark.sql("create table if not exists demo(id bigint,name String)")
spark.sql("insert overwrite demo values (1,'hamawhite'),(2,'song.bs')")
spark.sql("select * from demo").show()
其中 xxx.xxx.xxx.xxx:9083 是 Hive MetaStore 的地址。
Yarn-client 模式运行 pyspark 作业 pyspark_yarn.ipynb:
from random import random
from operator import add
from pyspark.sql import SparkSession
if __name__ == "__main__":
spark = SparkSession \
.builder \
.appName("PythonPi-Yarn-Client-Dockerfile") \
.master("yarn") \
.config("spark.submit.deployMode", "client") \
.getOrCreate()
n = 100000 * 2
def f(_):
x = random() * 2 - 1
y = random() * 2 - 1
return 1 if x ** 2 + y ** 2 <= 1 else 0
count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add)
print("Pi is roughly %f" % (4.0 * count / n))
spark.stop()
可以在 Yarn Web 界面上看到提交过去的作业。

2.3 测试 Flink
与手动安装路线的测试方法类似(见 02-手动安装:Flink 配置与测试)。/examples 目录下已内置 pyflink_sql.ipynb、pyflink_sql_hivecatalog.ipynb 等示例,可直接运行。