Utiliser des conteneurs personnalisés dans Dataflow

Cette page explique comment personnaliser l'environnement d'exécution du code utilisateur Python dans les pipelines Dataflow en fournissant une image de conteneur personnalisé. Les conteneurs personnalisés ne sont compatibles qu'avec les pipelines portables qui utilisent Dataflow Runner v2.

Lorsque Dataflow lance des VM de nœud de calcul, il utilise des images de conteneurs Docker. Vous pouvez spécifier une image de conteneur personnalisée au lieu d'utiliser l'une des images Apache Beam par défaut. Lorsque vous spécifiez une image de conteneur personnalisée, Dataflow lance des nœuds de calcul qui extraient l'image spécifiée. Voici quelques raisons pour lesquelles vous pouvez utiliser un conteneur personnalisé:

  • Préinstallation des dépendances de pipeline pour réduire le temps de démarrage des nœuds de calcul.
  • Préinstallation des dépendances de pipeline non disponibles dans les dépôts publics.
  • Lancement d'un logiciel tiers en arrière-plan.
  • Personnalisation de l'environnement d'exécution.

Pour une présentation plus détaillée des conteneurs personnalisés, consultez le guide des conteneurs personnalisés Apache Beam.

Avant de commencer

Vérifiez que la version 2.25.0 ou ultérieure du SDK Apache Beam est installée. Vérifiez que cette version du SDK Apache Beam est compatible avec votre version de Python. Pour en savoir plus, consultez le guide d'installation du SDK Apache Beam.

Assurez-vous que Docker est installé pour tester l'image de conteneur en local. Pour en savoir plus, consultez la page Obtenir Docker.

Créer l'image de conteneur

Dans cet exemple, nous utilisons Python 3.8 avec le SDK Apache Beam version 2.25.0. Pour créer une image de conteneur personnalisé, spécifiez l'image Apache Beam en tant qu'image parente et ajoutez vos propres personnalisations.

  1. Créez un fichier Dockerfile, en spécifiant le apache/beam_python3.8_sdk:2.25.0 en tant que parent et en ajoutant des personnalisations. Pour en savoir plus sur l'écriture de fichiers Dockerfile, consultez la section Bonnes pratiques pour l'écriture de fichiers Dockerfile.
    FROM apache/beam_python3.8_sdk:2.25.0
    # Make your customizations here, for example:
    ENV FOO=/bar
    COPY path/to/myfile ./
  2. Créez l'image enfant, puis transférez cette image vers un registre de conteneurs.

    Cloud Build

    export PROJECT=PROJECT
    export REPO=REPO
    export TAG=TAG
    export REGISTRY_HOST=HOST
    export IMAGE_URI=$REGISTRY_HOST/$PROJECT/$REPO:$TAG
    
    gcloud builds submit --tag $IMAGE_URI

    Docker

    export PROJECT=PROJECT
    export REPO=REPO
    export TAG=TAG
    export REGISTRY_HOST=HOST
    export IMAGE_URI=$REGISTRY_HOST/$PROJECT/$REPO:$TAG
    
    docker build -f Dockerfile -t $IMAGE_URI ./
    docker push $IMAGE_URI
    Remplacez l'élément suivant :
    • PROJECT : nom du projet ou de l'utilisateur.
    • REPO : nom du dépôt de l'image.
    • TAG : tag de l'image.
    • HOST : nom d'hôte du registre d'images, par exemple gcr.io.

Exécuter une tâche avec des conteneurs personnalisés

Lors de l'exécution du pipeline, utilisez la même version de Python et du SDK Apache Beam que celle indiquée dans l'image de conteneur personnalisé afin d'éviter les erreurs inattendues.

Tester localement

Testez l'image de conteneur localement en exécutant l'exemple wordcount Apache Beam à l'aide de PortableRunner :

python -m apache_beam.examples.wordcount \
  --input=INPUT_FILE \
  --output=OUTPUT_FILE \
  --runner=PortableRunner \
  --job_endpoint=embed \
  --environment_type=DOCKER \
  --environment_config=$IMAGE_URI

Remplacez l'élément suivant :

  • INPUT_FILE: fichier d'entrée pouvant être lu comme un fichier texte. Ce fichier doit être accessible par l'image de conteneur
    du SDK exploité, qui est préchargée sur l'image du conteneur ou dans un fichier distant.
  • OUTPUT_FILE: chemin d'accès au fichier dans lequel écrire le résultat. Ce chemin d'accès est un chemin d'accès distant ou un chemin d'accès local sur le conteneur.
  • $IMAGE_URI: URI de l'image du conteneur personnalisé. Vous pouvez utiliser la variable d'interface système $IMAGE_URI construite à l'étape précédente si la variable fait toujours partie du champ d'application.

