1. Introduction
Présentation
Ce tutoriel explique comment déployer un pool de nœuds de calcul Cloud Run (consommateur) pour traiter les messages Pub/Sub et comment effectuer le scaling automatique de vos instances de consommateur en fonction de la profondeur de la file d'attente à l'aide de l'autoscaling des métriques externes Cloud Run (CREMA).
Points abordés
Au cours de cet atelier de programmation, vous apprendrez à :
- Créez un sujet et un abonnement Pub/Sub, puis envoyez des messages à ce sujet.
- Déployez un pool de nœuds de calcul Cloud Run (consommateur) qui consomme des messages de Pub/Sub.
- Déployez le projet CREMA sur GitHub en tant que service Cloud Run pour mettre automatiquement à l'échelle votre pool de nœuds de calcul en fonction du nombre de messages dans l'abonnement Pub/Sub.
- Testez votre configuration d'autoscaling en générant de la charge à l'aide d'un script Python exécuté en local.
2. Configurer les variables d'environnement
Comme de nombreuses variables d'environnement sont utilisées tout au long de cet atelier de programmation, nous vous recommandons d'exécuter
set -u
qui vous avertit si vous essayez d'utiliser une variable d'environnement qui n'a pas encore été définie. Pour annuler ce paramètre, exécutez set +u
Commencez par remplacer la variable suivante par l'ID de votre projet.
export PROJECT_ID=<YOUR_PROJECT_ID>
et définissez-le comme projet pour cet atelier de programmation.
gcloud config set project $PROJECT_ID
Définissez ensuite les variables d'environnement utilisées par cet atelier de programmation.
export REGION=us-central1
export TOPIC_ID=crema-pubsub-topic
export SUBSCRIPTION_ID=crema-pubsub-sub
export CREMA_SA_NAME=crema-service-account
export CONSUMER_SA_NAME=consumer-service-account
export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
export CREMA_SERVICE_NAME=my-crema-service
Créez un répertoire pour cet atelier de programmation.
mkdir crema-pubsub-codelab
cd crema-pubsub-codelab
Activer les API
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
run.googleapis.com \
parametermanager.googleapis.com
Enfin, assurez-vous que votre gcloud utilise la dernière version.
gcloud components update
3. Configurer Pub/Sub
Créez le sujet et l'abonnement pull que votre pool de nœuds de calcul traitera. Bash
Créez le sujet.
gcloud pubsub topics create $TOPIC_ID
Créez l'abonnement.
gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID
4. IAM et comptes de service
Il est recommandé de créer un compte de service pour chaque ressource Cloud Run. Dans cet atelier de programmation, vous allez créer les éléments suivants :
- Compte de service consommateur : identité du pool de nœuds de calcul traitant les messages Pub/Sub.
- CREMA SA : identité du service de scaling automatique CREMA.
Créer des comptes de service
Créez le compte de service consommateur du pool de nœuds de calcul :
gcloud iam service-accounts create $CONSUMER_SA_NAME \
--display-name="PubSub Consumer Service Account"
Créez le compte de service CREMA du pool de nœuds de calcul :
gcloud iam service-accounts create $CREMA_SA_NAME \
--display-name="CREMA Autoscaler Service Account"
Accorder des autorisations à Consumer SA
Accordez à l'adresse SA du consommateur du pool de nœuds de calcul l'autorisation d'extraire les messages de l'abonnement.
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.subscriber"
Accorder des autorisations à CREMA SA
CREMA a besoin d'autorisations pour lire les paramètres, mettre à l'échelle le pool de nœuds de calcul et surveiller les métriques Pub/Sub.
- Accéder au Gestionnaire de paramètres (lecteur de configuration) :
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/parametermanager.parameterViewer"
- Mettre à l'échelle le pool de nœuds de calcul (développeur Cloud Run) :
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.developer"
- Surveiller Pub/Sub :
Attribuez le rôle Lecteur Monitoring.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"
Ajouter une règle à l'abonnement pour que le compte de service CREMA puisse le consulter
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.viewer"
Le CREMA SA a également besoin du rôle "Utilisateur du compte de service", qui est nécessaire pour modifier le nombre d'instances :
gcloud iam service-accounts add-iam-policy-binding \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
5. Vérifier les autorisations du compte de service
Avant de poursuivre l'atelier de programmation, vérifiez que le compte de service CREMA dispose des rôles appropriés au niveau du projet.
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
Vous devriez obtenir le résultat suivant :
roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer
Vérifiez que l'abonnement Pub/Sub dispose d'une stratégie qui autorise le compte de service CREMA à l'afficher.
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
Résultat attendu
roles/pubsub.viewer
et vérifiez que CREMA SA dispose du rôle Utilisateur de compte de service.
gcloud iam service-accounts get-iam-policy \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
Vous devriez obtenir le résultat suivant :
bindings:
members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
role: roles/iam.serviceAccountUser
Le compte de service consommateur du pool de nœuds de calcul dispose du rôle d'abonné Pub/Sub.
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
Résultat attendu
ROLE
roles/pubsub.subscriber
6. Créer et déployer le pool de nœuds de calcul du consommateur
Créez un répertoire pour votre code consommateur et accédez-y.
mkdir consumer
cd consumer
- Créez un fichier
consumer.py.
import os
import time
from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError
# Configuration
PROJECT_ID = os.environ.get('PROJECT_ID')
SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')
subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"
print(f"Worker Pool instance starting. Watching {subscription_path}...")
subscriber = pubsub_v1.SubscriberClient()
def callback(message):
try:
data = message.data.decode("utf-8")
print(f"Processing job: {data}")
time.sleep(5) # Simulate work
print(f"Done {data}")
message.ack()
except Exception as e:
print(f"Error processing message: {e}")
message.nack()
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}...")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
try:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
streaming_pull_future.result()
except TimeoutError:
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.
except Exception as e:
print(f"Streaming pull failed: {e}")
- Créer un objet
Dockerfile
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
- Déployer le pool de nœuds de calcul du consommateur
Cet atelier de programmation recommande de déployer le pool de nœuds de calcul avec 0 instance pour commencer. Vous pourrez ainsi observer CREMA mettre à l'échelle le pool de nœuds de calcul lorsqu'il détectera les messages Pub/Sub dans l'abonnement.
gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
--source . \
--region $REGION \
--service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--instances=0 \
--set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID
7. Configurer CREMA
- Revenez au répertoire racine de votre projet.
cd ..
- Créer le fichier de configuration Créez un fichier nommé
crema-config.yaml.
apiVersion: crema/v1
kind: CremaConfig
spec:
pollingInterval: 30
triggerAuthentications:
- metadata:
name: adc-trigger-auth
spec:
podIdentity:
provider: gcp
scaledObjects:
- spec:
scaleTargetRef:
name: projects/PROJECT_ID_PLACEHOLDER/locations/REGION_PLACEHOLDER/workerpools/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER
triggers:
- type: gcp-pubsub
metadata:
subscriptionName: "SUBSCRIPTION_ID_PLACEHOLDER"
# Target number of undelivered messages per worker instance
value: "10"
mode: "SubscriptionSize"
authenticationRef:
name: adc-trigger-auth
- Remplacer les variables
sed -i "s/PROJECT_ID_PLACEHOLDER/$PROJECT_ID/g" crema-config.yaml
sed -i "s/REGION_PLACEHOLDER/$REGION/g" crema-config.yaml
sed -i "s/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER/$CONSUMER_WORKER_POOL_NAME/g" crema-config.yaml
sed -i "s/SUBSCRIPTION_ID_PLACEHOLDER/$SUBSCRIPTION_ID/g" crema-config.yaml
- Vérifiez que votre
crema-config.yamlest correct.
if grep -q "_PLACEHOLDER" crema-config.yaml; then
echo "❌ ERROR: Validations failed. '_PLACEHOLDER' was found in crema-config.yaml."
echo "Please check your environment variables and run the 'sed' commands again."
else
echo "✅ Config check passed: No placeholders found."
fi
- Importer dans le gestionnaire de paramètres
Définir des variables d'environnement supplémentaires pour le Gestionnaire de paramètres
export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1
Créer la ressource Parameter
gcloud parametermanager parameters create $PARAMETER_ID \
--location=$PARAMETER_REGION \
--parameter-format=YAML
Créer une version de paramètre 1
gcloud parametermanager parameters versions create $PARAMETER_VERSION \
--parameter=crema-config \
--project=$PROJECT_ID \
--location=$PARAMETER_REGION \
--payload-data-from-file=crema-config.yaml
Vérifier que le paramètre a bien été ajouté
gcloud parametermanager parameters versions list \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION
Vous devriez obtenir un résultat semblable au suivant :
projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1
8. Déployer le service CREMA
Dans cette section, vous allez déployer le service de scaling automatique CREMA. Vous utiliserez l'image accessible au public.
- Définir les variables d'environnement nécessaires pour CREMA
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
- Vérifier le chemin d'accès au nom de la version
echo $CREMA_CONFIG_PARAM_VERSION
Elle devrait se présenter comme ceci :
projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
- Définir la variable d'environnement pour l'image CREMA
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
- et déployer le service CREMA
Notez que l'image de base est obligatoire.
gcloud beta run deploy $CREMA_SERVICE_NAME \
--image=$IMAGE \
--region=${REGION} \
--service-account="${CREMA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--no-allow-unauthenticated \
--no-cpu-throttling \
--labels=created-by=crema \
--base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
--set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True,ENABLE_CLOUD_LOGGING=True"
9. Tests de charge
- Créez un script qui publiera des messages dans le sujet Pub/Sub.
touch load-pubsub.sh
- Ajoutez le code suivant au fichier
load-pubsub.sh.
#!/bin/bash
TOPIC_ID=${TOPIC_ID}
PROJECT_ID=${PROJECT_ID}
NUM_MESSAGES=100
echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."
for i in $(seq 1 $NUM_MESSAGES); do
gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
if (( $i % 10 == 0 )); then
wait
echo "Published $i messages..."
fi
done
wait
echo "Done. All messages published."
- Exécuter un test de charge
chmod +x load-pubsub.sh
./load-pubsub.sh
- Surveillez la mise à l'échelle. Attendez trois à quatre minutes. Affichez les journaux CREMA pour voir les instances recommandées en fonction de la nouvelle configuration authenticationRef.
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
--limit=20 \
--format="value(textPayload)" \
--freshness=5m
- Surveillez le traitement. Consultez les journaux du consommateur pour voir s'il est en cours de démarrage.
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION
Vous devriez voir des journaux tels que
Done job-100
10. Dépannage
Tout d'abord, vous devez déterminer si le problème concerne la configuration du service CREMA ou celle du consommateur Pub/Sub.
Définissez l'autoscaler du consommateur Pub/Sub sur 1 au lieu de 0. Si le traitement des messages Pub/Sub commence immédiatement, il s'agit d'un problème lié à la CREMA. Si elle ne traite pas les messages Pub/Sub, cela signifie qu'il y a un problème avec le consommateur Pub/Sub.
11. Félicitations !
Bravo ! Vous avez terminé cet atelier de programmation.
Nous vous recommandons de consulter la documentation Cloud Run.
Points abordés
- Comment créer un sujet et un abonnement Pub/Sub, et envoyer des messages à ce sujet.
- Comment déployer un pool de nœuds de calcul Cloud Run (consommateur) qui consomme des messages de Pub/Sub.
- Découvrez comment déployer le projet CREMA sur GitHub en tant que service Cloud Run pour mettre automatiquement à l'échelle votre pool de nœuds de calcul en fonction du nombre de messages dans l'abonnement Pub/Sub.
- Découvrez comment tester votre configuration d'autoscaling en générant une charge à l'aide d'un script Python exécuté en local.
12. Effectuer un nettoyage
Pour éviter que les ressources utilisées dans cet atelier de programmation ne soient facturées sur votre compte Google Cloud, vous pouvez supprimer les ressources que vous avez créées ou supprimer l'intégralité du projet.
Supprimer les ressources utilisées dans cet atelier de programmation
- Supprimer le service CREMA Cloud Run
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
- Supprimer le consommateur du pool de nœuds de calcul Cloud Run
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
- Supprimez l'abonnement et le sujet Pub/Sub.
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
- Supprimer la configuration du gestionnaire de paramètres
Supprimer la version dans le paramètre
gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
Supprimez maintenant le paramètre vide.
gcloud parametermanager parameters delete $PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
- Supprimer les comptes de service
gcloud iam service-accounts delete "$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
gcloud iam service-accounts delete "$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
supprimer l'intégralité du projet.
Pour supprimer l'intégralité du projet, accédez à Gérer les ressources, sélectionnez le projet que vous avez créé à l'étape 2, puis choisissez "Supprimer". Si vous supprimez le projet, vous devrez changer de projet dans le SDK Cloud. Vous pouvez afficher la liste de tous les projets disponibles en exécutant gcloud projects list.