Crea un'orchestrazione basata su eventi con Eventarc e Workflows

1. Introduzione

cb762f29e9183a3f.png 1c05e3d0c2bd2b45.png a03f943ca09ac4c.png

Eventarc semplifica la connessione dei servizi Cloud Run a eventi provenienti da una varietà di origini. Consente di creare architetture basate su eventi in cui i microservizi sono a basso accoppiamento e distribuiti. Si occupa dell'importazione, della distribuzione, della sicurezza, dell'autorizzazione e della gestione degli errori degli eventi.

Flussi di lavoro è una piattaforma di orchestrazione completamente gestita che esegue i servizi in un ordine definito da te: un flusso di lavoro. Questi flussi di lavoro possono combinare servizi ospitati su Cloud Run o Cloud Functions, servizi Google Cloud come Cloud Vision AI e BigQuery e qualsiasi API basata su HTTP.

In questo codelab, creerai un'orchestrazione di microservizi basata su eventi per elaborare le immagini. Utilizzerai Workflows per orchestrare l'ordine, gli input e gli output di 4 funzioni Cloud Functions di elaborazione di immagini. Successivamente, abiliterai l'orchestrazione in modo che risponda agli eventi di Cloud Storage in modo a basso accoppiamento con Eventarc.

Alla fine, il risultato sarà un'architettura serverless flessibile ma strutturata per elaborare le immagini.

e372ceed8c26c5fb.png

Obiettivi didattici

  • Panoramica di Eventarc e Workflows
  • Come eseguire il deployment dei servizi Cloud Functions
  • Come orchestrare i servizi utilizzando Workflows
  • Come fare in modo che Workflows risponda agli eventi di Cloud Storage con Eventarc

2. Configurazione e requisiti

Configurazione dell'ambiente autogestito

  1. Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Il Nome progetto è il nome visualizzato dei partecipanti del progetto. Si tratta di una stringa di caratteri non utilizzata dalle API di Google. Puoi aggiornarla in qualsiasi momento.
  • L'ID progetto è univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca. di solito non ti importa cosa sia. Nella maggior parte dei codelab, dovrai fare riferimento all'ID progetto (in genere è identificato come PROJECT_ID). Se l'ID generato non ti soddisfa, puoi generarne un altro casuale. In alternativa, puoi provarne una personalizzata per verificare se è disponibile. Non può essere modificato dopo questo passaggio e rimarrà per tutta la durata del progetto.
  • Per informazione, c'è un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, dovrai abilitare la fatturazione nella console Cloud per utilizzare risorse/API Cloud. Eseguire questo codelab non dovrebbe costare molto. Per arrestare le risorse in modo da non incorrere in fatturazione oltre questo tutorial, puoi eliminare le risorse che hai creato o eliminare l'intero progetto. I nuovi utenti di Google Cloud sono idonei al programma prova senza costi di 300$.

Avvia Cloud Shell

Anche se Google Cloud può essere utilizzato da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.

Dalla console Google Cloud, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:

55efc1aaa7a4d3ad.png

Dovrebbe richiedere solo qualche istante per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere una schermata simile al seguente:

7ffe5cbb04455448.png

Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Tutto il lavoro in questo codelab può essere svolto all'interno di un browser. Non occorre installare nulla.

Configura gcloud

In Cloud Shell, imposta l'ID progetto e la regione in cui vuoi eseguire il deployment dell'applicazione. Salvale come variabili PROJECT_ID e REGION. Consulta le località di Cloud Functions per conoscere le regioni disponibili.

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

Recupera il codice sorgente

Il codice sorgente dell'applicazione si trova nella cartella processing-pipelines del repository eventarc-samples.

Clona il repository:

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

Vai alla cartella eventarc-samples/processing-pipelines:

cd eventarc-samples/processing-pipelines

3. Panoramica dell'architettura

L'architettura dell'applicazione è la seguente:

