Acerca de este codelab
1. Introducción
Descripción general
Cloud Run Functions es la oferta de funciones como servicio de Google Cloud con la tecnología de Cloud Run y Eventarc, que te brinda un control más avanzado sobre el rendimiento y la escalabilidad, y más control sobre el tiempo de ejecución de las funciones y los activadores de más de 90 fuentes de eventos.
En este codelab, se te guiará para crear funciones de Cloud Run que respondan a llamadas HTTP y se activen con mensajes de Pub/Sub y registros de auditoría de Cloud.
En este codelab, también se usan actualizaciones automáticas de imágenes base para las implementaciones de funciones. Para ello, se especifica una imagen base con la marca --base-image
. Las actualizaciones automáticas de imágenes base para Cloud Run permiten que Google aplique parches de seguridad al sistema operativo y a los componentes del entorno de ejecución de lenguaje de la imagen base automáticamente. No es necesario volver a compilar o volver a implementar el servicio para que se actualice la imagen base. Para obtener más información, consulta las actualizaciones automáticas de las imágenes base.
Si prefieres no usar actualizaciones automáticas de imágenes base, puedes quitar la marca --base-image
de los ejemplos que se muestran en este codelab.
Qué aprenderás
- Descripción general de las funciones de Cloud Run y cómo usar las actualizaciones automáticas de imágenes base.
- Cómo escribir una función que responda a llamadas HTTP
- Cómo escribir una función que responda a los mensajes de Pub/Sub
- Cómo escribir una función que responda a eventos de Cloud Storage
- Cómo dividir el tráfico entre dos revisiones
- Cómo deshacerte de los inicios en frío con instancias mínimas
2. Configuración y requisitos
Cómo crear una carpeta raíz
Crea una carpeta raíz para todos los ejemplos.
mkdir crf-codelab cd crf-codelab
Configura variables de entorno
Establece las variables de entorno que se usarán en este codelab.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
Habilita las APIs
Habilita todos los servicios necesarios con el siguiente comando:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Función HTTP
Para la primera función, crearemos una función de Node.js autenticada que responda a las solicitudes HTTP. También usaremos un tiempo de espera de 10 minutos para mostrar cómo una función puede tener más tiempo para responder a las solicitudes HTTP.
Creación
Crea una carpeta para la app y navega a ella:
mkdir hello-http cd hello-http
Crea un archivo index.js
que responda a las solicitudes 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!'); });
Crea un archivo package.json
para especificar las dependencias:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implementación
Sigue estos pasos para implementar la función:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
Este comando usa paquetes de compilación para transformar el código fuente de tu función en una imagen de contenedor lista para producción.
Ten en cuenta lo siguiente:
- La marca
--source
se usa para indicarle a Cloud Run que compile la función en un servicio ejecutable basado en contenedores. - La marca
--function
(nueva) se usa para establecer el punto de entrada del servicio nuevo como la firma de la función que deseas invocar. - La marca
--base-image
(nueva) especifica el entorno de imagen base para tu función, comonodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
ophp83
. Para obtener más detalles sobre las imágenes base y los paquetes incluidos en cada una, consulta Imágenes base de los entornos de ejecución. - (opcional) La marca
--timeout
permite que la función tenga un tiempo de espera más largo para responder a las solicitudes HTTP. En este ejemplo, se usan 600 segundos para demostrar un tiempo de respuesta de 10 minutos. - (opcional)
--no-allow-unauthenticated
para evitar que tu función se pueda invocar públicamente
Prueba
Prueba la función con los siguientes comandos:
# 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
Deberías ver el mensaje HTTP with Node.js in Cloud Run functions!
como respuesta.
4. Función de Pub/Sub
Para la segunda función, crearemos una función de Python activada por un mensaje de Pub/Sub publicado en un tema específico.
Configura los tokens de autenticación de Pub/Sub
Si habilitaste la cuenta de servicio de Pub/Sub el 8 de abril de 2021 o antes de esa fecha, otorga el rol iam.serviceAccountTokenCreator
a la cuenta de servicio de 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
Creación
Crea un tema de Pub/Sub para usar en la muestra:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Crea una carpeta para la app y navega a ella:
mkdir ../hello-pubsub cd ../hello-pubsub
Crea un archivo main.py
que registre un mensaje que contenga el ID de 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'])
Crea un archivo requirements.txt
con el siguiente contenido para especificar las dependencias:
functions-framework==3.*
Implementación
Sigue estos pasos para implementar la función:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Recupera el número de proyecto que se usará para la identidad de la cuenta de servicio.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Crea el activador
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
Prueba
Para probar la función, envía un mensaje al tema:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Debería ver el CloudEvent recibido en los registros:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Función de Cloud Storage
Para la siguiente función, crearemos una función de Node.js que responda a eventos de un bucket de Cloud Storage.
Configurar
Para usar las funciones de Cloud Storage, otorga el rol de IAM pubsub.publisher
a la cuenta de servicio de 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
Creación
Crea una carpeta para la app y navega a ella:
mkdir ../hello-storage cd ../hello-storage
Crea un archivo index.js
que simplemente responda a los eventos de 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); });
Crea un archivo package.json
para especificar las dependencias:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implementación
Primero, crea un bucket de Cloud Storage (o usa uno existente):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Sigue estos pasos para implementar la función:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Una vez que se implemente la función, podrás verla en la sección Cloud Run de la consola de Cloud.
Ahora, crea el activador de 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
Prueba
Sube un archivo al bucket para probar la función:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Debería ver el CloudEvent recibido en los registros:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. División del tráfico
Las funciones de Cloud Run admiten varias revisiones de tus funciones, lo que te permite dividir el tráfico entre diferentes revisiones y revertir la función a una versión anterior.
En este paso, implementarás 2 revisiones de una función y, luego, dividirás el tráfico entre ellas en partes iguales.
Creación
Crea una carpeta para la app y navega a ella:
mkdir ../traffic-splitting cd ../traffic-splitting
Crea un archivo main.py
con una función de Python que lea una variable de entorno de color y responda con Hello World
en ese color de fondo:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Crea un archivo requirements.txt
con el siguiente contenido para especificar las dependencias:
functions-framework==3.*
Implementación
Implementa la primera revisión de la función con un fondo naranja:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
En este punto, si pruebas la función viendo el activador HTTP (el resultado del URI del comando de implementación anterior) en tu navegador, deberías ver Hello World
con un fondo naranja:
Implementa la segunda revisión con un fondo amarillo:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Como esta es la revisión más reciente, si pruebas la función, deberías ver Hello World
con un fondo amarillo:
Cómo dividir el tráfico 50/50
Para dividir el tráfico entre las revisiones naranja y amarilla, debes encontrar los IDs de revisión de los servicios de Cloud Run. Este es el comando para ver los IDs de revisión:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
El resultado debería ser similar al siguiente ejemplo:
hello-world-colors-00001-man hello-world-colors-00002-wok
Ahora, divide el tráfico entre estas dos revisiones de la siguiente manera (actualiza el X-XXX
según los nombres de tus revisiones):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Prueba
Para probar la función, visita su URL pública. La mitad de las veces, deberías ver la revisión naranja y, la otra mitad, la revisión amarilla:
Consulta reversiones, lanzamientos graduales y migración de tráfico para obtener más información.
7. Cantidad mínima de instancias
En las funciones de Cloud Run, puedes especificar una cantidad mínima de instancias de función que se deben mantener en espera y listas para entregar solicitudes. Esto es útil para limitar la cantidad de inicios en frío.
En este paso, implementarás una función con inicialización lenta. Observarás el problema de inicio en frío. Luego, implementarás la función con el valor de instancia mínima establecido en 1 para eliminar el inicio en frío.
Creación
Crea una carpeta para la app y navega hasta ella:
mkdir ../min-instances cd ../min-instances
Crea un archivo main.go
. Este servicio de Go tiene una función init
que se suspende durante 10 segundos para simular una inicialización larga. También tiene una función HelloWorld
que responde a las llamadas 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!") }
Implementación
Implementa la primera revisión de la función con el valor mínimo predeterminado de instancia cero:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Prueba la función con este comando:
# 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
Observarás una demora de 10 segundos (inicio en frío) en la primera llamada y, luego, verás el mensaje. Las llamadas posteriores deberían mostrarse de inmediato.
Establece la cantidad mínima de instancias
Para deshacerte del inicio en frío en la primera solicitud, vuelve a implementar la función con la marca --min-instances
establecida en 1 de la siguiente manera:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Prueba
Vuelve a probar la función:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Ya no deberías ver la demora de 10 segundos en la primera solicitud. El problema de inicio en frío de la primera invocación (después de mucho tiempo sin él) desapareció, gracias a las instancias mínimas.
Consulta Usa una cantidad mínima de instancias para obtener más información.
8. ¡Felicitaciones!
¡Felicitaciones por completar el codelab!
Temas abordados
- Descripción general de las funciones de Cloud Run y cómo usar las actualizaciones automáticas de imágenes base.
- Cómo escribir una función que responda a llamadas HTTP
- Cómo escribir una función que responda a los mensajes de Pub/Sub
- Cómo escribir una función que responda a eventos de Cloud Storage
- Cómo dividir el tráfico entre dos revisiones
- Cómo deshacerte de los inicios en frío con instancias mínimas