Benutzerdefinierte Container verwenden

Managed Service for Apache Spark führt Arbeitslasten in Docker Containern aus. Der Container bietet die Laufzeitumgebung für die Treiber- und Executor-Prozesse der Arbeitslast. Standardmäßig verwendet Managed Service for Apache Spark ein Container-Image, das die Standardpakete für Spark, Java, Python und R enthält, die mit einer Laufzeitversion verknüpft sind. Mit der Managed Service for Apache Spark Batches API können Sie anstelle des Standard- Images ein benutzerdefiniertes Container-Image verwenden. In der Regel werden mit einem benutzerdefinierten Container-Image Java- oder Python-Abhängigkeiten für Spark-Arbeitslasten hinzugefügt, die nicht vom Standard-Container-Image bereitgestellt werden. Wichtig:Schließen Sie Spark nicht in Ihr benutzerdefiniertes Container-Image ein. Managed Service for Apache Spark stellt Spark zur Laufzeit im Container bereit.

Spark-Batcharbeitslast mit einem benutzerdefinierten Container-Image senden

gcloud

Verwenden Sie den gcloud dataproc batches submit spark Befehl mit dem --container-image Flag, um Ihr benutzerdefiniertes Container-Image anzugeben, wenn Sie eine Spark-Batcharbeitslast senden.

gcloud dataproc batches submit spark \
    --container-image=custom-image, for example, "gcr.io/my-project-id/my-image:1.0.1" \
    --region=region \
    --jars=path to user workload jar located in Cloud Storage or included in the custom container \
    --class=The fully qualified name of a class in the jar file, such as org.apache.spark.examples.SparkPi \
    -- add any workload arguments here

Hinweise :

  • Benutzerdefiniertes Image: Geben Sie das benutzerdefinierte Container-Image im folgenden Container Registry-Image-Namensformat an: {hostname}/{project-id}/{image}:{tag}, z. B. „gcr.io/my-project-id/my-image:1.0.1“. Hinweis: Sie müssen Ihr benutzerdefiniertes Container-Image in Container Registry oder Artifact Registry hosten. Managed Service for Apache Spark kann keine Container aus anderen Registries abrufen.
  • --jars: Geben Sie einen Pfad zu einer Nutzerarbeitslast an, die in Ihrem benutzerdefinierten Container-Image enthalten ist oder sich in Cloud Storage befindet, z. B. file:///opt/spark/jars/spark-examples.jar oder gs://my-bucket/spark/jars/spark-examples.jar.
  • Weitere Optionen für den Befehl „batches“: Sie können weitere optionale Flags für den Befehl „batches“ hinzufügen, z. B. um einen Persistent History Server (PHS) zu verwenden. Hinweis: Der PHS muss sich in der Region befinden, in der Sie Batcharbeitslasten ausführen.
  • Argumente für Arbeitslasten: Sie können beliebige Argumente für Arbeitslasten hinzufügen, indem Sie am Ende des Befehls „--“ und dann die Argumente für die Arbeitslasten hinzufügen.

REST

Das benutzerdefinierte Container-Image wird über das RuntimeConfig.containerImage Feld im Rahmen einer batches.create API-Anfrage bereitgestellt.

Im folgenden Beispiel wird gezeigt, wie Sie mit einem benutzerdefinierten Container eine Batcharbeitslast mit der Managed Service for Apache Spark batches.create API senden.

Ersetzen Sie diese Werte in den folgenden Anfragedaten:

  • project-id: ID des Google Cloud-Projekts.
  • region: Region
  • custom-container-image: Geben Sie das benutzerdefinierte Container-Image im folgenden Container Registry-Image-Namensformat an: {hostname}/{project-id}/{image}:{tag}, z. B. „gcr.io/my-project-id/my-image:1.0.1“. Hinweis: Der benutzerdefinierte Container muss in Container Registry oder Artifact Registry gehostet werden. Managed Service for Apache Spark kann keine Container aus anderen Registries abrufen.
  • jar-uri: Geben Sie einen Pfad zu einer Arbeitslast-JAR-Datei an, die in Ihrem benutzerdefinierten Container-Image enthalten ist oder sich in Cloud Storage befindet, z. B. „/opt/spark/jars/spark-examples.jar“ oder „gs:///spark/jars/spark-examples.jar“.
  • class:Der vollständig qualifizierte Name einer Klasse in der JAR-Datei, z. B. „org.apache.spark.examples.SparkPi“.
  • Weitere Optionen: Sie können andere Felder für Batcharbeitslastressourcen verwenden, z. B. das Feld sparkBatch.args, um Argumente an Ihre Arbeitslast zu übergeben. Weitere Informationen finden Sie in der Dokumentation zur Ressource Batch. Informationen zur Verwendung eines Persistent History Server (PHS), finden Sie unter Persistent History Server einrichten. Hinweis: Der PHS muss sich in der Region befinden, in der Sie Batcharbeitslasten ausführen.

