Crea un'orchestrazione basata su eventi con Eventarc e Workflows

1. Introduzione

f2f35f5c40b91a3c.png c637dcc97f298e7e.png c4a9d5b95f111710.png

Eventarc semplifica la connessione dei servizi Cloud Run con eventi provenienti da varie 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.

Workflows è 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 basata sugli eventi di microservizi per elaborare le immagini. Utilizzerai Workflows per orchestrare l'ordine, gli input e gli output di quattro Cloud Functions di elaborazione delle immagini. A questo punto, attiverai l'orchestrazione per rispondere agli eventi di Cloud Storage in modo a basso accoppiamento con Eventarc.

Alla fine, avrai un'architettura serverless flessibile ma strutturata per l'elaborazione delle immagini.

b75a14a4268cbe73.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 autonomo

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

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Il nome del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google. Puoi sempre aggiornarlo.
  • L'ID progetto è univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo l'impostazione). La console Cloud genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, dovrai fare riferimento all'ID progetto (in genere identificato come PROJECT_ID). Se non ti piace l'ID generato, puoi generarne un altro casuale. In alternativa, puoi provare a crearne uno e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimane per tutta la durata del progetto.
  • Per tua informazione, esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. Completare questo codelab non costa molto, se non nulla. Per arrestare le risorse ed evitare addebiti oltre a quelli previsti in questo tutorial, puoi eliminare le risorse che hai creato o il progetto. I nuovi utenti di Google Cloud possono usufruire del programma prova senza costi di 300$.

Avvia Cloud Shell

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

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

Attiva Cloud Shell

Bastano pochi istanti per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere un risultato simile a questo:

Screenshot del terminale Google Cloud Shell che mostra che l'ambiente è connesso

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

Configura gcloud

In Cloud Shell, imposta l'ID progetto e la regione in cui vuoi eseguire il deployment dell'applicazione. Salvali come variabili PROJECT_ID e REGION. Consulta Località di Cloud Functions per 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:

7b810e1505054c0c.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 Cloud Storage e trasmesso a Workflows come CloudEvent.
  3. Nel primo passaggio del flusso di lavoro, Filter, un servizio Cloud Functions, utilizza l'API Vision per determinare se l'immagine è sicura. Se l'immagine è sicura, i flussi di lavoro continuano con i passaggi successivi.
  4. Nel secondo passaggio del flusso di lavoro, Labeler, un servizio Cloud Functions, estrae le etichette dell'immagine con l'API Vision e le salva nel bucket di output.
  5. Nel terzo passaggio, Resizer, un altro servizio Cloud Functions, ridimensiona l'immagine utilizzando ImageSharp e la salva nel bucket di output.
  6. Nell'ultimo passaggio, Watermarker, un altro servizio 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, quindi è basata sugli eventi. L'elaborazione delle immagini avviene in un workflow, quindi si tratta di un'orchestrazione. Alla fine, si tratta di un'orchestrazione basata su eventi per un'architettura serverless flessibile ma strutturata per l'elaborazione delle immagini.

4. Crea bucket

Crea un bucket di input in cui gli utenti possono caricare le immagini e un bucket di output in cui la pipeline di elaborazione delle immagini può salvare le immagini elaborate.

Esegui il comando riportato di seguito in Cloud Shell:

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

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

5. Esegui il deployment del servizio di filtro

Iniziamo eseguendo 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

All'interno della 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

Una volta eseguito il deployment della funzione, imposta l'URL del servizio in una variabile, ne avremo bisogno 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.

All'interno della 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

Una volta eseguito il deployment della funzione, imposta l'URL del servizio in una variabile, ne avremo bisogno 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.

All'interno della 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 consentire alla funzione di ridimensionamento di avere più tempo per l'elaborazione.

Una volta eseguito il deployment della funzione, imposta l'URL del servizio in una variabile, ne avremo bisogno 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.

All'interno della 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

Una volta eseguito il deployment della funzione, imposta l'URL del servizio in una variabile, ne avremo bisogno in un secondo momento:

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

A questo punto, tutte e quattro le funzioni Cloud devono essere implementate ed eseguite:

fe662925cb0121e9.png

9. Definisci ed esegui il deployment del workflow

Utilizza i workflow per riunire i servizi di filtro, etichettatura, ridimensionamento e filigrana in un unico workflow. Workflows orchestrerà la chiamata di questi servizi nell'ordine e con i parametri che definiamo.

Innanzitutto, abilita i servizi richiesti per Workflows:

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

Definisci

Workflows riceve un CloudEvent come parametro. Questo valore verrà fornito da Eventarc una volta creato un trigger. Nei primi due passaggi, Workflows registra l'evento ed estrae le informazioni sul bucket e sul file dall'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}

Nel passaggio filter, Workflows chiama il servizio di filtro che abbiamo implementato in precedenza. Quindi, registra e controlla la sicurezza del 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, i flussi di lavoro chiamano il servizio di etichettatura e acquisiscono la risposta (le prime tre 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 chiama il 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 filigranata):

  - 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, i flussi di lavoro restituiscono il codice di stato HTTP dei 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 del servizio vengano sostituiti con gli URL delle funzioni di cui è stato eseguito il deployment manualmente o utilizzando sed:

All'interno della cartella di primo livello processing-pipelines, 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 workflow:

WORKFLOW_NAME=image-processing

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

Dopo pochi secondi, dovresti vedere il workflow di cui è stato eseguito il deployment nella console:

a5f537f2b3f3bd3.png

10. Crea trigger

Ora che il flusso di lavoro è stato eseguito il deployment, l'ultimo passaggio consiste nel collegarlo agli eventi Cloud Storage con un trigger Eventarc.

Installazione unica

Innanzitutto, abilita i servizi richiesti per Eventarc:

gcloud services enable \
 eventarc.googleapis.com

Crea un service account da utilizzare 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 il service account possa essere utilizzato per richiamare i workflow 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 non può essere utilizzato in un

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 al service account Cloud Storage. Questo è 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 passa 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 notare che il trigger è stato creato ed è pronto nella sezione Eventarc della console Google Cloud:

a5f4301863d7d9e4.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:

2c914341950b5fde.png

Dopo circa un minuto, dovresti vedere che l'esecuzione è riuscita. Puoi anche visualizzare l'input e l'output del flusso di lavoro:

9abba6c28c51a9b5.png

Se elenchi i contenuti del bucket di output, dovresti visualizzare l'immagine ridimensionata, l'immagine ridimensionata e filigranata e le etichette dell'immagine:

gsutil ls gs://$BUCKET2

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

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

46d375cb05a8aae4.jpeg

12. Complimenti

Congratulazioni, 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