Crie uma orquestração baseada em eventos com o Eventarc e o Workflows

1. Introdução

cb762f29e9183a3f.png 1c05e3d0c2bd2b45.png a03f943ca09ac4c.png

O Eventarc facilita a conexão dos serviços do Cloud Run com eventos de várias fontes. Ele permite criar arquiteturas orientadas a eventos em que os microsserviços são acoplados com flexibilidade e distribuídos. Ele cuida da ingestão, da entrega, da segurança, da autorização e do tratamento de erros de eventos para você.

O Workflows é uma plataforma de orquestração totalmente gerenciada que executa serviços na ordem que você definir: um fluxo de trabalho. Esses fluxos de trabalho podem combinar serviços hospedados no Cloud Run ou no Cloud Functions, serviços do Google Cloud, como Cloud Vision AI e BigQuery, e qualquer API baseada em HTTP.

Neste codelab, você criará uma orquestração de microsserviços orientada a eventos para processar imagens. Você vai usar o Workflows para orquestrar a ordem, as entradas e as saídas de quatro funções de processamento de imagens do Cloud Functions. Em seguida, você vai permitir que a orquestração responda a eventos do Cloud Storage de maneira acoplada com flexibilidade ao Eventarc.

No final, você terá uma arquitetura sem servidor flexível, mas estruturada, para processar imagens.

e372ceed8c26c5fb.png

O que você vai aprender

  • Uma visão geral do Eventarc e dos fluxos de trabalho
  • Como implantar serviços do Cloud Functions
  • Como orquestrar serviços usando o Workflows
  • Como fazer o Workflows responder a eventos do Cloud Storage com o Eventarc

2. Configuração e requisitos

Configuração de ambiente personalizada

  1. Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google Você pode atualizar a qualquer momento.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. normalmente você não se importa com o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, que normalmente é identificado como PROJECT_ID. Se você não gostar do ID gerado, poderá gerar outro ID aleatório. Como alternativa, você pode tentar o seu próprio e ver se ele está disponível. Ela não pode ser alterada após essa etapa e permanecerá durante a duração do projeto.
  • Para sua informação, há um terceiro valor, um Número de projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para encerrar os recursos e não gerar faturamento além deste tutorial, exclua os recursos criados ou exclua o projeto inteiro. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Iniciar o Cloud Shell

Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.

No Console do Google Cloud, clique no ícone do Cloud Shell na barra de ferramentas superior à direita:

55efc1aaa7a4d3ad.png

O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

7ffe5cbb04455448.png

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, todo o trabalho pode ser feito com um navegador. Você não precisa instalar nada.

Configurar a gcloud

No Cloud Shell, defina o ID do projeto e a região em que você quer implantar o aplicativo. Salve-as como variáveis PROJECT_ID e REGION. Confira as regiões disponíveis em Locais do Cloud Functions.

PROJECT_ID=your-project-id
gcloud config set project $PROJECT_ID

Conseguir o código-fonte

O código-fonte do aplicativo está na pasta processing-pipelines do repositório eventarc-samples.

Clone o repositório:

git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git

Navegue até a pasta eventarc-samples/processing-pipelines:

cd eventarc-samples/processing-pipelines

3. Visão geral da arquitetura

A arquitetura do aplicativo é a seguinte:

6aa6fbc7721dd6b6.png

  1. Uma imagem é salva em um bucket de entrada que gera um evento de criação do Cloud Storage.
  2. O evento de criação do Cloud Storage é lido pelo Eventarc por meio de um gatilho do Cloud Storage e transmitido para Workflows como um CloudEvent.
  3. Na primeira etapa do fluxo de trabalho, o Filtro, um serviço do Cloud Functions, usa a API Vision para determinar se a imagem está segura. Se a imagem estiver segura, o Workflows continuará com as próximas etapas.
  4. Na segunda etapa do fluxo de trabalho, o Labeler, um serviço do Cloud Functions, extrai os rótulos da imagem com a API Vision e os salva no bucket de saída.
  5. Na terceira etapa, Resizer, outro serviço do Cloud Functions, a imagem é redimensionada com o ImageSharp, que é salva no bucket de saída.
  6. Na última etapa, o Watermarker, outro serviço do Cloud Functions, adiciona uma marca-d'água dos rótulos do rotulador à imagem redimensionada usando o ImageSharp e salva a imagem no bucket de saída.

O aplicativo é acionado por um evento do Cloud Storage, portanto, é orientado por eventos. O processamento de imagens acontece em um fluxo de trabalho. Por isso, é uma orquestração. No fim das contas, é uma orquestração orientada a eventos de uma arquitetura sem servidor flexível e estruturada para processar imagens.

