Benutzerdefinierte Container-Images für Dataproc auf GKE

Sie können ein benutzerdefiniertes Container-Image angeben, das mit Dataproc in GKE verwendet werden soll . Für Ihr benutzerdefiniertes Container-Image muss eines der Basis-Spark-Images von Dataproc in GKE verwendet werden.

Benutzerdefiniertes Container-Image verwenden

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

  • 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 die Abgabe eines Jobs über die 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 auf der Grundlage eines der veröffentlichten Spark-Basisimages für Dataproc on GKE zu erstellen.

Containernutzer

In Dataproc on GKE werden Spark-Container als Linux-Nutzer spark mit der UID 1099 und der GID 1099 ausgeführt. Verwenden Sie die UID und GID für die 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 die Leseberechtigung für die Datei erteilen.

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-Releasenotizen.

    • Wenn Sie die Java-Umgebung anpassen, achten Sie darauf, dass JAVA_HOME auf den richtigen Speicherort festgelegt ist und PATH den Pfad zu den Binärdateien enthält.
  • Python:Auf den Spark-Basis-Images von Dataproc auf GKE ist Miniconda3 unter /opt/conda installiert. 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, achten Sie darauf ,dass CONDA_HOME auf das Conda-Basisverzeichnis verweist, ${CONDA_HOME}/bin in PATH enthalten ist und PYSPARK_PYTHON auf ${CONDA_HOME}/python. festgelegt ist.

    • Sie können Pakete in der Standard-Basisumgebung 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 hinzufügen, z. B. ein Python-Script mit Dienstprogrammfunktionen, fügen Sie die Modulverzeichnisse in PYTHONPATH ein.

  • Spark:Spark ist in /usr/lib/spark installiert und SPARK_HOME verweist auf diesen Speicherort. Spark kann nicht angepasst werden. Andernfalls wird das Containerimage 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: Legen Sie Jar-Dateien unter /opt/spark/jars ab und legen Sie SPARK_EXTRA_CLASSPATH auf /opt/spark/jars/* fest.

      Wenn Sie das Job-JAR in das Image einbetten, wird das Verzeichnis /opt/spark/job empfohlen. Wenn Sie den Job einreichen, können Sie ihn mit einem lokalen Pfad wie file:///opt/spark/job/my-spark-job.jar referenzieren.

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

    • Dienstprogramme: Die Dienstprogramme procps und tini sind zum Ausführen von Spark erforderlich. Diese Dienstprogramme sind in den Spark-Basis-Images enthalten. Sie müssen also nicht für benutzerdefinierte Images neu installiert werden.

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

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

      Das Einstiegspunkt-Script ruft das Initialisierungs-Script mit allen Befehlszeilenargumenten ($@) auf, bevor der Spark-Treiber, der Spark-Ausführer und andere Prozesse gestartet werden. Das Initialisierungsskript kann den Spark-Prozesstyp basierend auf dem ersten Argument ($1) auswählen. Mögliche Werte sind spark-submit für Treibercontainer und executor für Executor-Container.

  • Configs: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. Reichen Sie stattdessen alle Properties über die Dataproc on GKE API ein. Das hat folgende Gründe:

    • Einige Eigenschaften, z. B. die Größe des Executor-Arbeitsspeichers, werden zur Laufzeit und nicht beim Erstellen des Container-Images festgelegt. Sie müssen von Dataproc in GKE eingefügt werden.
    • Dataproc in GKE schränkt die von Nutzern angegebenen Properties ein. Dataproc on GKE bindet Konfigurationen von configMap in /etc/spark/conf im Container ein und überschreibt die im Image eingebetteten Einstellungen.

Basis-Spark-Images

Dataproc unterstützt die folgenden Spark-Basiscontainer-Images:

  • Spark 2.4: ${REGION}-docker.pkg.dev/cloud-dataproc/spark/dataproc_1.5
  • Spark 3.1: ${REGION}-docker.pkg.dev/cloud-dataproc/spark/dataproc_2.0

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 ein Image fest (z. B. 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-Init-Script.

    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}"