Benutzerdefinierte Container-Images für Dataproc auf GKE

Sie können ein benutzerdefiniertes Container-Image für die Verwendung mit Dataproc auf GKE angeben . Ihr benutzerdefiniertes Container-Image muss eines der Dataproc auf GKE Basis-Spark-Images verwenden.

Benutzerdefiniertes Container-Image verwenden

Wenn Sie ein benutzerdefiniertes Container-Image für Dataproc auf GKE verwenden möchten, legen Sie die spark.kubernetes.container.image property fest, wenn Sie einen virtuellen Dataproc auf GKE-Cluster erstellen oder einen Spark-Job senden an den Cluster.

  • Beispiel für die Clustererstellung mit der gcloud CLI:
    gcloud dataproc clusters gke create "${DP_CLUSTER}" \
        --properties=spark:spark.kubernetes.container.image=custom-image \
        ... other args ...
    
  • Beispiel für das Senden eines Jobs mit der gcloud CLI:
    gcloud dataproc jobs submit spark \
        --properties=spark.kubernetes.container.image=custom-image \
        ... other args ...
    

Anforderungen und Einstellungen für benutzerdefinierte Container-Images

Basis-Images

Sie können docker-Tools verwenden, um benutzerdefinierte Docker-Images basierend auf einem der veröffentlichten Dataproc auf GKE Basis-Spark-Images zu erstellen.

Container-Nutzer

Dataproc auf GKE führt Spark-Container als Linux-spark Nutzer mit einer 1099 UID und einer 1099 GID aus. 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.

Komponenten

  • Java:Die Umgebungsvariable JAVA_HOME verweist auf den Speicherort der Java-Installation. Der aktuelle Standardwert ist /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64, dieser kann sich ändern (aktuelle Informationen finden Sie in den Dataproc-Versionshinweisen).

    • Wenn Sie die Java-Umgebung anpassen, muss JAVA_HOME auf den richtigen Speicherort festgelegt sein und PATH muss den Pfad zu den Binärdateien enthalten.
  • Python: In den Dataproc auf GKE Basis-Spark-Images ist Miniconda3 unter /opt/condainstalliert. CONDA_HOME verweist auf diesen Speicherort, ${CONDA_HOME}/bin ist in PATH enthalten und PYSPARK_PYTHON ist auf ${CONDA_HOME}/python festgelegt.

    • Wenn Sie Conda anpassen, muss CONDA_HOME auf das Conda-Basisverzeichnis verweisen,${CONDA_HOME}/bin muss in PATH enthalten sein und PYSPARK_PYTHON muss auf ${CONDA_HOME}/python. festgelegt sein

    • Sie können Pakete in der Standardbasisumgebung installieren, entfernen und aktualisieren, oder eine neue Umgebung erstellen. Es wird jedoch dringend empfohlen, dass die Umgebung alle Pakete enthält, die in der Basisumgebung des Basis-Container-Images installiert sind.

    • Wenn Sie dem Container-Image Python-Module wie ein Python-Skript mit Hilfsfunktionen hinzufügen, fügen Sie die Modulverzeichnisse in PYTHONPATH ein.

  • Spark: Spark ist unter /usr/lib/spark installiert und SPARK_HOME verweist auf diesen Speicherort. Spark kann nicht angepasst werden. Wenn es geändert wird, wird das Container Image abgelehnt oder funktioniert nicht richtig.

    • Jobs: Sie können Spark-Jobabhängigkeiten anpassen. SPARK_EXTRA_CLASSPATH definiert den zusätzlichen Klassenpfad für Spark-JVM-Prozesse. Empfehlung: Platzieren Sie JAR-Dateien unter /opt/spark/jars, und legen Sie SPARK_EXTRA_CLASSPATH auf /opt/spark/jars/* fest.

      Wenn Sie die Job-JAR-Datei in das Image einbetten, ist das empfohlene Verzeichnis /opt/spark/job. Wenn Sie den Job senden, können Sie mit einem lokalen Pfad darauf verweisen, z. B. file:///opt/spark/job/my-spark-job.jar.

    • Cloud Storage-Connector: Der Cloud Storage-Connector ist unter /usr/lib/spark/jars installiert.

    • Dienstprogramme: Die Dienstprogrammpakete procps und tini sind für die Ausführung von Spark erforderlich. Diese Dienstprogramme sind in den Basis-Spark-Images enthalten, sodass sie in benutzerdefinierten Images nicht neu installiert werden müssen.

    • Einstiegspunkt: In Dataproc auf GKE werden alle Änderungen an den Primitiven ENTRYPOINT und CMD im Container-Image ignoriert.

    • Initialisierungsskripts: Sie können unter /opt/init-script.sh ein optionales Initialisierungsskript hinzufügen. Ein Initialisierungsskript kann Dateien aus Cloud Storage herunterladen, einen Proxy im Container starten, andere Skripts aufrufen und andere Startaufgaben ausführen.

      Das Einstiegspunktskript ruft das Initialisierungsskript mit allen Befehlszeilenargumenten ($@) auf, bevor der Spark-Treiber, der Spark-Executor und andere Prozesse gestartet werden. Das Initialisierungsskript kann den Typ des Spark-Prozesses anhand des ersten Arguments ($1) auswählen. Mögliche Werte sind spark-submit für Treibercontainer und executor für Executor-Container.

  • Konfigurationen: Spark-Konfigurationen befinden sich unter /etc/spark/conf. Die Umgebungsvariable SPARK_CONF_DIR verweist auf diesen Speicherort.

    Passen Sie die Spark-Konfigurationen nicht im Container-Image an. Senden Sie stattdessen alle Eigenschaften über die Dataproc auf GKE API. Das hat folgende Gründe:

    • Einige Eigenschaften wie die Größe des Executorspeichers werden zur Laufzeit und nicht beim Erstellen des Container-Images festgelegt. Sie müssen von Dataproc auf GKE eingefügt werden.
    • In Dataproc auf GKE gelten Einschränkungen für die von Nutzern bereitgestellten Eigenschaften. In Dataproc auf GKE werden Konfigurationen aus configMap in /etc/spark/conf im Container bereitgestellt, wodurch die im Image eingebetteten Einstellungen überschrieben werden.

Basis-Spark-Images

Dataproc unterstützt die folgenden Basis-Spark-Container-Images:

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

Beispiel für die Erstellung eines benutzerdefinierten Container-Images

Beispiel für ein 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

Container-Image erstellen

Führen Sie die folgenden Befehle im Dockerfile-Verzeichnis aus

  1. Legen Sie das Image fest (Beispiel: us-central1-docker.pkg.dev/my-project/spark/spark-test-image:latest) und wechseln Sie zum Build-Verzeichnis.
    IMAGE=custom container image \
        BUILD_DIR=$(mktemp -d) \
        cd "${BUILD_DIR}"
    
  2. Laden Sie den BigQuery-Connector herunter.

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

  3. Erstellen Sie eine Python-Beispieldatei.

    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. Erstellen Sie ein Beispiel-Initialisierungsskript.

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

  5. Erstellen Sie das Image und übertragen Sie es per Push.

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