HTTP-Methode und URL:

POST https://dataproc.googleapis.com/v1/projects/project-id/locations/region/batches

JSON-Text anfordern:

{
  "runtimeConfig":{
    "containerImage":"custom-container-image
  },
  "sparkBatch":{
    "jarFileUris":[
      "jar-uri"
    ],
    "mainClass":"class"
  }
}

Wenn Sie die Anfrage senden möchten, maximieren Sie eine der folgenden Optionen:

Sie sollten eine JSON-Antwort ähnlich wie diese erhalten:

{
"name":"projects/project-id/locations/region/batches/batch-id",
  "uuid":",uuid",
  "createTime":"2021-07-22T17:03:46.393957Z",
  "runtimeConfig":{
    "containerImage":"gcr.io/my-project/my-image:1.0.1"
  },
  "sparkBatch":{
    "mainClass":"org.apache.spark.examples.SparkPi",
    "jarFileUris":[
      "/opt/spark/jars/spark-examples.jar"
    ]
  },
  "runtimeInfo":{
    "outputUri":"gs://dataproc-.../driveroutput"
  },
  "state":"SUCCEEDED",
  "stateTime":"2021-07-22T17:06:30.301789Z",
  "creator":"account-email-address",
  "runtimeConfig":{
    "properties":{
      "spark:spark.executor.instances":"2",
      "spark:spark.driver.cores":"2",
      "spark:spark.executor.cores":"2",
      "spark:spark.app.name":"projects/project-id/locations/region/batches/batch-id"
    }
  },
  "environmentConfig":{
    "peripheralsConfig":{
      "sparkHistoryServerConfig":{
      }
    }
  },
  "operation":"projects/project-id/regions/region/operation-id"
}

Benutzerdefiniertes Container-Image erstellen

Benutzerdefinierte Container-Images für Managed Service for Apache Spark sind Docker-Images. Sie können die Tools zum Erstellen von Docker-Images verwenden, um benutzerdefinierte Container-Images zu erstellen. Es gibt jedoch Bedingungen, die die Images erfüllen müssen, um mit Managed Service for Apache Spark kompatibel zu sein. Diese Bedingungen werden in den folgenden Abschnitten erläutert.

Betriebssystem

Sie können ein beliebiges Betriebssystem-Basis-Image für Ihr benutzerdefiniertes Container-Image auswählen.

Empfehlung: Verwenden Sie die Standard-Debian 12-Images, z. B. debian:12-slim, da sie getestet wurden, um Kompatibilitätsprobleme zu vermeiden.

Dienstprogramme

Sie müssen die folgenden Dienstprogramm-Pakete, die zum Ausführen von Spark erforderlich sind, in Ihr benutzerdefiniertes Container-Image aufnehmen:

  • procps
  • tini

Wenn Sie XGBoost aus Spark (Java oder Scala) ausführen möchten, müssen Sie libgomp1 einbeziehen.

Container-Nutzer

Managed Service for Apache Spark führt Container als Linux-Nutzer spark mit einer 1099-UID und einer 1099-GID aus. USER -Anweisungen, die in Dockerfiles für benutzerdefinierte Container-Images festgelegt sind, werden zur Laufzeit ignoriert. Verwenden Sie die UID und GID für Dateisystemberechtigungen. Wenn Sie beispielsweise eine JAR-Datei unter /opt/spark/jars/my-lib.jar im Image als Arbeitslastabhängigkeit hinzufügen, müssen Sie dem Nutzer spark Leseberechtigung für die Datei gewähren.

Image-Streaming

Managed Service for Apache Spark beginnt normalerweise eine Arbeitslast, für die ein benutzerdefiniertes Container-Image erforderlich ist, indem das gesamte Image auf die Festplatte heruntergeladen wird. Dies kann zu einer Verzögerung der Initialisierungszeit führen, insbesondere bei Kunden mit großen Images.

