Benutzerdefinierte Container-Images für Dataproc in GKE

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

Benutzerdefiniertes Container-Image verwenden

Wenn Sie ein benutzerdefiniertes Dataproc-Container-Image verwenden möchten, legen Sie 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 das Erstellen einer gcloud-Befehlszeile:
    gcloud dataproc clusters gke create "${DP_CLUSTER}" \
        --properties=spark:spark.kubernetes.container.image=custom-image \
        ... other args ...
    
  • Beispiel für einen gcloud-Befehlszeilenjob:
    gcloud dataproc jobs submit spark \
        --properties=spark.kubernetes.container.image=custom-image \
        ... other args ...
    

Benutzerdefinierte Anforderungen für Container-Images und Einstellungen

Basis-Images

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

Container-Nutzer

Dataproc in 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 Lesezugriff auf 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. Diese können sich ändern. Aktuelle Informationen finden Sie in den Dataproc-Versionshinweisen.

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

    • 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 in der Basisumgebung des Basis-Container-Images installierten Pakete enthält.

    • Wenn Sie dem Container-Image Python-Module wie ein Python-Skript mit Dienstfunktionen hinzufügen, 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. Wenn es geändert wird, wird das Container-Image abgelehnt oder funktioniert nicht ordnungsgemäß.

    • Jobs: Sie können die Abhängigkeiten von Spark-Jobs anpassen. SPARK_EXTRA_CLASSPATH definiert den zusätzlichen Klassenpfad für Spark-JVM-Prozesse. Empfehlung: Fügen Sie JAR-Dateien unter /opt/spark/jars hinzu und setzen Sie SPARK_EXTRA_CLASSPATH auf /opt/spark/jars/*.

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

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

    • Verwalten: Die Dienstprogramme procps und tini sind erforderlich, um Spark auszuführen. Diese Dienstprogramme sind in den Basis-Spark-Images enthalten, sodass sie nicht von benutzerdefinierten Images neu installiert werden müssen.

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

    • Initialisierungsskripts:Unter /opt/init-script.sh können Sie ein optionales Initialisierungsskript hinzufügen. Ein Initialisierungsskript kann Dateien aus Cloud Storage herunterladen, einen Proxy innerhalb des Containers 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. Im Initialisierungsskript kann je nach erstem Argument ($1) der Typ des Spark-Prozesses ausgewählt werden. Zu den möglichen Werten gehören spark-submit für Treibercontainer und executor für Executor-Container.

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

    Passen Sie die Spark-Konfigurationen im Container-Image nicht an. Senden Sie stattdessen Attribute aus folgenden Gründen über die Dataproc on GKE API:

    • Einige Attribute, z. B. die Größe des Executor-Speichers, werden zur Laufzeit und nicht zum Zeitpunkt der Erstellung des Container-Images bestimmt. Sie müssen von Dataproc in GKE eingefügt werden.
    • Dataproc in GKE legt Einschränkungen für die von Nutzern bereitgestellten Attribute fest. Dataproc on GKE stellt Konfigurationen von configMap in /etc/spark/conf im Container bereit und überschreibt die im Image eingebetteten Einstellungen.

Basis-Spark-Images

Dataproc unterstützt die folgenden Spark-Container-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 einen benutzerdefinierten Container-Image-Build

Beispiel-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 im Dockerfile-Verzeichnis die folgenden Befehle aus:

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

    gsutil 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 für ein init-Skript.

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