Guía de inicio rápido: Compila y crea un trabajo de Go en Cloud Run

Compila y crea un trabajo de Go en Cloud Run

Aprende a crear un trabajo de Cloud Run simple, empaquetarlo en una imagen de contenedor, subir esta imagen de contenedor a Container Registry y, luego, implementarla en Cloud Run. Puedes usar otros lenguajes además de los que se muestran.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud. Obtén información sobre cómo verificar si la facturación está habilitada en un proyecto.

  4. Instala Google Cloud CLI.
  5. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  6. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  7. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud. Obtén información sobre cómo verificar si la facturación está habilitada en un proyecto.

  8. Instala Google Cloud CLI.
  9. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init

Escribe el trabajo de muestra

Para escribir un trabajo en Go, sigue estos pasos:

  1. Crea un directorio nuevo llamado jobs y usa el comando de cambio de directorio en él:

    mkdir jobs
    cd jobs
    
  2. En el mismo directorio, crea un archivo main.go para el código real del trabajo. Copia las siguientes líneas de muestra en él:

    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
    }
    

    Los trabajos de Cloud Run permiten a los usuarios especificar la cantidad de tareas que se ejecutarán en el trabajo. En este código de muestra, se indica cómo usar la variable de entorno integrada CLOUD_RUN_TASK_INDEX. Cada tarea representa una copia en ejecución del contenedor. Ten en cuenta que las tareas se suelen ejecutar en paralelo. Usar múltiples tareas es útil si cada una puede procesar de forma independiente un subconjunto de tus datos.

    Cada tarea conoce su índice, almacenado en la variable de entorno CLOUD_RUN_TASK_INDEX. La variable de entorno CLOUD_RUN_TASK_COUNT integrada contiene la cantidad de tareas que se proporcionan en el momento de la ejecución del trabajo mediante el parámetro --tasks.

    En el código que se muestra, también aparece cómo reintentar tareas mediante la variable de entorno integrada CLOUD_RUN_TASK_ATTEMPT, que contiene la cantidad de veces que se reintentó esta tarea, a partir del 0 para el primer intento y con incrementos de 1 por cada reintento sucesivo, hasta --max-retries.

    El código también te permite generar fallas como una forma de probar los reintentos y generar registros de errores para que puedas ver cómo se ven.

  3. Crea un archivo go.mod con el siguiente contenido:

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

Tu código está completo y listo para empaquetarse en un contenedor.

Compila un contenedor de trabajos y envía al repositorio

Importante: En esta guía de inicio rápido, se supone que tienes roles de propietario o de editor en el proyecto que usas para la guía de inicio rápido. De lo contrario, consulta los permisos de implementación de Cloud Run, los permisos de Cloud Build y los permisos de Artifact Registry para conocer los permisos necesarios.

Usa un Buildpack para compilar el contenedor:

gcloud builds submit --pack image=gcr.io/PROJECT_ID/logger-job

Crea un trabajo en Cloud Run

Para crear un trabajo con el contenedor que acabas de compilar, haz lo siguiente:

gcloud run jobs create job-quickstart \
    --image gcr.io/PROJECT_ID/logger-job \
    --tasks 50 \
    --set-env-vars SLEEP_MS=10000 \
    --set-env-vars FAIL_RATE=0.5 \
    --max-retries 5 \
    --region REGION \
    --project=PROJECT_ID

En el ejemplo anterior, PROJECT_ID es el ID del proyecto y REGION es la región, por ejemplo, us-central1. Ten en cuenta que puedes cambiar los diversos parámetros a cualquier valor que desees usar para fines de prueba. SLEEP_MS simula que el trabajo y FAIL_RATE hacen que el X% de las tareas fallen, por lo que puedes experimentar con el paralelismo y reintentar las tareas con errores.

Ejecuta un trabajo en Cloud Run

Para ejecutar el trabajo que acabas de crear, sigue estos pasos:

gcloud run jobs execute job-quickstart

Cuando se te solicite la región, selecciona la región que prefieras, por ejemplo, us-central1.

Realiza pruebas locales

Puedes ejecutar el trabajo de forma local:

docker run --rm -e FAIL_RATE=0.9 -e SLEEP_MS=1000 gcr.io/PROJECT_ID/logger-job
En el comando anterior, PROJECT_ID es el ID del proyecto.

¿Qué sigue?

Para obtener más información sobre cómo compilar un contenedor a partir de código fuente y enviarlo a un repositorio, consulta los siguientes vínculos: