1. Introducción
Descripción general
En este instructivo, se muestra cómo implementar un grupo de trabajadores (consumidor) de Cloud Run para procesar mensajes de Pub/Sub y cómo ajustar automáticamente la escala de tus instancias de consumidor según la profundidad de la cola con el ajuste de escala automático basado en métricas externas de Cloud Run (CREMA).
Qué aprenderás
En este codelab, harás lo siguiente:
- Crea un tema y una suscripción de Pub/Sub, y envía mensajes a ese tema.
- Implementa un grupo de trabajadores de Cloud Run (consumidor) que consuma mensajes de Pub/Sub.
- Implementa el proyecto de CREMA en GitHub como un servicio de Cloud Run para ajustar automáticamente la escala de tu grupo de trabajadores según la cantidad de mensajes en la suscripción a Pub/Sub.
- Para probar tu configuración del ajuste de escala automático, genera carga ejecutando una secuencia de comandos de Python de forma local.
2. Configura variables de entorno
Como se usan muchas variables de entorno a lo largo de este codelab, te recomendamos que ejecutes
set -u
que te advertirá si intentas usar una variable de entorno que aún no se configuró. Para deshacer este parámetro de configuración, ejecuta set +u
Primero, cambia la siguiente variable por el ID de tu proyecto.
export PROJECT_ID=<YOUR_PROJECT_ID>
y, luego, configúralo como el proyecto para este codelab.
gcloud config set project $PROJECT_ID
A continuación, configura las variables de entorno que se usan en este codelab.
export REGION=us-central1
export TOPIC_ID=crema-pubsub-topic
export SUBSCRIPTION_ID=crema-pubsub-sub
export CREMA_SA_NAME=crema-service-account
export CONSUMER_SA_NAME=consumer-service-account
export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
export CREMA_SERVICE_NAME=my-crema-service
Crea un directorio para este codelab
mkdir crema-pubsub-codelab
cd crema-pubsub-codelab
Habilita las APIs
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
run.googleapis.com \
parametermanager.googleapis.com
Por último, asegúrate de que tu gcloud esté usando la versión más reciente.
gcloud components update
3. Configuración de Pub/Sub
Crea el tema y la suscripción de extracción que procesará tu grupo de trabajadores. Bash
Crea el tema.
gcloud pubsub topics create $TOPIC_ID
Crea la suscripción.
gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID
4. IAM y cuentas de servicio
Se recomienda crear una cuenta de servicio para cada recurso de Cloud Run. En este codelab, crearás lo siguiente:
- SA del consumidor: Es la identidad del grupo de trabajadores que procesa los mensajes de Pub/Sub.
- CREMA SA: Es la identidad del servicio de ajuste automático de CREMA.
Creador de cuentas de servicio
Crea la SA del consumidor del grupo de trabajadores:
gcloud iam service-accounts create $CONSUMER_SA_NAME \
--display-name="PubSub Consumer Service Account"
Crea la SA del servicio CREMA del grupo de trabajadores:
gcloud iam service-accounts create $CREMA_SA_NAME \
--display-name="CREMA Autoscaler Service Account"
Otorga permisos a la SA del consumidor
Otorga permisos a la SA del consumidor del grupo de trabajadores para extraer mensajes de la suscripción.
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.subscriber"
Otorga permisos a CREMA SA
CREMA necesita permisos para leer parámetros, ajustar la escala del grupo de trabajadores y supervisar las métricas de Pub/Sub.
- Accede al Administrador de parámetros (lector de configuración):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/parametermanager.parameterViewer"
- Ajusta la escala del grupo de trabajadores (desarrollador de Cloud Run):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.developer"
- Supervisa Pub/Sub:
Otorga el rol de visualizador de Monitoring.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"
Agrega una política a la suscripción para que la SA del servicio de CREMA pueda verla
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.viewer"
El CREMA SA también necesita el rol de usuario de cuenta de servicio, que es necesario para cambiar los recuentos de instancias:
gcloud iam service-accounts add-iam-policy-binding \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
5. Verifica los permisos de SA
Antes de continuar con el codelab, verifica que la SA del servicio de CREMA tenga los roles correctos a nivel del proyecto.
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
Debería mostrar el siguiente resultado:
roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer
Verifica que la suscripción a Pub/Sub tenga una política que permita que la SA del servicio de CREMA la vea.
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
Debería dar como resultado
roles/pubsub.viewer
y verifica que la SA de CREMA tenga el rol de usuario de cuenta de servicio.
gcloud iam service-accounts get-iam-policy \
$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
Debería generar el siguiente resultado:
bindings:
members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
role: roles/iam.serviceAccountUser
Y la SA de Worker Pool Consumer tiene el rol de suscriptor de Pub/Sub.
gcloud pubsub subscriptions get-iam-policy $SUBSCRIPTION_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--format="table(bindings.role)"
Debería dar como resultado
ROLE
roles/pubsub.subscriber
6. Compila e implementa el grupo de trabajadores del consumidor
Crea un directorio para el código del consumidor y accede a él.
mkdir consumer
cd consumer
- Crea un archivo
consumer.py
import os
import time
from google.cloud import pubsub_v1
from concurrent.futures import TimeoutError
# Configuration
PROJECT_ID = os.environ.get('PROJECT_ID')
SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')
subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"
print(f"Worker Pool instance starting. Watching {subscription_path}...")
subscriber = pubsub_v1.SubscriberClient()
def callback(message):
try:
data = message.data.decode("utf-8")
print(f"Processing job: {data}")
time.sleep(5) # Simulate work
print(f"Done {data}")
message.ack()
except Exception as e:
print(f"Error processing message: {e}")
message.nack()
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}...")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
try:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
streaming_pull_future.result()
except TimeoutError:
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.
except Exception as e:
print(f"Streaming pull failed: {e}")
- Cómo crear un
Dockerfile
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
- Implementa un grupo de trabajadores de consumidor
En este codelab, se recomienda implementar el grupo de trabajadores con 0 instancias para comenzar, de modo que puedas observar cómo CREMA ajusta el grupo de trabajadores cuando detecta los mensajes de Pub/Sub en la suscripción.
gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
--source . \
--region $REGION \
--service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--instances=0 \
--set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID
7. Configura CREMA
- Regresa al directorio raíz de tu proyecto.
cd ..
- Crea el archivo de configuración. Crea un archivo llamado
crema-config.yaml.
apiVersion: crema/v1
kind: CremaConfig
spec:
pollingInterval: 30
triggerAuthentications:
- metadata:
name: adc-trigger-auth
spec:
podIdentity:
provider: gcp
scaledObjects:
- spec:
scaleTargetRef:
name: projects/PROJECT_ID_PLACEHOLDER/locations/REGION_PLACEHOLDER/workerpools/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER
triggers:
- type: gcp-pubsub
metadata:
subscriptionName: "SUBSCRIPTION_ID_PLACEHOLDER"
# Target number of undelivered messages per worker instance
value: "10"
mode: "SubscriptionSize"
authenticationRef:
name: adc-trigger-auth
- Sustituir variables
sed -i "s/PROJECT_ID_PLACEHOLDER/$PROJECT_ID/g" crema-config.yaml
sed -i "s/REGION_PLACEHOLDER/$REGION/g" crema-config.yaml
sed -i "s/CONSUMER_WORKER_POOL_NAME_PLACEHOLDER/$CONSUMER_WORKER_POOL_NAME/g" crema-config.yaml
sed -i "s/SUBSCRIPTION_ID_PLACEHOLDER/$SUBSCRIPTION_ID/g" crema-config.yaml
- Verifica que tu
crema-config.yamlsea correcto
if grep -q "_PLACEHOLDER" crema-config.yaml; then
echo "❌ ERROR: Validations failed. '_PLACEHOLDER' was found in crema-config.yaml."
echo "Please check your environment variables and run the 'sed' commands again."
else
echo "✅ Config check passed: No placeholders found."
fi
- Cómo subir datos a Parameter Manager
Configura variables de entorno adicionales para Parameter Manager
export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1
Crea el recurso Parameter
gcloud parametermanager parameters create $PARAMETER_ID \
--location=$PARAMETER_REGION \
--parameter-format=YAML
Crea la versión 1 del parámetro
gcloud parametermanager parameters versions create $PARAMETER_VERSION \
--parameter=crema-config \
--project=$PROJECT_ID \
--location=$PARAMETER_REGION \
--payload-data-from-file=crema-config.yaml
Verifica que el parámetro se haya agregado correctamente
gcloud parametermanager parameters versions list \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION
Deberías ver algo como
projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1
8. Implementa el servicio de CREMA
En esta sección, implementarás el servicio de escalador automático de CREMA. Usarás la imagen que está disponible de forma pública.
- Configura las variables de entorno necesarias para CREMA
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
- Verifica la ruta de acceso al nombre de la versión
echo $CREMA_CONFIG_PARAM_VERSION
Debería verse de la siguiente manera:
projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
- Establece la variable de entorno para la imagen de CREMA
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
- e implementa el servicio de CREMA
Ten en cuenta que la imagen base es obligatoria.
gcloud beta run deploy $CREMA_SERVICE_NAME \
--image=$IMAGE \
--region=${REGION} \
--service-account="${CREMA_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--no-allow-unauthenticated \
--no-cpu-throttling \
--labels=created-by=crema \
--base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
--set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True,ENABLE_CLOUD_LOGGING=True"
9. Pruebas de carga
- Crea una secuencia de comandos que publique mensajes en el tema de Pub/Sub
touch load-pubsub.sh
- Agrega el siguiente código al archivo
load-pubsub.sh.
#!/bin/bash
TOPIC_ID=${TOPIC_ID}
PROJECT_ID=${PROJECT_ID}
NUM_MESSAGES=100
echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."
for i in $(seq 1 $NUM_MESSAGES); do
gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
if (( $i % 10 == 0 )); then
wait
echo "Published $i messages..."
fi
done
wait
echo "Done. All messages published."
- Ejecutar prueba de carga
chmod +x load-pubsub.sh
./load-pubsub.sh
- Espera de 3 a 4 minutos para supervisar el ajuste de escala. Consulta los registros de CREMA para ver cómo recomienda instancias según la nueva configuración de authenticationRef.
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
--limit=20 \
--format="value(textPayload)" \
--freshness=5m
- Supervisa el procesamiento. Consulta los registros de Consumer para ver cómo se inicia.
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION
Deberías ver registros como los siguientes:
Done job-100
10. Solución de problemas
Primero, deberás determinar si el problema se debe a la configuración del servicio de CREMA o a la configuración del consumidor de Pub/Sub.
Establece el escalador automático del consumidor de Pub/Sub en 1, en lugar de 0. Si comienza a procesar mensajes de Pub/Sub de inmediato, el problema está en CREMA. Si no procesa los mensajes de Pub/Sub, hay un problema con el consumidor de Pub/Sub.
11. ¡Felicitaciones!
¡Felicitaciones por completar el codelab!
Te recomendamos que revises la documentación de Cloud Run.
Temas abordados
- Cómo crear un tema y una suscripción de Pub/Sub, y enviar mensajes a ese tema
- Cómo implementar un grupo de trabajadores (consumidor) de Cloud Run que consuma mensajes de Pub/Sub
- Cómo implementar el proyecto de CREMA en GitHub como un servicio de Cloud Run para ajustar automáticamente la escala de tu grupo de trabajadores según la cantidad de mensajes en la suscripción de Pub/Sub
- Cómo probar tu configuración del ajuste de escala automático generando carga con la ejecución local de una secuencia de comandos de Python
12. Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este codelab, puedes borrar los recursos que creaste o borrar todo el proyecto.
Borra los recursos que se usaron en este codelab
- Borra el servicio de CREMA de Cloud Run
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
- Borra el consumidor del grupo de trabajadores de Cloud Run
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
- Borra la suscripción y el tema de Pub/Sub
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
- Borra la configuración de Parameter Manager
Borra la versión dentro del parámetro
gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
Ahora, borra el parámetro vacío.
gcloud parametermanager parameters delete $PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
- Borra las cuentas de servicio
gcloud iam service-accounts delete "$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
gcloud iam service-accounts delete "$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" --quiet
Borrar todo el proyecto
Para borrar todo el proyecto, ve a Administrar recursos, selecciona el proyecto que creaste en el paso 2 y elige Borrar. Si borras el proyecto, deberás cambiar de proyecto en el SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list.