Sobre este codelab
1. Introdução
Visão geral
O Cloud Run Functions é a oferta de funções como serviço do Google Cloud com tecnologia do Cloud Run e do Eventarc, que oferece controle avançado sobre o desempenho e a escalonabilidade, além de mais controle sobre o ambiente de execução das funções e gatilhos de mais de 90 origens de eventos.
Neste codelab, você vai aprender a criar funções do Cloud Run que respondem a chamadas HTTP e são acionadas por mensagens do Pub/Sub e registros de auditoria do Cloud.
Este codelab também usa atualizações automáticas de imagem de base para implantações de função especificando uma imagem de base usando a flag --base-image
. As atualizações automáticas da imagem de base para o Cloud Run permitem que o Google faça patches de segurança para os componentes do sistema operacional e do ambiente de execução de linguagem da imagem de base automaticamente. Não é necessário recriar ou reimplantar o serviço para que a imagem de base seja atualizada. Para mais informações, consulte as atualizações automáticas de imagem de base.
Se você não quiser usar as atualizações automáticas de imagem de base, remova a flag --base-image
dos exemplos mostrados neste codelab.
O que você vai aprender
- Informações gerais sobre o Cloud Run functions e como usar as atualizações automáticas de imagem de base.
- Como escrever uma função que responde a chamadas HTTP.
- Como escrever uma função que responde a mensagens do Pub/Sub.
- Como escrever uma função que responde a eventos do Cloud Storage.
- Como dividir o tráfego entre duas revisões.
- Como se livrar das inicializações a frio com instâncias mínimas.
2. Configuração e requisitos
Criar uma pasta raiz
Crie uma pasta raiz para todos os exemplos.
mkdir crf-codelab cd crf-codelab
Configure as variáveis de ambiente
Defina as variáveis de ambiente que serão usadas neste codelab.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
Ativar APIs
Ative todos os serviços necessários:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Função HTTP
Para a primeira função, vamos criar uma função autenticada do Node.js que responda a solicitações HTTP. Vamos usar um tempo limite de 10 minutos para mostrar como uma função pode ter mais tempo para responder a solicitações HTTP.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir hello-http cd hello-http
Crie um arquivo index.js
que responda a solicitações 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!'); });
Crie um arquivo package.json
para especificar as dependências:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implantar
Implante a função:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
Esse comando usa buildpacks para transformar o código-fonte da função em uma imagem de contêiner pronta para produção.
Observações:
- A flag
--source
é usada para informar ao Cloud Run que a função precisa ser criada em um serviço baseado em contêiner executável. - A flag
--function
(new) é usada para definir o ponto de entrada do novo serviço como a assinatura de função que você quer invocar. - a flag
--base-image
(nova) especifica o ambiente de imagem de base da função, comonodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
ouphp83
. Para mais detalhes sobre as imagens de base e os pacotes incluídos em cada imagem, consulte Imagens de base dos ambientes de execução. - (opcional) a flag
--timeout
permite que a função tenha um tempo limite mais longo para responder a solicitações HTTP. Neste exemplo, 600 segundos são usados para demonstrar um tempo de resposta de 10 minutos. - (opcional)
--no-allow-unauthenticated
para impedir que a função seja invocável publicamente
Teste
Teste a função com os seguintes 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
A mensagem HTTP with Node.js in Cloud Run functions!
vai aparecer como resposta.
4. Função do Pub/Sub
Para a segunda função, vamos criar uma função Python acionada por uma mensagem do Pub/Sub publicada em um tópico específico.
Configurar tokens de autenticação do Pub/Sub
Se você ativou a conta de serviço do Pub/Sub até 8 de abril de 2021, conceda o papel iam.serviceAccountTokenCreator
à conta de serviço do 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
Criação
Crie um tópico do Pub/Sub para usar no exemplo:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Crie uma pasta para o app e navegue até ela:
mkdir ../hello-pubsub cd ../hello-pubsub
Crie um arquivo main.py
que registre uma mensagem com o ID do 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'])
Crie um arquivo requirements.txt
com o seguinte conteúdo para especificar as dependências:
functions-framework==3.*
Implantar
Implante a função:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Extraia o número do projeto que será usado para a identidade da conta de serviço.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Criar o acionador
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
Teste
Para testar a função, envie uma mensagem para o tópico:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Você verá o CloudEvent recebido nos registros:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Função do Cloud Storage
Na próxima função, vamos criar uma função Node.js que responda a eventos de um bucket do Cloud Storage.
Configurar
Para usar as funções do Cloud Storage, conceda a função pubsub.publisher
do IAM à conta de serviço do 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
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ../hello-storage cd ../hello-storage
Crie um arquivo index.js
que simplesmente responda a eventos do 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); });
Crie um arquivo package.json
para especificar as dependências:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implantar
Primeiro, crie um bucket do Cloud Storage (ou use um bucket que você já tenha):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Implante a função:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Depois que a função é implantada, ela aparece na seção "Cloud Run" do Console do Cloud.
Agora crie o gatilho do 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
Teste
Teste a função fazendo upload de um arquivo para o bucket:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Você verá o CloudEvent recebido nos registros:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Divisão de tráfego
O Cloud Run functions é compatível com várias revisões de funções, dividindo o tráfego entre diferentes revisões e revertendo a função para uma versão anterior.
Nesta etapa, você vai implantar duas revisões de uma função e dividir o tráfego entre elas em 50-50.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ../traffic-splitting cd ../traffic-splitting
Crie um arquivo main.py
com uma função Python que leia uma variável de ambiente de cor e responda com Hello World
nessa cor de plano de fundo:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Crie um arquivo requirements.txt
com o seguinte conteúdo para especificar as dependências:
functions-framework==3.*
Implantar
Implante a primeira revisão da função com um plano de fundo laranja:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Nesse ponto, se você testar a função visualizando o gatilho HTTP (a saída de URI do comando de implantação acima) no navegador, vai aparecer Hello World
com um plano de fundo laranja:
Implante a segunda revisão com um plano de fundo amarelo:
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 é a revisão mais recente, se você testar a função, verá Hello World
com um plano de fundo amarelo:
Dividir o tráfego em 50-50
Para dividir o tráfego entre as revisões laranja e amarela, você precisa encontrar os IDs de revisão dos serviços do Cloud Run. Este é o comando para conferir os IDs de revisão:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
A saída será semelhante a esta:
hello-world-colors-00001-man hello-world-colors-00002-wok
Agora, divida o tráfego entre essas duas revisões da seguinte maneira (atualize o X-XXX
de acordo com os nomes das revisões):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Teste
Acesse o URL público para testar a função. Na metade do tempo, você vai ver a revisão laranja e, na outra metade, a revisão amarela:
Consulte reversões, lançamentos graduais e migração de tráfego para mais informações.
7. Instâncias mínimas
No Cloud Run, é possível especificar um número mínimo de instâncias de função que serão mantidas quentes e prontas para atender solicitações. Isso é útil para limitar o número de inicializações a frio.
Nesta etapa, você vai implantar uma função com inicialização lenta. Você vai observar o problema de inicialização a frio. Em seguida, implante a função com o valor mínimo da instância definido como 1 para se livrar da inicialização a frio.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ../min-instances cd ../min-instances
Crie um arquivo main.go
. Esse serviço Go tem uma função init
que fica inativa por 10 segundos para simular uma inicialização longa. Ela também tem uma função HelloWorld
que responde a chamadas 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!") }
Implantar
Implante a primeira revisão da função com o valor mínimo da instância padrão de zero:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Teste a função com 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
Você vai notar um atraso de 10 segundos (início frio) na primeira chamada e depois vai receber a mensagem. As chamadas seguintes devem ser retornadas imediatamente.
Definir instâncias mínimas
Para se livrar da inicialização a frio na primeira solicitação, reimplante a função com a flag --min-instances
definida como 1, conforme mostrado abaixo:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Teste
Teste a função novamente:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
O atraso de 10 segundos não vai mais aparecer na primeira solicitação. O problema de inicialização a frio da primeira invocação (depois de muito tempo sem uso) foi resolvido, graças às instâncias mínimas.
Consulte Como usar instâncias mínimas para mais informações.
8. Parabéns!
Parabéns por concluir o codelab.
O que vimos
- Informações gerais sobre o Cloud Run functions e como usar as atualizações automáticas de imagem de base.
- Como escrever uma função que responde a chamadas HTTP.
- Como escrever uma função que responde a mensagens do Pub/Sub.
- Como escrever uma função que responde a eventos do Cloud Storage.
- Como dividir o tráfego entre duas revisões.
- Como se livrar das inicializações a frio com instâncias mínimas.