Dataproc on GKE 自訂容器映像檔

您可以指定要搭配 Dataproc on GKE 使用的自訂容器映像檔。 自訂容器映像檔必須使用其中一個 Dataproc on GKE 基本 Spark 映像檔

使用自訂容器映像檔

如要使用 Dataproc on GKE 自訂容器映像檔,請在建立 Dataproc 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 工具,根據發布的 Dataproc on GKE 基本 Spark 映像檔,建構自訂 Docker。

容器使用者

Dataproc on GKE 會以 Linux spark 使用者身分執行 Spark 容器,並使用 1099 UID 和 1099 GID。使用 UID 和 GID 設定檔案系統權限。舉例來說,如果您在圖片中的 /opt/spark/jars/my-lib.jar 新增 JAR 檔案做為工作負載依附元件,就必須授予 spark 使用者該檔案的讀取權限。

元件

  • Java:JAVA_HOME 環境變數會指向 Java 安裝位置。目前的預設值為 /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64,但可能會變更 (如需最新資訊,請參閱 Dataproc 版本資訊)。

    • 如果自訂 Java 環境,請確認 JAVA_HOME 已設為正確位置,且 PATH 包含二進位檔的路徑。
  • Python:Dataproc on GKE 基本 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

    • 公用程式:執行 Spark 時需要 procpstini 公用程式套件。這些公用程式包含在基本 Spark 映像檔中,因此自訂映像檔不需要重新安裝。

    • 進入點:Dataproc on GKE 會忽略對容器映像檔中 ENTRYPOINTCMD 基本體的任何變更。

    • 初始化指令碼:您可以在 /opt/init-script.sh 新增選用的初始化指令碼。 初始化指令碼可以從 Cloud Storage 下載檔案、在容器內啟動 Proxy、呼叫其他指令碼,以及執行其他啟動工作。

      啟動 Spark 驅動程式、Spark 執行器和其他程序之前,進入點指令碼會使用所有指令列引數 ($@) 呼叫初始化指令碼。初始化指令碼可以根據第一個引數 ($1) 選取 Spark 處理程序類型,可能的值包括驅動程式容器的 spark-submit,以及執行器容器的 executor

  • 設定:Spark 設定位於 /etc/spark/conf 下方。 SPARK_CONF_DIR 環境變數會指向這個位置。

    請勿在容器映像檔中自訂 Spark 設定。請改為透過 Dataproc on GKE API 提交任何屬性,原因如下:

    • 部分屬性 (例如執行器記憶體大小) 是在執行階段決定,而非在容器映像檔建構階段決定,因此必須由 Dataproc on GKE 插入。
    • Dataproc on GKE 會限制使用者提供的屬性。 Dataproc on GKE 會將 configMap 中的設定掛接至容器中的 /etc/spark/conf,覆寫映像檔內嵌的設定。

基礎 Spark 映像檔

Dataproc 支援下列基本 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), 然後切換至建構目錄。
    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}"