1. Introdução
Visão geral
Neste tutorial, mostramos como implantar um pool de workers do Cloud Run (consumidor) para processar mensagens do Pub/Sub e escalonar automaticamente as instâncias do consumidor com base na profundidade da fila usando o escalonamento automático de métricas externas do Cloud Run (CREMA).
O que você vai aprender
Neste codelab, você vai:
- Crie um tópico e uma assinatura do Pub/Sub e envie mensagens para ele.
- Implante um pool de workers do Cloud Run (consumidor) que consome mensagens do Pub/Sub.
- Implante o projeto CREMA no GitHub como um serviço do Cloud Run para escalonar automaticamente seu pool de workers com base no número de mensagens na assinatura do Pub/Sub.
- Teste a configuração de escalonamento automático gerando carga ao executar um script Python localmente.
2. Configurar variáveis de ambiente
Como muitas variáveis de ambiente são usadas ao longo deste codelab, recomendamos executar
set -u
que vai avisar se você tentar usar uma variável de ambiente que ainda não foi definida. Para desfazer essa configuração, execute set +u
Primeiro, mude a variável a seguir para o ID do projeto.
export PROJECT_ID=<YOUR_PROJECT_ID>
e defina como o projeto deste codelab.
gcloud config set project $PROJECT_ID
Em seguida, defina as variáveis de ambiente usadas neste 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
Crie um diretório para este codelab
mkdir crema-pubsub-codelab
cd crema-pubsub-codelab
Ativar APIs
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
run.googleapis.com \
parametermanager.googleapis.com
Por fim, verifique se a gcloud está usando a versão mais recente.
gcloud components update
3. Configuração do Pub/Sub
Crie o tópico e a assinatura de pull que seu pool de workers vai processar. Bash
Crie o tópico.
gcloud pubsub topics create $TOPIC_ID
Crie a assinatura.
gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID
4. IAM e contas de serviço
Recomendamos criar uma conta de serviço para cada recurso do Cloud Run. Neste codelab, você vai criar o seguinte:
- SA do consumidor: identidade do pool de workers que processa mensagens do Pub/Sub.
- CREMA SA: identidade do serviço de escalonamento automático da CREMA.
Criar contas de serviço
Crie a SA do consumidor do pool de workers:
gcloud iam service-accounts create $CONSUMER_SA_NAME \
--display-name="PubSub Consumer Service Account"
Crie a conta de serviço do CREMA para o pool de workers:
gcloud iam service-accounts create $CREMA_SA_NAME \
--display-name="CREMA Autoscaler Service Account"
Conceder permissões à Consumer SA
Conceda permissões à SA do consumidor do pool de workers para extrair mensagens da assinatura.
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.subscriber"
Conceder permissões à CREMA SA
O CREMA precisa de permissões para ler parâmetros, escalonar o pool de workers e monitorar métricas do Pub/Sub.
- Acessar o Gerenciador de parâmetros (leitor de configuração):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/parametermanager.parameterViewer"
- Escalonar o pool de workers (desenvolvedor do Cloud Run):
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.developer"
- Monitorar o Pub/Sub:
Conceda o papel de leitor do Monitoring.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/monitoring.viewer"
Adicione uma política à assinatura da SA do serviço CREMA para visualizá-la.
gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
--member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.viewer"
A SA do CREMA também precisa de um usuário da conta de serviço, que é necessário para mudar as contagens de instâncias:
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. Verificar permissões de SA
Antes de continuar o codelab, verifique se a SA do serviço CREMA tem as funções corretas no nível do projeto.
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"
Isso vai resultar no seguinte:
roles/monitoring.viewer
roles/parametermanager.parameterViewer
roles/run.developer
Verifique se a assinatura do Pub/Sub tem uma política que permite que a SA do serviço CREMA a consulte.
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)"
Resulta em
roles/pubsub.viewer
e verifique se a SA do CREMA tem o papel de usuário da conta de serviço.
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"
Isso vai resultar no seguinte:
bindings:
members: serviceAccount:crema-service-account@<PROJECT_ID>.iam.gserviceaccount.com
role: roles/iam.serviceAccountUser
e a SA do consumidor do pool de workers tem o papel de assinante do 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)"
Resulta em
ROLE
roles/pubsub.subscriber
6. Criar e implantar o pool de workers do consumidor
Crie um diretório para seu código de consumidor e acesse-o.
mkdir consumer
cd consumer
- Crie um arquivo
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}")
- Criar um
Dockerfile
FROM python:3.12-slim
RUN pip install google-cloud-pubsub
COPY consumer.py .
CMD ["python", "-u", "consumer.py"]
- Implantar pool de workers do consumidor
Este codelab recomenda implantar o pool de workers com zero instâncias para começar. Assim, você pode observar o CREMA escalonar o pool de workers quando ele detectar as mensagens do Pub/Sub na assinatura.
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. Configurar o CREMA
- Volte para o diretório raiz do projeto.
cd ..
- Crie o arquivo de configuração
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
- Substituir variáveis
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
- Verifique se o
crema-config.yamlestá correto
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
- Fazer upload para o Gerenciador de parâmetros
Definir outras variáveis de ambiente para o Gerenciador de parâmetros
export PARAMETER_ID=crema-config
export PARAMETER_REGION=global
export PARAMETER_VERSION=1
Criar o recurso Parameter
gcloud parametermanager parameters create $PARAMETER_ID \
--location=$PARAMETER_REGION \
--parameter-format=YAML
Criar parâmetro versão 1
gcloud parametermanager parameters versions create $PARAMETER_VERSION \
--parameter=crema-config \
--project=$PROJECT_ID \
--location=$PARAMETER_REGION \
--payload-data-from-file=crema-config.yaml
Verifique se o parâmetro foi adicionado
gcloud parametermanager parameters versions list \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION
Você vai ver algo como
projects/<YOUR_PROJECT_ID>/locations/global/parameters/crema-config/versions/1
8. Implantar o serviço CREMA
Nesta seção, você vai implantar o serviço de escalonador automático do CREMA. Você vai usar a imagem disponível publicamente.
- Definir as variáveis de ambiente necessárias para o CREMA
CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
- Verificar o caminho do nome da versão
echo $CREMA_CONFIG_PARAM_VERSION
Ele vai ficar assim:
projects/<YOUR_PROJECT>/locations/global/parameters/crema-config/versions/1
- Defina a variável de ambiente para a imagem do CREMA
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0
- e implante o serviço CREMA
A imagem de base é obrigatória.
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. Teste de carga
- Criar um script que publique mensagens no tópico do Pub/Sub
touch load-pubsub.sh
- Adicione o seguinte código ao arquivo
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."
- Executar teste de carga
chmod +x load-pubsub.sh
./load-pubsub.sh
- Monitore a espera de escalonamento por 3 a 4 minutos. Confira os registros do CREMA para ver as recomendações de instâncias com base na nova configuração "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
- Monitore o processamento e veja os registros do consumidor para conferir se ele está sendo iniciado.
gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION
Você vai ver registros como
Done job-100
10. Solução de problemas
Primeiro, determine se o problema está na configuração do serviço CREMA ou na configuração do consumidor do Pub/Sub.
Defina o escalonador automático do consumidor do Pub/Sub como 1, em vez de 0. Se ele começar imediatamente a processar mensagens pubsub, o problema é com o CREMA. Se ele não processar as mensagens do pubsub, há um problema com o consumidor do pubsub.
11. Parabéns!
Parabéns por concluir o codelab!
Recomendamos que você consulte a documentação do Cloud Run.
O que aprendemos
- Como criar um tópico e uma assinatura do Pub/Sub e enviar mensagens para esse tópico.
- Como implantar um pool de workers do Cloud Run (consumidor) que consome mensagens do Pub/Sub.
- Como implantar o projeto CREMA no GitHub como um serviço do Cloud Run para escalonar automaticamente o pool de workers com base no número de mensagens na assinatura do Pub/Sub.
- Como testar sua configuração de escalonamento automático gerando carga executando um script Python localmente.
12. Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua os recursos criados neste codelab ou o projeto inteiro.
Excluir recursos usados neste codelab
- Excluir o serviço CREMA do Cloud Run
gcloud run services delete $CREMA_SERVICE_NAME --region=$REGION --quiet
- Excluir o consumidor do pool de workers do Cloud Run
gcloud beta run worker-pools delete $CONSUMER_WORKER_POOL_NAME --region=$REGION --quiet
- Excluir a assinatura e o tópico do Pub/Sub
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet
gcloud pubsub topics delete $TOPIC_ID --quiet
- Excluir a configuração do Parameter Manager
Excluir a versão dentro do parâmetro
gcloud parametermanager parameters versions delete $PARAMETER_VERSION \
--parameter=$PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
Agora, exclua o parâmetro vazio.
gcloud parametermanager parameters delete $PARAMETER_ID \
--location=$PARAMETER_REGION \
--quiet
- Excluir as contas de serviço
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
Ou excluir todo o projeto
Para excluir todo o projeto, acesse Gerenciar recursos, selecione o projeto criado na etapa 2 e escolha "Excluir". Se você excluir o projeto, será necessário mudar de projeto no SDK do Cloud. Para conferir a lista de todos os projetos disponíveis, execute gcloud projects list.