基于 Dockerfile 的 Hadoop 生态集成镜像

想直接用平台源码里已打包好的大数据 notebook 镜像(开箱即用,自带 Spark/Flink 示例)时读这篇;也包含该镜像的构建方式

平台使用 / 在线开发
Dockerfilebigdata集成镜像大数据镜像jupyter-ubuntu-bigdatainit.shbuild.shSparkFlinkHiveYarnexamples开箱即用

基于 Dockerfile 的 Hadoop 生态集成镜像(bigdata)

平台源码里已经把整套 Hadoop 生态(Spark / Flink / Hive / Hadoop / Maven / JDK8)打进了 bigdata 镜像,开箱即用。源码目录:images/jupyter-notebook/bigdata/

本文内容已与当前源码核实(images/jupyter-notebook/bigdata/Dockerfileinit.shbuild.sh)。原始教程基于旧版 hadoop/Dockerfile-ubuntu-hadooprun-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

主要变化(相对旧版教程):

  • 基础镜像 notebooknotebook-enterprise
  • 版本升级:Spark 3.4.3 / Flink 1.17.0 / Hadoop 3.3.6 / Hive 3.1.3 / Maven 3.8.8;
  • 各组件 HOME 与 PATHPYTHONPATH 全部用 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 控制器注入的环境变量(PORT1PORT2SERVICE_EXTERNAL_IPNOTEBOOK_NAMEUSERNAMESSH_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.xmlhdfs-site.xmlyarn-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.ipynbpyspark_local_hive.ipynbpyspark_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 界面上看到提交过去的作业。

Yarn 提交的作业

2.3 测试 Flink

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

最后更新 2026-06-30完整文档以官方仓库为准:GitHub Wiki