6aa6fbc7721dd6b6.png

  1. Un'immagine viene salvata in un bucket di input che genera un evento di creazione di Cloud Storage.
  2. L'evento di creazione di Cloud Storage viene letto da Eventarc tramite un trigger di Cloud Storage e passato a Workflows come CloudEvent.
  3. Nel primo passaggio del flusso di lavoro, Filtra, un servizio di funzioni Cloud Functions, utilizza l'API Vision per determinare se l'immagine è sicura. Se l'immagine è sicura, Workflows continua con i passaggi successivi.
  4. Nel secondo passaggio del flusso di lavoro, Labeler, un servizio di funzione Cloud Functions, estrae le etichette dell'immagine con l'API Vision e le salva nel bucket di output.
  5. Nel terzo passaggio, Ridimensionar, un altro servizio della funzione Cloud Functions, ridimensiona l'immagine utilizzando ImageSharp e salva l'immagine ridimensionata nel bucket di output.
  6. Nell'ultimo passaggio, Watermarker, un altro servizio di funzione Cloud Functions, aggiunge una filigrana di etichette da Labeler all'immagine ridimensionata utilizzando ImageSharp e salva l'immagine nel bucket di output.

L'applicazione viene attivata da un evento Cloud Storage, per cui è basata su eventi. L'elaborazione delle immagini avviene in un flusso di lavoro, da qui si tratta di un'orchestrazione. Alla fine, si tratta di un'orchestrazione basata su eventi per un'architettura serverless flessibile ma strutturata per elaborare le immagini.

4. Creazione di bucket

Creare un bucket di input in cui gli utenti possono caricare le immagini e un bucket di output per la pipeline di elaborazione delle immagini al fine di salvare le immagini elaborate.

Esegui il comando riportato di seguito in 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. Esegui il deployment del servizio filtro

Iniziamo con il deployment del primo servizio. Questo servizio Cloud Functions riceve le informazioni sul bucket e sul file, determina se l'immagine è sicura con l'API Vision e restituisce il risultato.

Innanzitutto, abilita i servizi richiesti per Cloud Functions gen2 e l'API Vision:

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

Nella cartella di primo livello processing-pipelines, esegui il deployment del servizio:

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

Dopo il deployment della funzione, imposta l'URL del servizio in una variabile, che ci servirà in un secondo momento:

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

6. Esegui il deployment del servizio di etichettatura

Il secondo servizio Cloud Functions riceve le informazioni sul bucket e sul file, estrae le etichette dell'immagine con l'API Vision e le salva nel bucket di output.

Nella cartella di primo livello processing-pipelines, esegui il deployment del servizio:

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

Dopo il deployment della funzione, imposta l'URL del servizio in una variabile, che ci servirà in un secondo momento:

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

7. Esegui il deployment del servizio di ridimensionamento

Questo servizio Cloud Functions riceve le informazioni sul bucket e sul file, ridimensiona l'immagine utilizzando ImageSharp e la salva nel bucket di output.

Nella cartella di primo livello processing-pipelines, esegui il deployment del servizio:

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

Prendi nota del valore timeout di 2 minuti per concedere alla funzione di ridimensionamento più tempo per l'elaborazione.

Dopo il deployment della funzione, imposta l'URL del servizio in una variabile, che ci servirà in un secondo momento:

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

8. Esegui il deployment del servizio di filigrana

Questo servizio Cloud Functions riceve le informazioni su bucket, file ed etichette, legge il file, aggiunge le etichette come filigrana all'immagine utilizzando ImageSharp e salva l'immagine nel bucket di output.

Nella cartella di primo livello processing-pipelines, esegui il deployment del servizio:

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

Dopo il deployment della funzione, imposta l'URL del servizio in una variabile, che ci servirà in un secondo momento:

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

A questo punto, devi eseguire il deployment e l'esecuzione di tutte e quattro le funzioni Cloud Functions:

76a218568982c90c.png

9. Definisci ed esegui il deployment del flusso di lavoro

Utilizza Workflows per riunire in un flusso di lavoro i servizi di filtro, etichettatore, ridimensionatore e filigrana. Workflows orchestra le chiamate a questi servizi nell'ordine e con i parametri da noi definiti.

Innanzitutto, abilita i servizi richiesti per Workflows:

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

Definisci

