À propos de cet atelier de programmation
1. Introduction
Présentation
Les fonctions Cloud Run sont l'offre Functions as a Service de Google Cloud, basée sur Cloud Run et Eventarc. Elles vous permettent de contrôler plus en détail les performances et l'évolutivité, ainsi que l'environnement d'exécution des fonctions et les déclencheurs à partir de plus de 90 sources d'événements.
Cet atelier de programmation vous explique comment créer des fonctions Cloud Run qui répondent aux appels HTTP et sont déclenchées par des messages Pub/Sub et des journaux d'audit Cloud.
Cet atelier de programmation utilise également les mises à jour automatiques des images de base pour les déploiements de fonctions en spécifiant une image de base à l'aide de l'option --base-image
. Les mises à jour automatiques des images de base pour Cloud Run permettent à Google d'appliquer automatiquement des correctifs de sécurité au système d'exploitation et aux composants d'exécution du langage de l'image de base. Vous n'avez pas besoin de recompiler ou de redéployer votre service pour que l'image de base soit mise à jour. Pour en savoir plus, consultez la section Mises à jour automatiques des images de base.
Si vous préférez ne pas utiliser les mises à jour automatiques de l'image de base, vous pouvez supprimer l'option --base-image
des exemples présentés dans cet atelier de programmation.
Points abordés
- Présentation des fonctions Cloud Run et de l'utilisation des mises à jour automatiques des images de base.
- Écrire une fonction qui répond aux appels HTTP
- Écrire une fonction qui répond aux messages Pub/Sub
- Écrire une fonction qui répond aux événements Cloud Storage
- Répartir le trafic entre deux révisions
- Comment éliminer les démarrages à froid avec un nombre minimal d'instances
2. Préparation
Créer un dossier racine
Créez un dossier racine pour tous les exemples.
mkdir crf-codelab cd crf-codelab
Configurer des variables d'environnement
Définissez les variables d'environnement qui seront utilisées tout au long de cet atelier de programmation.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
Activer les API
Activez tous les services nécessaires :
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Fonction HTTP
Pour la première fonction, créons une fonction Node.js authentifiée qui répond aux requêtes HTTP. Utilisons également un délai avant expiration de 10 minutes pour montrer comment une fonction peut avoir plus de temps pour répondre aux requêtes HTTP.
Créer
Créez un dossier pour l'application et accédez-y:
mkdir hello-http cd hello-http
Créez un fichier index.js
qui répond aux requêtes HTTP:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
Créez un fichier package.json
pour spécifier les dépendances:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Déployer
Déployez la fonction :
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
Cette commande utilise des buildpacks pour transformer le code source de votre fonction en image de conteneur prête à la production.
Remarques :
- L'indicateur
--source
permet d'indiquer à Cloud Run de créer la fonction dans un service basé sur des conteneurs exécutables. - L'indicateur
--function
(nouveau) permet de définir le point d'entrée du nouveau service sur la signature de fonction que vous souhaitez appeler. - L'indicateur
--base-image
(nouveau) spécifie l'environnement d'image de base de votre fonction, par exemplenodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
ouphp83
. Pour en savoir plus sur les images de base et les packages inclus dans chaque image, consultez Images de base des environnements d'exécution. - (facultatif) L'indicateur
--timeout
permet à la fonction d'avoir un délai avant expiration plus long pour répondre aux requêtes HTTP. Dans cet exemple, 600 secondes sont utilisées pour illustrer un temps de réponse de 10 minutes. - (Facultatif)
--no-allow-unauthenticated
pour empêcher l'appel public de votre fonction
Tester
Testez la fonction à l'aide des commandes suivantes:
# get the Service URL SERVICE_URL="$(gcloud run services describe nodejs-run-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Le message HTTP with Node.js in Cloud Run functions!
doit s'afficher en réponse.
4. Fonction Pub/Sub
Pour la deuxième fonction, créons une fonction Python déclenchée par un message Pub/Sub publié sur un sujet spécifique.
Configurer des jetons d'autorisation Pub/Sub
Si vous avez activé le compte de service Pub/Sub le 8 avril 2021 ou avant cette date, attribuez le rôle iam.serviceAccountTokenCreator
au compte de service Pub/Sub:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
Créer
Créez un sujet Pub/Sub à utiliser pour l'exemple:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Créez un dossier pour l'application et accédez-y:
mkdir ../hello-pubsub cd ../hello-pubsub
Créez un fichier main.py
qui consigne un message contenant l'ID CloudEvent:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in Cloud Run functions! Id: ' + cloud_event['id'])
Créez un fichier requirements.txt
avec le contenu suivant pour spécifier les dépendances:
functions-framework==3.*
Déployer
Déployez la fonction :
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Récupérez le numéro de projet à utiliser pour l'identité du compte de service.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Créer le déclencheur
gcloud eventarc triggers create python-pubsub-function-trigger \ --location=$REGION \ --destination-run-service=python-pubsub-function \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Tester
Testez la fonction en envoyant un message au sujet:
gcloud pubsub topics publish $TOPIC --message="Hello World"
L'événement CloudEvent reçu doit apparaître dans les journaux :
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Fonction Cloud Storage
Pour la fonction suivante, créons une fonction Node.js qui répond aux événements d'un bucket Cloud Storage.
Configurer
Pour utiliser les fonctions Cloud Storage, attribuez le rôle IAM pubsub.publisher
au compte de service Cloud Storage:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Créer
Créez un dossier pour l'application et accédez-y:
mkdir ../hello-storage cd ../hello-storage
Créez un fichier index.js
qui répond simplement aux événements Cloud Storage:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in Cloud Run functions!'); console.log(cloudevent); });
Créez un fichier package.json
pour spécifier les dépendances:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Déployer
Commencez par créer un bucket Cloud Storage (ou utilisez un bucket existant):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Déployez la fonction :
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Une fois la fonction déployée, vous pouvez la voir dans la section "Cloud Run" de la console Cloud.
Créez maintenant le déclencheur Eventarc.
BUCKET_REGION=$REGION gcloud eventarc triggers create nodejs-crf-cloud-storage-trigger \ --location=$BUCKET_REGION \ --destination-run-service=nodejs-crf-cloud-storage \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Tester
Testez la fonction en important un fichier dans le bucket:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
L'événement CloudEvent reçu doit apparaître dans les journaux :
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Répartition du trafic
Les fonctions Cloud Run acceptent plusieurs révisions de vos fonctions, ce qui vous permet de répartir le trafic entre différentes révisions et d'effectuer un rollback de votre fonction vers une version précédente.
À cette étape, vous allez déployer deux révisions d'une fonction, puis répartir le trafic entre elles à 50/50.
Créer
Créez un dossier pour l'application et accédez-y:
mkdir ../traffic-splitting cd ../traffic-splitting
Créez un fichier main.py
avec une fonction Python qui lit une variable d'environnement de couleur et renvoie Hello World
avec cette couleur d'arrière-plan:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Créez un fichier requirements.txt
avec le contenu suivant pour spécifier les dépendances:
functions-framework==3.*
Déployer
Déployez la première révision de la fonction avec un arrière-plan orange:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
À ce stade, si vous testez la fonction en affichant le déclencheur HTTP (la sortie URI de la commande de déploiement ci-dessus) dans votre navigateur, vous devriez voir Hello World
avec un arrière-plan orange:
Déployez la deuxième révision avec un arrière-plan jaune:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Comme il s'agit de la dernière révision, si vous testez la fonction, Hello World
devrait s'afficher avec un arrière-plan jaune:
Répartir le trafic en 50/50
Pour répartir le trafic entre les révisions orange et jaune, vous devez trouver les ID de révision des services Cloud Run. Voici la commande à exécuter pour afficher les ID de révision:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
La sortie devrait ressembler à ce qui suit :
hello-world-colors-00001-man hello-world-colors-00002-wok
Répartissez maintenant le trafic entre ces deux révisions comme suit (modifiez X-XXX
en fonction des noms de vos révisions):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Tester
Testez la fonction en accédant à son URL publique. La moitié du temps, vous devriez voir la version orange et l'autre moitié, la version jaune:
Pour en savoir plus, consultez la section Rollbacks, déploiements progressifs et migration du trafic.
7. Nombre minimal d'instances
Dans les fonctions Cloud Run, vous pouvez spécifier un nombre minimal d'instances de fonction à garder en attente et prêtes à diffuser des requêtes. Cela permet de limiter le nombre de démarrages à froid.
À cette étape, vous allez déployer une fonction avec une initialisation lente. Vous observerez le problème de démarrage à froid. Vous allez ensuite déployer la fonction avec la valeur d'instance minimale définie sur 1 pour supprimer le démarrage à froid.
Créer
Créez un dossier pour l'application et accédez-y:
mkdir ../min-instances cd ../min-instances
Créez un fichier main.go
. Ce service Go comporte une fonction init
qui passe en veille pendant 10 secondes pour simuler une longue initialisation. Il comporte également une fonction HelloWorld
qui répond aux appels HTTP:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in Cloud Run functions!") }
Déployer
Déployez la première révision de la fonction avec une valeur d'instance minimale par défaut de zéro:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Testez la fonction avec cette commande:
# get the Service URL SERVICE_URL="$(gcloud run services describe go-slow-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Vous constaterez un délai de 10 secondes (démarrage à froid) au premier appel, puis le message s'affichera. Les appels suivants doivent être renvoyés immédiatement.
Définir le nombre minimal d'instances
Pour supprimer le démarrage à froid lors de la première requête, redéployez la fonction avec l'indicateur --min-instances
défini sur 1 comme suit:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Tester
Testez à nouveau la fonction:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Le délai de 10 secondes ne devrait plus s'afficher dans la première requête. Le problème de démarrage à froid pour la première invocation (après une longue période sans) a disparu, grâce aux instances minimales.
Pour en savoir plus, consultez la section Utiliser un nombre minimal d'instances.
8. Félicitations !
Félicitations ! Vous avez terminé cet atelier de programmation.
Points abordés
- Présentation des fonctions Cloud Run et de l'utilisation des mises à jour automatiques des images de base.
- Écrire une fonction qui répond aux appels HTTP
- Écrire une fonction qui répond aux messages Pub/Sub
- Écrire une fonction qui répond aux événements Cloud Storage
- Répartir le trafic entre deux révisions
- Comment éliminer les démarrages à froid avec un nombre minimal d'instances