4. Criar buckets

Crie um bucket de entrada para os usuários fazerem upload das imagens e um bucket de saída para o pipeline de processamento de imagens salvar as imagens processadas.

Execute o seguinte no Cloud Shell:

REGION=us-central1
BUCKET1=$PROJECT_ID-images-input
BUCKET2=$PROJECT_ID-images-output

gsutil mb -l $REGION gs://$BUCKET1
gsutil mb -l $REGION gs://$BUCKET2

5. Implantar serviço de filtro

Vamos começar implantando o primeiro serviço. Esse serviço do Cloud Functions recebe as informações do bucket e do arquivo, determina se a imagem é segura com a API Vision e retorna o resultado.

Primeiro, ative os serviços necessários para o Cloud Functions gen2 e a API Vision:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  run.googleapis.com \
  vision.googleapis.com

Na pasta de nível superior processing-pipelines, implante o serviço:

SERVICE_NAME=filter

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --entry-point Filter.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp

Depois que a função for implantada, defina o URL do serviço em uma variável, que será necessária mais tarde:

FILTER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

6. Implantar o serviço de rotulador

O segundo serviço do Cloud Functions recebe as informações do bucket e do arquivo, extrai os rótulos da imagem com a API Vision e os salva no bucket de saída.

Na pasta de nível superior processing-pipelines, implante o serviço:

SERVICE_NAME=labeler

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Labeler.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp

Depois que a função for implantada, defina o URL do serviço em uma variável, que será necessária mais tarde:

LABELER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

7. Implantar o serviço de redimensionamento

Esse serviço do Cloud Functions recebe as informações do bucket e do arquivo, redimensiona a imagem usando o comando ImageSharp e salva a imagem no bucket de saída.

Na pasta de nível superior processing-pipelines, implante o serviço:

SERVICE_NAME=resizer

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Resizer.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp \
  --timeout=120s

Observe o valor timeout de 2 minutos para permitir que a função do redimensionador tenha tempo extra para o processamento.

Depois que a função for implantada, defina o URL do serviço em uma variável, que será necessária mais tarde:

RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

8. Implantar serviço de marca-d'água

Esse serviço do Cloud Functions recebe as informações do bucket, do arquivo e dos rótulos, lê o arquivo, adiciona os rótulos como marca-d'água à imagem usando o ImageSharp e salva a imagem no bucket de saída.

Na pasta de nível superior processing-pipelines, implante o serviço:

SERVICE_NAME=watermarker

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Watermarker.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp

Depois que a função for implantada, defina o URL do serviço em uma variável, que será necessária mais tarde:

WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

Neste ponto, as quatro funções do Cloud devem estar implantadas e em execução:

76a218568982c90c.png

9. Definir e implantar o fluxo de trabalho

Use o Workflows para reunir serviços de filtro, rotulador, redimensionador e marca d'água em um fluxo de trabalho. O Workflows vai orquestrar a chamada desses serviços na ordem e com os parâmetros que definirmos.

Primeiro, ative os serviços necessários para o Workflows:

gcloud services enable \
  workflows.googleapis.com \
  workflowexecutions.googleapis.com

Defina

O Workflows recebe um CloudEvent como parâmetro. Ele virá do Eventarc quando criarmos um gatilho. Nas primeiras duas etapas, o Workflows registra o evento e extrai as informações do bucket e do arquivo do evento:

main:
  params: [event]
  steps:
  - log_event:
      call: sys.log
      args:
          text: ${event}
          severity: INFO
  - extract_bucket_and_file:
      assign:
      - bucket: ${event.data.bucket}
      - file: ${event.data.name}

Na etapa filter, o Workflows faz uma chamada para o serviço de filtro que implantamos anteriormente. Em seguida, ele registra e verifica a segurança dos arquivos:

  - filter:
      call: http.post
      args:
        url: FILTER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: filterResponse
  - log_safety:
      call: sys.log
      args:
          text: ${filterResponse.body.safe}
          severity: INFO
  - check_safety:
      switch:
        - condition: ${filterResponse.body.safe == true}
          next: label
      next: end

Na etapa label, o Workflows faz uma chamada para o serviço de rotulador e captura a resposta (três principais rótulos):

  - label:
      call: http.post
      args:
        url: LABELER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: labelResponse

Na etapa resize, o Workflows faz uma chamada para o serviço de redimensionamento e captura a resposta (o bucket e o arquivo da imagem redimensionada):

  - resize:
      call: http.post
      args:
        url: RESIZER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: resizeResponse