Workflows riceve un CloudEvent come parametro. Proveniente da Eventarc dopo la creazione di un trigger. Nei primi due passaggi, Workflows registra l'evento ed estrae dall'evento le informazioni su bucket e file:

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}

Nel passaggio filter, Workflows effettua una chiamata al servizio filtro di cui abbiamo eseguito il deployment in precedenza. Quindi registra e controlla la sicurezza dei file:

  - 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

Nel passaggio label, Workflows effettua una chiamata al servizio di etichettatura e acquisisce la risposta (le prime 3 etichette):

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

Nel passaggio resize, Workflows effettua una chiamata al servizio di ridimensionamento e acquisisce la risposta (il bucket e il file dell'immagine ridimensionata):

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

Nel passaggio watermark, Workflows chiama il servizio di filigrana con l'immagine ridimensionata e le etichette e acquisisce il risultato (l'immagine ridimensionata e con filigrana):

  - 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

Nel passaggio final, Workflows restituisce il codice di stato HTTP dai servizi di etichettatura, ridimensionamento e filigrana:

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

Esegui il deployment

Prima di eseguire il deployment del flusso di lavoro, assicurati che gli URL dei servizi vengano sostituiti con gli URL delle funzioni di cui è stato eseguito il deployment manualmente o utilizzando sed:

Nella cartella processing-pipelines di primo livello, vai alla cartella image-v3 in cui si trova il file workflows.yaml:

cd image-v3/

Esegui sed per sostituire gli URL segnaposto con gli URL effettivi dei servizi di cui è stato eseguito il deployment:

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

Esegui il deployment del flusso di lavoro:

WORKFLOW_NAME=image-processing

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

In pochi secondi, dovresti vedere il deployment del flusso di lavoro nella console:

92cf4e758bdc3dde.png

10. Crea trigger

Dopo aver eseguito il deployment del flusso di lavoro, l'ultimo passaggio consiste nel connetterlo agli eventi di Cloud Storage con un trigger Eventarc.

Installazione unica

Innanzitutto, abilita i servizi richiesti per Eventarc:

gcloud services enable \
 eventarc.googleapis.com

Crea un account di servizio che utilizzerai nel trigger Eventarc.

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

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

Concedi il ruolo workflows.invoker, in modo che l'account di servizio possa essere utilizzato per richiamare Workflows da Eventarc:

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

Concedi il ruolo eventarc.eventReceiver, altrimenti l'account di servizio può essere utilizzato in

Trigger di Cloud Storage:

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

Concedi il ruolo pubsub.publisher all'account di servizio Cloud Storage. È necessario per il trigger Cloud Storage di 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

Crea

Esegui questo comando per creare un trigger. Questo trigger filtra gli eventi di creazione di nuovi file dal bucket Cloud Storage di input e li trasmette al flusso di lavoro definito in precedenza:

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

Puoi vedere che il trigger è stato creato ed è pronto nella sezione Eventarc della console Cloud:

14330c4fa2451bc0.png

11. Testa la pipeline

La pipeline di elaborazione delle immagini è pronta a ricevere eventi da Cloud Storage. Per testare la pipeline, carica un'immagine nel bucket di input:

gsutil cp beach.jpg gs://$BUCKET1

Non appena carichi l'immagine, dovresti vedere un'esecuzione di Workflows in stato attivo:

36d07cb63c39e7d9.png

Dopo circa un minuto, l'esecuzione dovrebbe essere completata correttamente. Puoi anche visualizzare l'input e l'output del flusso di lavoro:

229200c79d989c25.png

Se elenchi i contenuti del bucket di output, dovresti vedere l'immagine ridimensionata, l'immagine ridimensionata e con filigrana e le etichette dell'immagine:

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

Per verificare, puoi aprire l'immagine ridimensionata e con filigrana per vedere il risultato:

75f3c0019ca842ce.jpeg

12. Complimenti

Complimenti, hai completato il codelab.

Argomenti trattati

  • Panoramica di Eventarc e Workflows
  • Come eseguire il deployment dei servizi Cloud Functions
  • Come orchestrare i servizi utilizzando Workflows
  • Come fare in modo che Workflows risponda agli eventi di Cloud Storage con Eventarc