Ereignisgesteuerte Orchestrierung mit Eventarc und Workflows erstellen

1. Einführung

f2f35f5c40b91a3c.png c637dcc97f298e7e.png c4a9d5b95f111710.png

Mit Eventarc lassen sich Cloud Run-Dienste ganz einfach mit Ereignissen aus verschiedenen Quellen verbinden. Damit können Sie ereignisgesteuerte Architekturen erstellen, in denen Mikrodienste lose gekoppelt und verteilt sind. Eventarc übernimmt die Aufnahme, Bereitstellung, Sicherheit, Autorisierung und Fehlerbehandlung von Daten für Sie.

Workflows ist eine vollständig verwaltete Orchestrierungsplattform, die Dienste in einer von Ihnen definierten Reihenfolge ausführt: einem Workflow. Diese Workflows können Dienste kombinieren, die in Cloud Run oder Cloud Functions gehostet werden, Google Cloud-Dienste wie Cloud Vision AI und BigQuery sowie eine beliebige HTTP-basierte API.

In diesem Codelab erstellen Sie eine ereignisgesteuerte Orchestrierung von Mikrodiensten zur Verarbeitung von Bildern. Sie verwenden Workflows, um die Reihenfolge, Eingaben und Ausgaben von vier Cloud Functions zur Bildverarbeitung zu orchestrieren. Anschließend aktivieren Sie die Orchestrierung, damit sie mit Eventarc lose gekoppelt auf Cloud Storage-Ereignisse reagiert.

Am Ende erhalten Sie eine flexible, aber strukturierte serverlose Architektur für die Verarbeitung von Bildern.

b75a14a4268cbe73.png

Lerninhalte

  • Übersicht über Eventarc und Workflows
  • Cloud Functions-Dienste bereitstellen
  • Dienste mit Workflows koordinieren
  • Workflows mit Eventarc auf Cloud Storage-Ereignisse reagieren lassen

2. Einrichtung und Anforderungen

