Concevoir et créer une tâche Go dans Cloud Run

Découvrez comment créer un job Cloud Run simple et le déployer à partir d'une source pour mettre automatiquement votre code en package dans une image de conteneur, importer cette image dans Artifact Registry, puis la déployer dans Cloud Run. Vous pouvez utiliser d'autres langages en plus de ceux présentés.

Avant de commencer

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Make sure that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Activez l'API Cloud Run Admin et l'API Cloud Build :

    gcloud services enable run.googleapis.com \
        cloudbuild.googleapis.com

    Une fois l'API Cloud Run Admin activée, le compte de service Compute Engine par défaut est créé automatiquement.

  11. Pour que Cloud Build puisse créer vos sources, attribuez le rôle Compte de service Cloud Build au compte de service Compute Engine par défaut en exécutant la commande suivante :

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --role=roles/cloudbuild.builds.builder

    Remplacez PROJECT_NUMBER par votre numéro de projet Google Cloud et PROJECT_ID par votre ID de projet Google Cloud. Pour obtenir des instructions détaillées sur la recherche de votre ID et de votre numéro de projet, consultez la section Créer et gérer des projets.

    La propagation du rôle de compte de service Cloud Build au compte de service Compute Engine par défaut prend quelques minutes.

Écrire l'exemple de tâche

Pour écrire une tâche dans Go :

  1. Créez un répertoire nommé jobs et modifiez les sous-répertoires comme suit :

    mkdir jobs
    cd jobs
    
  2. Dans le même répertoire, créez un fichier main.go pour le code de la tâche réelle. Copiez les exemples de lignes suivants :

    package main
    
    import (
    	"fmt"
    	"log"
    	"math/rand"
    	"os"
    	"strconv"
    	"time"
    )
    
    type Config struct {
    	// Job-defined
    	taskNum    string
    	attemptNum string
    
    	// User-defined
    	sleepMs  int64
    	failRate float64
    }
    
    func configFromEnv() (Config, error) {
    	// Job-defined
    	taskNum := os.Getenv("CLOUD_RUN_TASK_INDEX")
    	attemptNum := os.Getenv("CLOUD_RUN_TASK_ATTEMPT")
    	// User-defined
    	sleepMs, err := sleepMsToInt(os.Getenv("SLEEP_MS"))
    	failRate, err := failRateToFloat(os.Getenv("FAIL_RATE"))
    
    	if err != nil {
    		return Config{}, err
    	}
    
    	config := Config{
    		taskNum:    taskNum,
    		attemptNum: attemptNum,
    		sleepMs:    sleepMs,
    		failRate:   failRate,
    	}
    	return config, nil
    }
    
    func sleepMsToInt(s string) (int64, error) {
    	sleepMs, err := strconv.ParseInt(s, 10, 64)
    	return sleepMs, err
    }
    
    func failRateToFloat(s string) (float64, error) {
    	// Default empty variable to 0
    	if s == "" {
    		return 0, nil
    	}
    
    	// Convert string to float
    	failRate, err := strconv.ParseFloat(s, 64)
    
    	// Check that rate is valid
    	if failRate < 0 || failRate > 1 {
    		return failRate, fmt.Errorf("Invalid FAIL_RATE value: %f. Must be a float between 0 and 1 inclusive.", failRate)
    	}
    
    	return failRate, err
    }
    
    func main() {
    	config, err := configFromEnv()
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	log.Printf("Starting Task #%s, Attempt #%s ...", config.taskNum, config.attemptNum)
    
    	// Simulate work
    	if config.sleepMs > 0 {
    		time.Sleep(time.Duration(config.sleepMs) * time.Millisecond)
    	}
    
    	// Simulate errors
    	if config.failRate > 0 {
    		if failure := randomFailure(config); failure != nil {
    			log.Fatalf("%v", failure)
    		}
    	}
    
    	log.Printf("Completed Task #%s, Attempt #%s", config.taskNum, config.attemptNum)
    }
    
    // Throw an error based on fail rate
    func randomFailure(config Config) error {
    	rand.Seed(time.Now().UnixNano())
    	randomFailure := rand.Float64()
    
    	if randomFailure < config.failRate {
    		return fmt.Errorf("Task #%s, Attempt #%s failed.", config.taskNum, config.attemptNum)
    	}
    	return nil
    }
    

    Les jobs Cloud Run permettent aux utilisateurs de spécifier le nombre de tâches que le job doit exécuter. Cet exemple de code montre comment utiliser la variable d'environnement CLOUD_RUN_TASK_INDEX intégrée. Chaque tâche correspond à une copie en cours d'exécution du conteneur. Notez que les tâches sont généralement exécutées en parallèle. L'utilisation de plusieurs tâches est pertinente si chacune d'elles peut traiter indépendamment un sous-ensemble de vos données.

    Chaque tâche connaît son index, stocké dans la variable d'environnement CLOUD_RUN_TASK_INDEX. La variable d'environnement CLOUD_RUN_TASK_COUNT intégrée contient le nombre de tâches fournies au moment de l'exécution du job via le paramètre --tasks.

    Le code présenté montre également comment relancer des tâches à l'aide de la variable d'environnement intégrée CLOUD_RUN_TASK_ATTEMPT, qui contient le nombre de tentatives d'exécution de cette tâche, commençant à 0 pour la première tentative et incrémentée de 1 pour chaque nouvelle tentative, jusqu'à--max-retries.

    Le code vous permet également de générer des échecs afin de tester la répétition des tentatives et de générer des journaux d'erreurs afin que vous puissiez voir à quoi ils ressemblent.

  3. Créez un fichier go.mod avec le contenu suivant :

    module github.com/GoogleCloudPlatform/golang-samples/run/jobs
    
    go 1.21
    

Votre code est terminé et prêt à être empaqueté dans un conteneur.

Créer un conteneur de jobs, l'envoyer à Artifact Registry et le déployer dans Cloud Run

Important : Dans ce guide de démarrage rapide, nous partons du principe que vous disposez de rôles de propriétaire ou d'éditeur dans le projet que vous utilisez pour les besoins du guide de démarrage rapide. Sinon, reportez-vous au rôle Développeur source Cloud Run afin de connaître les autorisations requises pour déployer une ressource Cloud Run depuis la source.

Ce guide de démarrage rapide utilise un déploiement à partir d'une source pour créer le conteneur, l'importer dans Artifact Registry et déployer le job dans Cloud Run :

gcloud run jobs deploy job-quickstart \
    --source . \
    --tasks 50 \
    --set-env-vars SLEEP_MS=10000 \
    --set-env-vars FAIL_RATE=0.1 \
    --max-retries 5 \
    --region REGION \
    --project=PROJECT_ID

PROJECT_ID correspond à votre ID de projet et REGION à votre région, par exemple us-central1. Notez que vous pouvez remplacer les différents paramètres par les valeurs que vous souhaitez utiliser à des fins de test. SLEEP_MS simule le travail et FAIL_RATE entraîne l'échec de X % des tâches afin que vous puissiez tester le parallélisme et réessayer les tâches ayant échoué.

Exécuter un job dans Cloud Run

Pour exécuter le job que vous venez de créer, procédez comme suit :

gcloud run jobs execute job-quickstart --region REGION

Remplacez REGION par la région que vous avez utilisée lors de la création et du déploiement du job (par exemple, us-central1).

Étapes suivantes

Pour savoir comment créer un conteneur à partir d'une source de code et le transférer vers un dépôt, consultez la section suivante :