Stattdessen können Sie das Image-Streaming verwenden, eine Methode zum Abrufen von Image-Daten nach Bedarf. So kann die Arbeitslast gestartet werden, ohne dass das gesamte Image heruntergeladen werden muss, was die Initialisierungszeit möglicherweise verkürzt. Wenn Sie das Image Streaming aktivieren möchten, müssen Sie die Container File System API aktivieren. Außerdem müssen Sie Ihre Container-Images in Artifact Registry speichern. Das Artifact Registry-Repository muss sich in derselben Region wie Ihre Managed Service for Apache Spark-Arbeitslast oder in einer Multi-Region befinden, die der Region entspricht, in der Ihre Arbeitslast ausgeführt wird. Wenn Managed Service for Apache Spark das Image nicht unterstützt oder der Image-Streaming-Dienst nicht verfügbar ist, wird das gesamte Image von unserer Streaming-Implementierung heruntergeladen.

Folgendes wird für das Image-Streaming nicht unterstützt:

In diesen Fällen ruft Managed Service for Apache Spark das gesamte Image ab, bevor die Arbeitslast gestartet wird.

Spark

Schließen Sie Spark nicht in Ihr benutzerdefiniertes Container-Image ein. Zur Laufzeit stellt Managed Service for Apache Spark Spark-Binärdateien und -Konfigurationen vom Host im Container bereit: Binärdateien werden im Verzeichnis /usr/lib/spark und Konfigurationen im Verzeichnis /etc/spark/conf bereitgestellt. Vorhandene Dateien in diesen Verzeichnissen werden zur Laufzeit von Managed Service for Apache Spark überschrieben.

Java-Laufzeitumgebung

Schließen Sie keine eigene Java-Laufzeitumgebung (Java Runtime Environment, JRE) in Ihr benutzerdefiniertes Container-Image ein. Zur Laufzeit stellt Managed Service for Apache Spark OpenJDK vom Host im Container bereit. Wenn Sie eine JRE in Ihr benutzerdefiniertes Container-Image einbeziehen, wird sie ignoriert.

Java-Pakete