Einrichtung der Umgebung im eigenen Tempo

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (kann nach dem Festlegen nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen Namen versuchen. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um Kosten zu vermeiden, die über diese Anleitung hinausgehen, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können am Programm Kostenlose Testversion mit einem Guthaben von 300$ teilnehmen.

Cloud Shell starten

Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Klicken Sie in der Google Cloud Console rechts oben in der Symbolleiste auf das Cloud Shell-Symbol:

Cloud Shell aktivieren

Die Bereitstellung und Verbindung mit der Umgebung sollte nur wenige Augenblicke dauern. Anschließend sehen Sie in etwa Folgendes:

Screenshot des Google Cloud Shell-Terminals, auf dem zu sehen ist, dass die Umgebung verbunden ist

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Alle Aufgaben in diesem Codelab können in einem Browser ausgeführt werden. Sie müssen nichts installieren.

gcloud einrichten

Legen Sie in Cloud Shell Ihre Projekt-ID und die Region fest, in der Sie Ihre Anwendung bereitstellen möchten. Speichern Sie diese als die Variablen PROJECT_ID und REGION ab. Die verfügbaren Regionen finden Sie unter Cloud Functions-Standorte.

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

Quellcode abrufen

Der Quellcode der Anwendung befindet sich im Ordner processing-pipelines des eventarc-samples-Repositorys.

Klonen Sie das Repository:

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

Rufen Sie den eventarc-samples/processing-pipelines-Ordner auf:

cd eventarc-samples/processing-pipelines

3. Architektur

Die Architektur der Anwendung sieht so aus:

7b810e1505054c0c.png

  1. Ein Bild wird in einem Eingabe-Bucket gespeichert, wodurch ein Cloud Storage-Erstellungsereignis generiert wird.
  2. Das Cloud Storage-Erstellungsereignis wird von Eventarc über einen Cloud Storage-Trigger gelesen und als CloudEvent an Workflows übergeben.
  3. Im ersten Schritt des Workflows, Filter, wird mit einem Cloud Functions-Dienst die Vision API verwendet, um zu ermitteln, ob das Bild sicher ist. Wenn das Bild sicher ist, werden die nächsten Schritte ausgeführt.
  4. Im zweiten Schritt des Workflows, Labeler, extrahiert ein Cloud Functions-Dienst Labels des Bildes mit der Vision API und speichert die Labels im Ausgabebucket.
  5. Im dritten Schritt, Resizer, wird das Bild mit ImageSharp in einem weiteren Cloud Functions-Dienst in der Größe angepasst und im Ausgabebucket gespeichert.
  6. Im letzten Schritt, Watermarker, fügt ein weiterer Cloud Functions-Dienst mit ImageSharp ein Wasserzeichen mit Labels aus Labeler zum skalierten Bild hinzu und speichert das Bild im Ausgabebucket.

Die Anwendung wird durch ein Cloud Storage-Ereignis ausgelöst und ist daher ereignisgesteuert. Die Verarbeitung von Bildern erfolgt in einem Workflow, daher handelt es sich um eine Orchestrierung. Letztendlich handelt es sich um eine ereignisgesteuerte Orchestrierung für eine flexible, aber strukturierte serverlose Architektur zur Verarbeitung von Bildern.

4. Buckets erstellen

Erstellen Sie einen Eingabe-Bucket, in den Nutzer die Bilder hochladen können, und einen Ausgabe-Bucket, in dem die Pipeline zur Bildverarbeitung die verarbeiteten Bilder speichert.

Führen Sie in Cloud Shell den folgenden Befehl aus:

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. Filterdienst bereitstellen

Beginnen wir mit der Bereitstellung des ersten Dienstes. Dieser Cloud Functions-Dienst empfängt die Bucket- und Dateiinformationen, ermittelt mit der Vision API, ob das Bild sicher ist, und gibt das Ergebnis zurück.

Aktivieren Sie zuerst die erforderlichen Dienste für Cloud Functions der 2. Generation und die Vision API:

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

Stellen Sie den Dienst im Ordner processing-pipelines der obersten Ebene bereit:

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

Nachdem die Funktion bereitgestellt wurde, legen Sie die Dienst-URL in einer Variablen fest. Wir benötigen sie später:

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

6. Labeler-Dienst bereitstellen

Der zweite Cloud Functions-Dienst empfängt die Bucket- und Dateiinformationen, extrahiert Labels des Bildes mit der Vision API und speichert die Labels im Ausgabebucket.

Stellen Sie den Dienst im Ordner processing-pipelines der obersten Ebene bereit:

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

Nachdem die Funktion bereitgestellt wurde, legen Sie die Dienst-URL in einer Variablen fest. Wir benötigen sie später:

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

7. Resizer-Dienst bereitstellen

Dieser Cloud Functions-Dienst empfängt die Bucket- und Dateiinformationen, ändert die Größe des Bildes mit ImageSharp und speichert das Bild im Ausgabebucket.

Stellen Sie den Dienst im Ordner processing-pipelines der obersten Ebene bereit:

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

Beachten Sie den timeout-Wert von 2 Minuten, damit die Resizer-Funktion mehr Zeit für die Verarbeitung hat.

Nachdem die Funktion bereitgestellt wurde, legen Sie die Dienst-URL in einer Variablen fest. Wir benötigen sie später:

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

8. Wasserzeichen-Dienst bereitstellen

Dieser Cloud Functions-Dienst empfängt die Informationen zu Bucket, Datei und Labels, liest die Datei, fügt die Labels mit ImageSharp als Wasserzeichen in das Bild ein und speichert das Bild im Ausgabebucket.

Stellen Sie den Dienst im Ordner processing-pipelines der obersten Ebene bereit:

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

Nachdem die Funktion bereitgestellt wurde, legen Sie die Dienst-URL in einer Variablen fest. Wir benötigen sie später:

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

Zu diesem Zeitpunkt sollten alle vier Cloud Functions-Funktionen bereitgestellt sein und ausgeführt werden:

fe662925cb0121e9.png

9. Workflow definieren und bereitstellen

Mit Workflows können Sie Filter-, Labeler-, Resizer- und Watermarker-Dienste in einem Workflow zusammenführen. Workflows orchestrieren den Aufruf dieser Dienste in der von uns definierten Reihenfolge und mit den von uns definierten Parametern.

Aktivieren Sie zuerst die erforderlichen Dienste für Workflows:

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

Definieren

Workflows empfängt ein CloudEvent als Parameter. Dieser Wert stammt von Eventarc, sobald wir einen Trigger erstellen. In den ersten beiden Schritten protokolliert Workflows das Ereignis und extrahiert die Bucket- und Dateiinformationen aus dem Ereignis:

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}

