创建 Google Kubernetes Engine 自定义容器映像

您可以指定要与 GKE 上的 Managed Service for Apache Spark 搭配使用的自定义容器映像。您的自定义容器映像必须使用其中一个 Managed Service for Apache Spark on GKE 基础 Spark 映像

使用自定义容器映像

如需使用 Managed Service for Apache Spark on GKE 自定义容器映像,请在创建 Managed Service for Apache Spark on GKE 虚拟集群或向集群提交 Spark 作业时设置 spark.kubernetes.container.image property

  • gcloud CLI 集群创建示例:
    gcloud dataproc clusters gke create "${DP_CLUSTER}" \
        --properties=spark:spark.kubernetes.container.image=custom-image \
        ... other args ...
    
  • gcloud CLI 作业提交示例:
    gcloud dataproc jobs submit spark \
        --properties=spark.kubernetes.container.image=custom-image \
        ... other args ...
    

自定义容器映像要求和设置

基础映像

您可以使用 docker 工具根据已发布的任意 Managed Service for Apache Spark on GKE 基础 Spark 映像构建自定义 Docker。

容器用户

Managed Service for Apache Spark on GKE 以 Linux spark 用户身份通过 1099 UID 和 1099 GID 来运行 Spark 容器。使用 UID 和 GID 获得文件系统权限。 例如,如果您将映像中位于 /opt/spark/jars/my-lib.jar 中的 jar 文件添加为工作负载依赖项,则必须向 spark 用户授予该文件的读取权限。

组件

  • Java:JAVA_HOME 环境变量指向 Java 安装的位置。当前默认值为 /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64,可能会发生变化(如需了解最新信息,请参阅 Managed Service for Apache Spark 版本说明)。

    • 如果您自定义 Java 环境,请确保 JAVA_HOME 设置为正确的位置,并且 PATH 包含二进制文件的路径。
  • Python:GKE 上的 Managed Service for Apache Spark 基础 Spark 映像已在 /opt/conda 安装 Miniconda3。CONDA_HOME 指向此位置,${CONDA_HOME}/bin 包含在 PATH 中,并且 PYSPARK_PYTHON 设置为 ${CONDA_HOME}/python

    • 如果您自定义 Conda,请确保 CONDA_HOME 指向 Conda 主目录,${CONDA_HOME}/bin 包含在 PATH 中,并且 PYSPARK_PYTHON 设置为 ${CONDA_HOME}/python.

    • 您可以在默认基础环境中安装、移除和更新软件包,也可以创建新环境,但强烈建议该环境包含在基础容器映像的基础环境中安装的所有软件包。

    • 如果您向容器映像添加 Python 模块(例如包含实用程序函数的 Python 脚本),请将模块目录添加到 PYTHONPATH 中。

  • Spark:Spark 安装在 /usr/lib/spark 中,SPARK_HOME 指向此位置。Spark 无法自定义。如果更改了该字段,容器映像将被拒绝或无法正常运行。

    • 作业:您可以自定义 Spark 作业依赖项。SPARK_EXTRA_CLASSPATH 用于定义 Spark JVM 进程的额外类路径。建议:将 jar 放入 /opt/spark/jars 下,并将 SPARK_EXTRA_CLASSPATH 设置为 /opt/spark/jars/*

      如果您将作业 JAR 嵌入到映像中,建议使用 /opt/spark/job 作为目录。提交作业时,您可以使用本地路径(例如 file:///opt/spark/job/my-spark-job.jar)引用该作业。

    • Cloud Storage 连接器:Cloud Storage 连接器已安装在 /usr/lib/spark/jars 中。

    • 实用程序:必须使用 procpstini 实用程序软件包才能运行 Spark。这些实用程序包含在基础 Spark 映像中,因此自定义映像无需重新安装这些实用程序。

    • 入口点Managed Service for Apache Spark on GKE 会忽略对容器映像中的 ENTRYPOINTCMD 基元所做的任何更改。

    • 初始化脚本:您可以在 /opt/init-script.sh 中添加可选的初始化脚本。初始化脚本可以从 Cloud Storage 下载文件、在容器内启动代理、调用其他脚本以及执行其他启动任务。

      在启动 Spark 驱动程序、Spark 执行程序和其他进程之前,入口点脚本会使用所有命令行参数 ($@) 调用初始化脚本。初始化脚本可以根据第一个参数 ($1) 选择 Spark 进程的类型:可能的值包括 spark-submit(针对驱动程序容器)和 executor(针对执行程序容器)。

  • 配置:Spark 配置位于 /etc/spark/conf 下。SPARK_CONF_DIR 环境变量指向此位置。

    请勿在容器映像中自定义 Spark 配置。请改为通过 Managed Service for Apache Spark on GKE API 提交任何属性,原因如下:

    • 某些属性(例如执行器内存大小)是在运行时确定的,而不是在容器映像构建时间确定的;这些属性必须由 Managed Service for Apache Spark on GKE 注入。
    • GKE 上的 Managed Service for Apache Spark 对用户提供的属性施加了限制。GKE 上的 Managed Service for Apache Spark 会将 configMap 中的配置挂载到容器中的 /etc/spark/conf,从而替换映像中嵌入的设置。

基础 Spark 映像

Managed Service for Apache Spark 支持以下基础 Spark 容器映像:

  • Spark 3.5:${REGION}-docker.pkg.dev/cloud-dataproc/spark/dataproc_2.2

自定义容器映像构建示例

Dockerfile 示例

FROM us-central1-docker.pkg.dev/cloud-dataproc/spark/dataproc_2.0:latest

# Change to root temporarily so that it has permissions to create dirs and copy
# files.
USER root

# Add a BigQuery connector jar.
ENV SPARK_EXTRA_JARS_DIR=/opt/spark/jars/
ENV SPARK_EXTRA_CLASSPATH='/opt/spark/jars/*'
RUN mkdir -p "${SPARK_EXTRA_JARS_DIR}" \
    && chown spark:spark "${SPARK_EXTRA_JARS_DIR}"
COPY --chown=spark:spark \
    spark-bigquery-with-dependencies_2.12-0.22.2.jar "${SPARK_EXTRA_JARS_DIR}"

# Install Cloud Storage client Conda package.
RUN "${CONDA_HOME}/bin/conda" install google-cloud-storage

# Add a custom Python file.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"
COPY test_util.py "${PYTHONPATH}"

# Add an init script.
COPY --chown=spark:spark init-script.sh /opt/init-script.sh

# (Optional) Set user back to `spark`.
USER spark

构建容器映像

在 Dockerfile 目录中运行以下命令

  1. 设置映像(例如 us-central1-docker.pkg.dev/my-project/spark/spark-test-image:latest),然后更改为 build 目录。
    IMAGE=custom container image \
        BUILD_DIR=$(mktemp -d) \
        cd "${BUILD_DIR}"
    
  2. 下载 BigQuery 连接器。

    gcloud storage cp \
        gs://spark-lib/bigquery/spark-bigquery-with-dependencies_2.12-0.22.2.jar .
    

  3. 创建 Python 示例文件。

    cat >test_util.py <<'EOF'
    def hello(name):
      print("hello {}".format(name))
    def read_lines(path):   with open(path) as f:     return f.readlines() EOF

  4. 创建示例 init 脚本。

    cat >init-script.sh <<EOF
    echo "hello world" >/tmp/init-script.out
    EOF
    

  5. 构建并推送映像。

    docker build -t "${IMAGE}" . && docker push "${IMAGE}"