Sie können JAR-Dateien als Spark-Arbeitslastabhängigkeiten in Ihr benutzerdefiniertes Container-Image einbeziehen und die Umgebungsvariable SPARK_EXTRA_CLASSPATH festlegen, um die JAR-Dateien einzubeziehen. Managed Service for Apache Spark fügt den Wert der Umgebungsvariable im Klassenpfad der Spark-JVM-Prozesse hinzu. Empfehlung: Platzieren Sie JAR-Dateien im Verzeichnis /opt/spark/jars und legen Sie SPARK_EXTRA_CLASSPATH auf /opt/spark/jars/* fest.

Sie können die Arbeitslast-JAR-Datei in Ihr benutzerdefiniertes Container-Image einbeziehen und dann beim Senden der Arbeitslast mit einem lokalen Pfad darauf verweisen, z. B. file:///opt/spark/jars/my-spark-job.jar Ein Beispiel finden Sie unter Spark-Batcharbeitslast mit einem benutzerdefinierten Container-Image senden.

Python-Pakete

Standardmäßig stellt Managed Service for Apache Spark zur Laufzeit eine Conda-Umgebung, die mit einem OSS Conda-Forge-Repository erstellt wurde, vom Host im Verzeichnis /opt/dataproc/conda im Container bereit. PYSPARK_PYTHON ist auf /opt/dataproc/conda/bin/python festgelegt. Das Basisverzeichnis /opt/dataproc/conda/bin ist in PATH enthalten.

Sie können Ihre Python-Umgebung mit Paketen in einem anderen Verzeichnis in Ihr benutzerdefiniertes Container-Image einbeziehen, z. B. in /opt/conda, und die PYSPARK_PYTHON Umgebungsvariable auf /opt/conda/bin/python festlegen.

Ihr benutzerdefiniertes Container-Image kann andere Python-Module enthalten, die nicht Teil der Python-Umgebung sind, z. B. Python-Skripts mit Dienstprogrammfunktionen. Legen Sie die Umgebungsvariable PYTHONPATH fest, um die Verzeichnisse einzubeziehen, in denen sich die Module befinden.

R-Umgebung

Sie können die R-Umgebung in Ihrem benutzerdefinierten Container-Image mit einer der folgenden Optionen anpassen:

  • Verwenden Sie Conda, um R-Pakete aus dem conda-forge-Kanal zu verwalten und zu installieren.
  • Fügen Sie ein R-Repository für das Linux-Betriebssystem Ihres Container-Images hinzu und installieren Sie R-Pakete mit dem Paketmanager des Linux-Betriebssystems. Weitere Informationen finden Sie im R Software package index.

Wenn Sie eine der beiden Optionen verwenden, müssen Sie die Umgebungsvariable R_HOME so festlegen, dass sie auf Ihre benutzerdefinierte R-Umgebung verweist. Ausnahme: Wenn Sie Conda sowohl zum Verwalten Ihrer R-Umgebung als auch zum Anpassen Ihrer Python-Umgebung verwenden, müssen Sie die Umgebungsvariable R_HOME nicht festlegen. Sie wird automatisch basierend auf der Umgebungsvariable PYSPARK_PYTHON festgelegt.

Beispiel für das Erstellen eines benutzerdefinierten Container-Images

Dieser Abschnitt enthält Beispiele für das Erstellen benutzerdefinierter Container-Images, die Beispiel-Dockerfilesenthalten, gefolgt von einem Build-Befehl. Ein Beispiel enthält die Mindestkonfiguration, die zum Erstellen eines Images erforderlich ist. Das andere Beispiel enthält Beispiele für zusätzliche Konfigurationen, einschließlich Python- und R-Bibliotheken.

Minimalkonfiguration

# Recommendation: Use Debian 12.
FROM debian:12-slim

# Suppress interactive prompts.
ENV DEBIAN_FRONTEND=noninteractive

# Install utilities required by Spark scripts.
RUN apt update && apt install -y procps tini libjemalloc2

# Enable jemalloc as default memory allocator.
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2

# Create the 'spark' group/user.
# The GID and UID must be 1099. Home directory is required.
RUN groupadd -g 1099 spark
RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
USER spark
    

Zusätzliche Konfiguration

# Recommendation: Use Debian 12.
FROM debian:12-slim

# Suppress interactive prompts.
ENV DEBIAN_FRONTEND=noninteractive

# Install utilities required by Spark scripts.
RUN apt update && apt install -y procps tini libjemalloc2

# Enable jemalloc as default memory allocator
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2

# Install utilities required by XGBoost for Spark.
RUN apt install -y procps libgomp1

# Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniforge3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PATH=${CONDA_HOME}/bin:${PATH}
ADD https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh .
RUN bash Miniforge3-Linux-x86_64.sh -b -p /opt/miniforge3 \
  && ${CONDA_HOME}/bin/conda config --system --set always_yes True \
  && ${CONDA_HOME}/bin/conda config --system --set auto_update_conda False \
  && ${CONDA_HOME}/bin/conda config --system --set channel_priority strict
# Packages ipython and ipykernel are required if using custom conda and want to
# use this container for running notebooks.
RUN ${CONDA_HOME}/bin/mamba install ipython ipykernel

#Install Google Cloud SDK.
RUN ${CONDA_HOME}/bin/mamba install -n base google-cloud-sdk

# Install Conda packages.
#
# The following packages are installed in the default image.
# Recommendation: include all packages.
#
# Use mamba to quickly install packages.
RUN ${CONDA_HOME}/bin/mamba install -n base \
    accelerate \
    bigframes \
    cython \
    deepspeed \
    evaluate \
    fastavro \
    fastparquet \
    gcsfs \
    google-cloud-aiplatform \
    google-cloud-bigquery-storage \
    google-cloud-bigquery[pandas] \
    google-cloud-bigtable \
    google-cloud-container \
    google-cloud-datacatalog \
    google-cloud-dataproc \
    google-cloud-datastore \
    google-cloud-language \
    google-cloud-logging \
    google-cloud-monitoring \
    google-cloud-pubsub \
    google-cloud-redis \
    google-cloud-spanner \
    google-cloud-speech \
    google-cloud-storage \
    google-cloud-texttospeech \
    google-cloud-translate \
    google-cloud-vision \
    langchain \
    lightgbm \
    koalas \
    matplotlib \
    mlflow \
    nltk \
    numba \
    numpy \
    openblas \
    orc \
    pandas \
    pyarrow \
    pynvml \
    pysal \
    pytables \
    python \
    pytorch-cpu \
    regex \
    requests \
    rtree \
    scikit-image \
    scikit-learn \
    scipy \
    seaborn \
    sentence-transformers \
    sqlalchemy \
    sympy \
    tokenizers \
    transformers \
    virtualenv \
    xgboost

# Install pip packages.
RUN ${PYSPARK_PYTHON} -m pip install \
    spark-tensorflow-distributor \
    torcheval

# Install R and R libraries.
RUN ${CONDA_HOME}/bin/mamba install -n base \ 
    r-askpass \
    r-assertthat \
    r-backports \
    r-bit \
    r-bit64 \
    r-blob \
    r-boot \
    r-brew \
    r-broom \
    r-callr \
    r-caret \
    r-cellranger \
    r-chron \
    r-class \
    r-cli \
    r-clipr \
    r-cluster \
    r-codetools \
    r-colorspace \
    r-commonmark \
    r-cpp11 \
    r-crayon \
    r-curl \
    r-data.table \
    r-dbi \
    r-dbplyr \
    r-desc \
    r-devtools \
    r-digest \
    r-dplyr \
    r-ellipsis \
    r-evaluate \
    r-fansi \
    r-fastmap \
    r-forcats \
    r-foreach \
    r-foreign \
    r-fs \
    r-future \
    r-generics \
    r-ggplot2 \
    r-gh \
    r-glmnet \
    r-globals \
    r-glue \
    r-gower \
    r-gtable \
    r-haven \
    r-highr \
    r-hms \
    r-htmltools \
    r-htmlwidgets \
    r-httpuv \
    r-httr \
    r-hwriter \
    r-ini \
    r-ipred \
    r-isoband \
    r-iterators \
    r-jsonlite \
    r-kernsmooth \
    r-knitr \
    r-labeling \
    r-later \
    r-lattice \
    r-lava \
    r-lifecycle \
    r-listenv \
    r-lubridate \
    r-magrittr \
    r-markdown \
    r-mass \
    r-matrix \
    r-memoise \
    r-mgcv \
    r-mime \
    r-modelmetrics \
    r-modelr \
    r-munsell \
    r-nlme \
    r-nnet \
    r-numderiv \
    r-openssl \
    r-pillar \
    r-pkgbuild \
    r-pkgconfig \
    r-pkgload \
    r-plogr \
    r-plyr \
    r-praise \
    r-prettyunits \
    r-processx \
    r-prodlim \
    r-progress \
    r-promises \
    r-proto \
    r-ps \
    r-purrr \
    r-r6 \
    r-randomforest \
    r-rappdirs \
    r-rcmdcheck \
    r-rcolorbrewer \
    r-rcpp \
    r-rcurl \
    r-readr \
    r-readxl \
    r-recipes \
    r-recommended \
    r-rematch \
    r-remotes \
    r-reprex \
    r-reshape2 \
    r-rlang \
    r-rmarkdown \
    r-rodbc \
    r-roxygen2 \
    r-rpart \
    r-rprojroot \
    r-rserve \
    r-rsqlite \
    r-rstudioapi \
    r-rvest \
    r-scales \
    r-selectr \
    r-sessioninfo \
    r-shape \
    r-shiny \
    r-sourcetools \
    r-spatial \
    r-squarem \
    r-stringi \
    r-stringr \
    r-survival \
    r-sys \
    r-teachingdemos \
    r-testthat \
    r-tibble \
    r-tidyr \
    r-tidyselect \
    r-tidyverse \
    r-timedate \
    r-tinytex \
    r-usethis \
    r-utf8 \
    r-uuid \
    r-vctrs \
    r-whisker \
    r-withr \
    r-xfun \
    r-xml2 \
    r-xopen \
    r-xtable \
    r-yaml \
    r-zip

ENV R_HOME=/usr/lib/R

# Add extra Python modules.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"

# Add extra jars.
ENV SPARK_EXTRA_JARS_DIR=/opt/spark/jars/
ENV SPARK_EXTRA_CLASSPATH='/opt/spark/jars/*'
RUN mkdir -p "${SPARK_EXTRA_JARS_DIR}"

#Uncomment below and replace EXTRA_JAR_NAME with the jar file name.
#COPY "EXTRA_JAR_NAME" "${SPARK_EXTRA_JARS_DIR}"

# Create the 'spark' group/user.
# The GID and UID must be 1099. Home directory is required.
RUN groupadd -g 1099 spark
RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
USER spark
      

Build-Befehl

Führen Sie den folgenden Befehl im Dockerfile-Verzeichnis aus, um das benutzerdefinierte Image zu erstellen und per Push an die Artifact Registry zu senden.

# Build and push the image.
gcloud builds submit --region=REGION \
    --tag REGION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE_NAME:IMAGE_VERSION