Images de conteneurs personnalisées Dataproc sur GKE

Vous pouvez spécifier une image de conteneur personnalisée à utiliser avec Dataproc sur GKE . Votre image de conteneur personnalisé doit utiliser l'une des images Spark de base Dataproc sur GKE.

Utiliser une image de conteneur personnalisée

Pour utiliser une image de conteneur personnalisé Dataproc sur GKE, définissez la valeur spark.kubernetes.container.image property lorsque vous créez un cluster virtuel Dataproc sur GKE ou envoyez une tâche Spark au cluster.

  • Exemple de création de cluster avec gcloud CLI:
    gcloud dataproc clusters gke create "${DP_CLUSTER}" \
        --properties=spark:spark.kubernetes.container.image=custom-image \
        ... other args ...
    
  • Exemple d'envoi de job avec gcloud CLI:
    gcloud dataproc jobs submit spark \
        --properties=spark.kubernetes.container.image=custom-image \
        ... other args ...
    

Exigences et paramètres liés aux images de conteneurs personnalisées

Images de base

Vous pouvez utiliser les outils docker pour créer des fichiers Docker personnalisés basés sur l'une des images Spark de base Dataproc sur GKE publiées.

Utilisateur du conteneur

Dataproc sur GKE exécute des conteneurs Spark en tant qu'utilisateur Linux spark avec un UID 1099 et un GID 1099. Utilisez l'UID et le GID pour les autorisations du système de fichiers. Par exemple, si vous ajoutez un fichier JAR à l'emplacement /opt/spark/jars/my-lib.jar de l'image en tant que dépendance de charge de travail, vous devez accorder à l'utilisateur spark l'autorisation de lecture sur ce fichier.

Composants

  • Java:la variable d'environnement JAVA_HOME pointe vers l'emplacement de l'installation de Java. La valeur par défaut actuelle est /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64, qui est susceptible d'être modifiée (consultez les notes de version de Dataproc pour obtenir des informations à jour).

    • Si vous personnalisez l'environnement Java, assurez-vous que JAVA_HOME est défini sur l'emplacement approprié et que PATH inclut le chemin d'accès aux binaires.
  • Python:Miniconda3 est installé dans les images Spark de base de Dataproc sur GKE à l'emplacement /opt/conda. CONDA_HOME pointe vers cet emplacement, ${CONDA_HOME}/bin est inclus dans PATH et PYSPARK_PYTHON est défini sur ${CONDA_HOME}/python.

    • Si vous personnalisez Conda, assurez-vous que CONDA_HOME pointe vers le répertoire d'accueil Conda. ${CONDA_HOME}/bin est inclus dans PATH et PYSPARK_PYTHON est défini sur ${CONDA_HOME}/python..

    • Vous pouvez installer, supprimer et mettre à jour des packages dans l'environnement de base par défaut ou créer un environnement. Toutefois, nous vous recommandons vivement d'inclure tous les packages installés dans l'environnement de base de l'image de conteneur de base.

    • Si vous ajoutez des modules Python, tels qu'un script Python avec des fonctions utilitaires, à l'image du conteneur, incluez les répertoires de module dans PYTHONPATH.

  • Spark:Spark est installé dans /usr/lib/spark, et SPARK_HOME pointe vers cet emplacement. Vous ne pouvez pas personnaliser Spark. Si vous la modifiez, l'image de conteneur sera rejetée ou ne fonctionnera pas correctement.

    • Tâches: vous pouvez personnaliser les dépendances des tâches Spark. SPARK_EXTRA_CLASSPATH définit le chemin de classe supplémentaire pour les processus JVM Spark. Recommandation: Placez les fichiers JAR sous /opt/spark/jars et définissez SPARK_EXTRA_CLASSPATH sur /opt/spark/jars/*.

      Si vous intégrez le fichier JAR de la tâche dans l'image, le répertoire recommandé est /opt/spark/job. Lorsque vous envoyez la tâche, vous pouvez la référencer avec un chemin d'accès local, par exemple file:///opt/spark/job/my-spark-job.jar.

    • Connecteur Cloud Storage:le connecteur Cloud Storage est installé à l'emplacement /usr/lib/spark/jars.

    • Utilitaires: les packages utilitaires procps et tini sont requis pour exécuter Spark. Ces utilitaires sont inclus dans les images Spark de base. Les images personnalisées n'ont donc pas besoin de les réinstaller.

    • Point d'entrée:Dataproc sur GKE ignore les modifications apportées aux primitives ENTRYPOINT et CMD dans l'image du conteneur.

    • Scripts d'initialisation:vous pouvez ajouter un script d'initialisation facultatif à l'adresse /opt/init-script.sh. Un script d'initialisation peut télécharger des fichiers à partir de Cloud Storage, démarrer un proxy dans le conteneur, appeler d'autres scripts et effectuer d'autres tâches de démarrage.

      Le script de point d'entrée appelle le script d'initialisation avec tous les arguments de ligne de commande ($@) avant de démarrer le pilote Spark, l'exécuteur Spark et les autres processus. Le script d'initialisation peut sélectionner le type de processus Spark en fonction du premier argument ($1). Les valeurs possibles sont spark-submit pour les conteneurs de pilotes et executor pour les conteneurs de l'exécuteur.

  • Configurations:les configurations Spark se trouvent sous /etc/spark/conf. La variable d'environnement SPARK_CONF_DIR pointe vers cet emplacement.

    Ne personnalisez pas les configurations Spark dans l'image du conteneur. Envoyez plutôt des propriétés via l'API Dataproc sur GKE pour les raisons suivantes:

    • Certaines propriétés, telles que la taille de la mémoire de l'exécuteur, sont déterminées au moment de l'exécution, et non au moment de la compilation de l'image du conteneur. Elles doivent être injectées par Dataproc sur GKE.
    • Dataproc sur GKE impose des restrictions sur les propriétés fournies par les utilisateurs. Dataproc sur GKE installe les configurations de configMap dans /etc/spark/conf dans le conteneur, remplaçant les paramètres intégrés dans l'image.

Images Spark de base

Dataproc est compatible avec les images de conteneur Spark de base suivantes:

  • 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

Exemple de compilation d'images de conteneurs personnalisés

Exemple de 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

Créer l'image de conteneur

Exécutez les commandes suivantes dans le répertoire Dockerfile.

  1. Définissez l'image (exemple: us-central1-docker.pkg.dev/my-project/spark/spark-test-image:latest) et passez au répertoire de compilation.
    IMAGE=custom container image \
        BUILD_DIR=$(mktemp -d) \
        cd "${BUILD_DIR}"
    
  2. Téléchargez le connecteur BigQuery.

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

  3. Créez un fichier d'exemple Python.

    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. Créez un exemple de script d'initialisation.

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

  5. Créez et transférez l'image.

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