Im Schritt filter ruft Workflows den zuvor bereitgestellten Filterservice auf. Anschließend wird die Dateisicherheit protokolliert und geprüft:

  - 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

Im Schritt label ruft Workflows den Labeling-Dienst auf und erfasst die Antwort (die drei wichtigsten Labels):

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

Im Schritt resize ruft Workflows den Dienst zum Ändern der Größe auf und erfasst die Antwort (den Bucket und die Datei des Bildes mit geänderter Größe):

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

Im watermark-Schritt ruft Workflows den Watermarker-Dienst mit dem angepassten Bild und den Labels auf und erfasst das Ergebnis (das angepasste und mit Wasserzeichen versehene Bild):

  - 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

Im Schritt final gibt Workflows den HTTP-Statuscode von den Diensten „Labeler“, „Resizer“ und „Watermarker“ zurück:

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

Bereitstellen

Bevor Sie den Workflow bereitstellen, müssen Sie die Dienst-URLs manuell oder mit sed durch die URLs der bereitgestellten Funktionen ersetzen:

Wechseln Sie im Ordner processing-pipelines der obersten Ebene zum Ordner image-v3, in dem sich die Datei workflows.yaml befindet:

cd image-v3/

Führen Sie sed aus, um die Platzhalter-URLs durch die tatsächlichen URLs der bereitgestellten Dienste zu ersetzen:

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

Stellen Sie den Workflow bereit:

WORKFLOW_NAME=image-processing

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

Nach einigen Sekunden sollte der bereitgestellte Workflow in der Konsole angezeigt werden:

a5f537f2b3f3bd3.png

10. Trigger erstellen

Nachdem der Workflow bereitgestellt wurde, besteht der letzte Schritt darin, ihn mit einem Eventarc-Trigger mit Cloud Storage-Ereignissen zu verbinden.

Einmalige Einrichtung

Aktivieren Sie zuerst die erforderlichen Dienste für Eventarc:

gcloud services enable \
 eventarc.googleapis.com

Erstellen Sie ein Dienstkonto, das Sie im Eventarc-Trigger verwenden.

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

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

Weisen Sie die Rolle workflows.invoker zu, damit das Dienstkonto zum Aufrufen von Workflows aus Eventarc verwendet werden kann:

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

Weisen Sie dem Dienstkonto die Rolle eventarc.eventReceiver zu, damit es in einem

Cloud Storage-Trigger:

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

Weisen Sie dem Cloud Storage-Dienstkonto die Rolle pubsub.publisher zu. Dies ist für den Cloud Storage-Trigger von Eventarc erforderlich:

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

Erstellen

Führen Sie den folgenden Befehl aus, um einen Trigger zu erstellen. Dieser Trigger filtert nach Ereignissen zum Erstellen neuer Dateien aus dem Cloud Storage-Eingabe-Bucket und übergibt sie an den Workflow, den wir zuvor definiert haben:

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

Sie können sehen, dass der Trigger im Eventarc-Abschnitt der Cloud Console erstellt wurde und bereit ist:

a5f4301863d7d9e4.png

11. Pipeline testen

Die Bildverarbeitungs-Pipeline ist bereit, Ereignisse aus Cloud Storage zu empfangen. Laden Sie zum Testen der Pipeline ein Bild in den Eingabe-Bucket hoch:

gsutil cp beach.jpg gs://$BUCKET1

Sobald Sie das Bild hochladen, sollte eine Workflow-Ausführung im aktiven Status angezeigt werden:

2c914341950b5fde.png

Nach etwa einer Minute sollte die Ausführung erfolgreich sein. Sie können sich auch die Ein- und Ausgabe des Workflows ansehen:

9abba6c28c51a9b5.png

Wenn Sie den Inhalt des Ausgabebuckets auflisten, sollten Sie das in der Größe angepasste Bild, das in der Größe angepasste und mit Wasserzeichen versehene Bild sowie die Labels des Bildes sehen:

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

Sie können das verkleinerte und mit Wasserzeichen versehene Bild öffnen, um das Ergebnis zu sehen:

46d375cb05a8aae4.jpeg

12. Glückwunsch

Herzlichen Glückwunsch! Sie haben das Codelab abgeschlossen.

Behandelte Themen

  • Übersicht über Eventarc und Workflows
  • Cloud Functions-Dienste bereitstellen
  • Dienste mit Workflows koordinieren
  • Workflows mit Eventarc auf Cloud Storage-Ereignisse reagieren lassen