Na etapa watermark, o Workflows chama o serviço de marca-d'água com a imagem redimensionada e os rótulos e captura o resultado (a imagem redimensionada e com marca d'água):

  - watermark:
      call: http.post
      args:
        url: WATERMARKER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${resizeResponse.body.bucket}
            file: ${resizeResponse.body.file}
            labels: ${labelResponse.body.labels}
      result: watermarkResponse

Na etapa final, o Workflows retorna o código de status HTTP dos serviços de rotulador, redimensionador e marca-d'água:

  - final:
      return:
        label: ${labelResponse.code}
        resize: ${resizeResponse.code}
        watermark: ${watermarkResponse.code}

Implantar

Antes de implantar o fluxo de trabalho, verifique se os URLs de serviço foram substituídos pelos URLs das funções implantadas manualmente ou usando sed:

Na pasta de nível superior processing-pipelines, navegue até a pasta image-v3 em que o arquivo workflows.yaml está localizado:

cd image-v3/

Execute sed para substituir os URLs de marcadores pelos URLs reais dos serviços implantados:

sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml
sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml
sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml
sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml

Implante o fluxo de trabalho:

WORKFLOW_NAME=image-processing

gcloud workflows deploy $WORKFLOW_NAME \
    --source=workflow.yaml \
    --location=$REGION

Em alguns segundos, o fluxo de trabalho será implantado no console:

92cf4e758bdc3dde.png

10. Criar gatilho

Agora que o fluxo de trabalho foi implantado, a última etapa é conectá-lo a eventos do Cloud Storage com um gatilho do Eventarc.

Configuração única

Primeiro, ative os serviços necessários para o Eventarc:

gcloud services enable \
 eventarc.googleapis.com

Crie uma conta de serviço para usar no gatilho do Eventarc.

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Eventarc trigger image processing service account"

Conceda o papel workflows.invoker para que a conta de serviço possa ser usada para invocar fluxos de trabalho do Eventarc:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/workflows.invoker \
  --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

Conceda o papel eventarc.eventReceiver. A conta de serviço pode ser usada em um

Gatilho do Cloud Storage:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/eventarc.eventReceiver \
  --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

Conceda o papel pubsub.publisher à conta de serviço do Cloud Storage. Isso é necessário para o gatilho do Cloud Storage do Eventarc:

STORAGE_SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_ID)"

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:$STORAGE_SERVICE_ACCOUNT \
    --role roles/pubsub.publisher

Criar

Execute o comando a seguir para criar um gatilho. Esse gatilho filtra os novos eventos de criação de arquivos do bucket de entrada do Cloud Storage e os transmite para o fluxo de trabalho definido anteriormente:

TRIGGER_NAME=trigger-image-processing

gcloud eventarc triggers create $TRIGGER_NAME \
  --location=$REGION \
  --destination-workflow=$WORKFLOW_NAME \
  --destination-workflow-location=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.finalized" \
  --event-filters="bucket=$BUCKET1" \
  --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

O gatilho foi criado e está pronto na seção Eventarc do console do Cloud:

14330c4fa2451bc0.png

11. Teste o pipeline

O pipeline de processamento de imagens está pronto para receber eventos do Cloud Storage. Para testar o pipeline, faça upload de uma imagem para o bucket de entrada:

gsutil cp beach.jpg gs://$BUCKET1

Assim que você fizer upload da imagem, vai aparecer uma execução do Workflows no estado ativo:

36d07cb63c39e7d9.png

Após cerca de um minuto, a execução será concluída. Também é possível ver a entrada e a saída do fluxo de trabalho:

229200c79d989c25.png

Se você listar o conteúdo do bucket de saída, verá a imagem redimensionada, a imagem redimensionada e com marca d'água e os rótulos da imagem:

gsutil ls gs://$BUCKET2

gs://$PROJECT_ID-images-output/beach-400x400-watermark.jpeg
gs://$PROJECT_ID-images-output/beach-400x400.png
gs://$PROJECT_ID-images-output/beach-labels.txt

Abra a imagem redimensionada e com marca d'água para conferir o resultado:

75f3c0019ca842ce.jpeg

12. Parabéns

Parabéns, você concluiu o codelab.

O que aprendemos

  • Uma visão geral do Eventarc e dos fluxos de trabalho
  • Como implantar serviços do Cloud Functions
  • Como orquestrar serviços usando o Workflows
  • Como fazer o Workflows responder a eventos do Cloud Storage com o Eventarc