Une fois le pipeline terminé, consultez les journaux de la console pour vérifier que le pipeline a bien été effectué et que l'image distante spécifiée par $IMAGE_URI a été utilisée.

Ce test local permet de vérifier l'image réelle du conteneur. Le pipeline lui-même doit être validé sans image de conteneur avant cette étape, par exemple à l'aide de DirectRunner. La nature isolée des conteneurs empêche l'accès aux systèmes de fichiers locaux et à la configuration locale, comme les variables d'environnement.

Cela signifie que les fichiers d'entrée locaux ou d'identifiants, ainsi que les variables d'environnement locales, comme celles utilisées pour configurer les identifiants par défaut de l'application, ne sont pas accessibles par le conteneur. Les résultats locaux sont écrits dans le système de fichiers du conteneur et ne sont pas accessibles une fois le conteneur arrêté et le pipeline terminé.

Si ces résultats doivent être persistants, fournissez un système de fichiers distant comme chemin de sortie et assurez-vous que l'accès à ce système de fichiers distant est configuré sur le conteneur lui-même. L'ajout d'une journalisation temporaire peut également s'avérer utile pour le débogage.

Pour en savoir plus, consultez le guide Apache Beam pour Exécuter des pipelines avec des images de conteneurs personnalisés.

Lancer la tâche Dataflow

Indiquez le chemin d'accès à l'image de conteneur lors du lancement du pipeline Apache Beam sur Dataflow. Si vous lancez un pipeline Python par lots, vous devez définir l'option --experiment=use_runner_v2. Si vous lancez un pipeline Python de traitement par flux, vous n'avez pas besoin de spécifier le test. Par exemple, pour lancer l'exemple de décompte par lot avec une image de conteneur personnalisée, procédez comme suit :

python -m apache_beam.examples.wordcount \
  --input=INPUT_FILE \
  --output=OUTPUT_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --temp_location=TEMP_LOCATION \
  --runner=DataflowRunner \
  --experiment=use_runner_v2 \
  --worker_harness_container_image=$IMAGE_URI

Remplacez l'élément suivant :

  • INPUT_FILE : chemin d'accès au fichier d'entrée Cloud Storage lu par Dataflow lors de l'exécution de l'exemple.
  • OUTPUT_FILE : chemin d'accès du fichier de sortie Cloud Storage sur lequel l'exemple de pipeline écrit. Il contient le nombre de mots.
  • PROJECT_ID : ID de votre projet Google Cloud.
  • REGION : point de terminaison régional pour le déploiement de votre tâche Dataflow.
  • TEMP_LOCATION : chemin d'accès à Cloud Storage dans lequel Dataflow prépare les fichiers de tâches temporaires créés lors de l'exécution du pipeline.
  • $IMAGE_URI: URI de l'image du conteneur personnalisé. Vous pouvez utiliser la variable d'interface système $IMAGE_URI construite à l'étape précédente si la variable fait toujours partie du champ d'application.

Dépannage

Cette section fournit des instructions pour résoudre les problèmes courants rencontrés lors de l'interaction avec des conteneurs personnalisés dans Dataflow.

Avant de contacter l'assistance, assurez-vous d'avoir résolu les problèmes liés à votre image de conteneur en suivant les étapes de test local et des sections de dépannage suivantes.

Rechercher des journaux de conteneur

Les journaux des nœuds de calcul Dataflow des messages d'erreur liés au conteneur sont disponibles dans l'explorateur de journaux :

  1. Sélectionnez les noms de journaux suivants :

    • dataflow.googleapis.com/docker
    • dataflow.googleapis.com/kubelet
    • dataflow.googleapis.com/worker
  2. Sélectionnez la ressource Dataflow Step et spécifiez job_id.

Les nœuds de calcul ne démarrent pas

Si vos nœuds de calcul ne démarrent pas ou si votre tâche expire, vérifiez que Dataflow est en mesure d'extraire votre image de conteneur personnalisé.

Interrogez les journaux Dataflow à l'aide de l'explorateur de journaux pour obtenir un message de journal Error Syncing pod... avec la requête suivante :

resource.type="dataflow_step" AND jsonPayload.message:("$IMAGE_URI") AND severity="ERROR"

Les nœuds de calcul Dataflow doivent pouvoir accéder à l'image afin que les nœuds de calcul puissent l'extraire au démarrage. Si vous utilisez Container Registry pour héberger votre image de conteneur, le compte de service Google Cloud par défaut est déjà en mesure d'accéder aux images du même projet. Si Dataflow ne parvient pas à extraire l'image du conteneur, les nœuds de calcul ne peuvent pas démarrer.

Pour en savoir plus, consultez la section Configurer le contrôle des accès.