Premiers pas avec les fonctions Cloud Run

Premiers pas avec les fonctions Cloud Run

À propos de cet atelier de programmation

subjectDernière mise à jour : mai 7, 2025
account_circleRédigé par Mete Atamel

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 exemple nodejs22, python312, go123, java21, dotnet8, ruby33 ou php83. 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:

36ca0c5f39cc89cf.png

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:

391286a08ad3cdde.png

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:

36ca0c5f39cc89cf.png 391286a08ad3cdde.png

Pour en savoir plus, consultez la section Rollbacks, déploiements progressifs et migration du trafic.

7. Nombre minimal d&#39;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