Benutzerdefinierte Container mit Dataproc Server for Spark verwenden

Dataproc Serverless for 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 Dataproc Serverless for Spark ein Container-Image, das die standardmäßigen Spark-, Java-, Python- und R-Pakete enthält, die mit einer Laufzeitversion verknüpft sind. Mit der Dataproc Batch for Spark Batches API können Sie ein benutzerdefiniertes Container-Image anstelle des Standard-Images verwenden. In der Regel werden durch ein benutzerdefiniertes Container-Image Spark-Java- oder Python-Abhängigkeiten hinzugefügt, die nicht vom Standard-Container-Image bereitgestellt werden. Wichtig: Fügen Sie Spark nicht in Ihr benutzerdefiniertes Container-Image ein. Dataproc Serverless for Spark stellt Spark zur Laufzeit im Container bereit.

Spark-Batch-Arbeitslast mit einem benutzerdefinierten Container-Image einreichen

gcloud

Wenn Sie eine Spark-Batch-Arbeitslast einreichen, verwenden Sie den Befehl gcloud developers Batches send spark mit dem Flag --container-image, um Ihr benutzerdefiniertes Container-Image anzugeben.

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:

  • Custom-Image:Geben Sie das benutzerdefinierte Container-Image mit dem folgenden Container Registry-Image-Namensformat an: {hostname}/{project-id}/{image}:{tag}, z. B. "gcr.io/my-project-id/my-image:1.0.1" Hinweis: Das benutzerdefinierte Container-Image muss in Container Registry gehostet werden. Dataproc serverlose kann keine Container aus anderen Registries abrufen.
  • --jars:Geben Sie einen Pfad zu einer Nutzerarbeitslast an, die in Ihrem benutzerdefinierten Container-Image oder in Cloud Storage enthalten ist, z. B. "/opt/spark/jars/spark-examples.jar" oder "gs://my-bucket/spark/jars/spark-examples.jar".
  • Andere Batch-Befehlsoptionen: Sie können weitere optionale Batch-Befehls-Flags hinzufügen, z. B. um einen Spark History Server zu verwenden. Unter gcloud dataproc batches submit finden Sie unterstützte Befehls-Flags.
  • Arbeitslastargumente: Sie können beliebige Arbeitslastargumente hinzufügen, indem Sie „&-t&-t“ an das Ende des Befehls und dann die Arbeitslastargumente hinzufügen.

REST UND BEFEHLSZEILE

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

Im folgenden Beispiel wird gezeigt, wie Sie mit einem benutzerdefinierten Dataproc-Container die Batch-Arbeitslast der Dataproc-Spark-API batches.create senden.

Bevor Sie eine der Anfragedaten verwenden, nehmen Sie folgende Ersetzungen vor:

  • project-id: Google Cloud-Projekt-ID
  • region: region [Region]
  • custom-container-image: Geben Sie das benutzerdefinierte Container-Image mit dem folgenden Namensformat für Container Registry-Images an: {hostname}/{project-id}/{image}:{tag}, z. B. "gcr.io/my-project-id/my-image:1.0.1" Hinweis: Sie müssen Ihren benutzerdefinierten Container in Container Registry hosten (serverloses Dataproc kann keine Container aus anderen Registries abrufen).
  • jar-uri:Geben Sie einen Pfad zu einer 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 voll qualifizierte Name einer Klasse in der JAR-Datei, z. B. "org.apache.spark.examples.SparkPi"
  • Weitere Optionen: Sie können andere Felder von Batch-Arbeitslastressourcen verwenden, z. B. das Feld sparkBatch.args, um Argumente an Ihre Arbeitslast zu übergeben. Weitere Informationen finden Sie in der Batch-Ressourcendokumentation. Informationen zum Verwenden eines Spark-Verlaufsservers finden Sie unter Nichtflüchtigen Verlaufsserver einrichten.

HTTP-Methode und URL:

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

JSON-Text der Anfrage:

{
  "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 in etwa folgende JSON-Antwort 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 Dataproc-Container-Images sind Docker-Images. Sie können die Tools zum Erstellen von Docker-Images verwenden, um benutzerdefinierte Container-Images zu erstellen. Es müssen jedoch Bedingungen erfüllt sein, dass die Images mit Dataproc Serverless for Spark kompatibel sind. In den folgenden Abschnitten werden diese Bedingungen erläutert.

Betriebssystem

Sie können jedes Betriebssystem-Image als benutzerdefiniertes Container-Image auswählen. Empfehlung: Wir empfehlen die Standard-Debian 11-Images (z. B. debian:11-slim), da sie Kompatibilitätsprobleme erhalten haben, um Kompatibilitätsprobleme zu vermeiden.

Dienstprogramme

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

  • procps
  • tini

Containernutzer

Dataproc Serverless for Spark führt Container als spark-Linux-Nutzer mit einer 1099-UID und einer 1099-GID aus. USER-Anweisungen, die in benutzerdefinierten Container-Image-Dockerfiles festgelegt sind, werden zur Laufzeit ignoriert. Verwenden Sie die UID und die GID für Dateisystemberechtigungen. Wenn Sie beispielsweise eine JAR-Datei bei /opt/spark/jars/my-lib.jar als Arbeitslast in einer Bildabhängigkeit hinzufügen, müssen Sie der Datei die Berechtigung spark für die Nutzer erteilen.

Spark

Fügen Sie Spark nicht in Ihr benutzerdefiniertes Container-Image ein. Während der Laufzeit stellt Dataproc Serverless für Spark Spark-Binärprogramme und -Konfigurationen vom Host im Container bereit: Binärprogramme werden im Verzeichnis /usr/lib/spark und Konfigurationen im Verzeichnis /etc/spark/conf bereitgestellt. Vorhandene Dateien in diesen Verzeichnissen werden von Dataproc Serverless for Spark zur Laufzeit überschrieben.

Java-Laufzeitumgebung

Fügen Sie keine eigene Java-Laufzeitumgebung (JRE) in Ihr benutzerdefiniertes Container-Image ein. Zur Laufzeit stellt Dataproc Server for Spark OpenJDK11 vom Host auf den Container bereit. Wenn Sie eine JRE in Ihr benutzerdefiniertes Container-Image einfügen, wird es ignoriert.

Java-Pakete

Sie können JAR-Dateien als Abhängigkeiten von Spark-Arbeitslasten in Ihr benutzerdefiniertes Container-Image aufnehmen und die Umgebungsvariable SPARK_EXTRA_CLASSPATH so festlegen, dass die JAR-Dateien enthalten sind. Dataproc Serverless for Spark fügt den Wert der Umgebungsvariablen in den Klassenpfad von Spark JVM-Prozessen ein. Empfehlung: Setzen Sie JAR-Dateien im Verzeichnis /opt/spark/jars und setzen Sie SPARK_EXTRA_CLASSPATH auf /opt/spark/jars/*.

Sie können die JAR-Arbeitslast in Ihr benutzerdefiniertes Container-Image einfügen und dann mit einem lokalen Pfad darauf verweisen, z. B. file:///opt/spark/jars/my-spark-job.jar. Ein Beispiel finden Sie unter Spark-Batch-Arbeitslast mit einem benutzerdefinierten Container-Image einreichen.

Python-Pakete

Standardmäßig stellt Dataproc Server for Spark Conda vom Host zum Verzeichnis /opt/dataproc/conda im Container zur Laufzeit bereit. PYSPARK_PYTHON ist auf /opt/dataproc/conda/bin/python gesetzt. 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 aufnehmen, z. B. in /opt/conda, und die Umgebungsvariable PYSPARK_PYTHON auf /opt/conda/bin/python festlegen.

Das benutzerdefinierte 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 so fest, dass sie die Verzeichnisse enthält, 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 Ihr Container-Image-Linux hinzu und installieren Sie R-Pakete über den Linux OS-Paketmanager (siehe R-Softwarepaketindex).

In beiden Fällen müssen Sie die Umgebungsvariable R_HOME so festlegen, dass sie auf Ihre benutzerdefinierte R-Umgebung verweist. Ausnahme: Wenn Sie Conda verwenden, um Ihre R-Umgebung zu verwalten und Ihre Python-Umgebung anzupassen, müssen Sie die Umgebungsvariable R_HOME nicht festlegen. Sie wird automatisch anhand der Umgebungsvariablen PYSPARK_PYTHON festgelegt.

Beispiel für einen benutzerdefinierten Container-Image-Build

Dockerfile

# Debian 11 is recommended.
FROM debian:11-slim

# Suppress interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

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

# (Optional) 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}"
COPY spark-bigquery-with-dependencies_2.12-0.22.2.jar "${SPARK_EXTRA_JARS_DIR}"

# (Optional) Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniconda3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PATH=${CONDA_HOME}/bin:${PATH}
COPY Miniconda3-py39_4.10.3-Linux-x86_64.sh .
RUN bash Miniconda3-py39_4.10.3-Linux-x86_64.sh -b -p /opt/miniconda3 \
  && ${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 --prepend channels conda-forge \
  && ${CONDA_HOME}/bin/conda config --system --set channel_priority strict

# (Optional) Install Conda packages.
#
# The following packages are installed in the default image, it is strongly
# recommended to include all of them.
#
# Use mamba to install packages quickly.
RUN ${CONDA_HOME}/bin/conda install mamba -n base -c conda-forge \
    && ${CONDA_HOME}/bin/mamba install \
      conda \
      cython \
      fastavro \
      fastparquet \
      gcsfs \
      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 \
      koalas \
      matplotlib \
      nltk \
      numba \
      numpy \
      openblas \
      orc \
      pandas \
      pyarrow \
      pysal \
      pytables \
      python \
      regex \
      requests \
      rtree \
      scikit-image \
      scikit-learn \
      scipy \
      seaborn \
      sqlalchemy \
      sympy \
      virtualenv

# (Optional) Add extra Python modules.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"
COPY test_util.py "${PYTHONPATH}"

# (Optional) Install R and R libraries.
RUN apt update \
  && apt install -y gnupg \
  && apt-key adv --no-tty \
      --keyserver "hkp://keyserver.ubuntu.com:80" \
      --recv-keys E19F5F87128899B192B1A2C2AD5F960A256A04AF \
  && echo "deb http://cloud.r-project.org/bin/linux/debian bullseye-cran40/" \
      >/etc/apt/sources.list.d/cran-r.list \
  && apt update \
  && apt install -y \
      libopenblas-base \
      libssl-dev \
      r-base \
      r-base-dev \
      r-recommended \
      r-cran-blob

ENV R_HOME=/usr/lib/R

# (Required) 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-Befehle

Führen Sie das Verzeichnis im Dockerfile-Verzeichnis aus.

IMAGE=gcr.io/my-project/my-image:1.0.1

# Download the BigQuery connector.
gsutil cp \
  gs://spark-lib/bigquery/spark-bigquery-with-dependencies_2.12-0.22.2.jar .

# Download the Miniconda3 installer.
wget https://repo.anaconda.com/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh

# Python module example
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

# Build and push the image.
docker build -t "${IMAGE}" .
docker push "${IMAGE}"