Ereignisgesteuerte Orchestrierung mit Eventarc und Workflows erstellen

1. Einführung

cb762f29e9183a3f.png 1c05e3d0c2bd2b45.png a03f943ca09ac4c.png

Eventarc vereinfacht die Verbindung von Cloud Run-Diensten mit Ereignissen aus einer Vielzahl von Quellen. Sie können damit ereignisgesteuerte Architekturen erstellen, in denen Mikrodienste lose miteinander verknüpft und verteilt sind. Er übernimmt die Ereignisaufnahme, ‐übermittlung, ‐sicherheit, ‐autorisierung und Fehlerbehandlung für Sie.

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

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-Funktionen zur Bildverarbeitung zu orchestrieren. Anschließend aktivieren Sie die Orchestrierung, um mit Eventarc lose auf Cloud Storage-Ereignisse zu reagieren.

Am Ende haben Sie eine flexible, aber strukturierte serverlose Architektur zur Verarbeitung von Images.

e372ceed8c26c5fb.png

Lerninhalte

  • Eine Übersicht über Eventarc und Workflows
  • Cloud Functions-Dienste bereitstellen
  • Dienste mithilfe von Workflows orchestrieren
  • Workflows mit Eventarc auf Cloud Storage-Ereignisse reagieren lassen

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  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.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Projektteilnehmer. Es handelt sich um eine Zeichenfolge, die von Google APIs nicht verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf die Projekt-ID verweisen, die üblicherweise als PROJECT_ID gekennzeichnet ist. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID erstellen. Alternativ können Sie einen eigenen verwenden und nachsehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/APIs verwenden zu können. Dieses Codelab sollte möglichst wenig kosten. Wenn Sie Ressourcen herunterfahren möchten, um über diese Anleitung hinaus keine Kosten zu verursachen, können Sie die von Ihnen erstellten Ressourcen oder das gesamte Projekt löschen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, 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:

55efc1aaa7a4d3ad.png

Die Bereitstellung und Verbindung mit der Umgebung dauert nur einen Moment. Wenn er abgeschlossen ist, sollten Sie in etwa Folgendes sehen:

7ffe5cbb04455448.png

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

gcloud einrichten

Legen Sie in Cloud Shell Ihre Projekt-ID und die Region fest, in der Sie die Anwendung bereitstellen möchten. Speichern Sie sie als Variablen des Typs PROJECT_ID und REGION. Informationen zu 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 Repositorys eventarc-samples.

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:

6aa6fbc7721dd6b6.png

  1. Ein Bild wird in einem Eingabe-Bucket gespeichert, der ein Cloud Storage-Erstellungsereignis generiert.
  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 ermittelt der Cloud Functions-Dienst Filter mithilfe der Vision API, ob das Bild sicher ist. Wenn das Image sicher ist, fährt Workflows mit den nächsten Schritten fort.
  4. Im zweiten Schritt des Workflows extrahiert der Cloud Functions-Dienst Labeler die Bildlabels mit der Vision API und speichert sie im Ausgabe-Bucket.
  5. Im dritten Schritt Resizer, einem weiteren Cloud Functions-Dienst, passt die Größe des Bildes mithilfe von ImageSharp an und speichert das Bild im Ausgabe-Bucket.
  6. Im letzten Schritt fügt der Cloud Functions-Dienst Watermarker dem geänderten Bild mithilfe von ImageSharp ein Wasserzeichen mit Labels aus Labeler hinzu und speichert das Bild im Ausgabe-Bucket.

Die Anwendung wird durch ein Cloud Storage-Ereignis ausgelöst und ist daher ereignisgesteuert. Die Verarbeitung von Bildern erfolgt in einem Workflow, daher ist es 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 die Nutzer die Bilder hochladen können, und einen Ausgabe-Bucket für die Bildverarbeitungspipeline, um die verarbeiteten Bilder zu speichern.

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

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

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

Aktivieren Sie zuerst die erforderlichen Dienste für Cloud Functions gen2 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 übergeordneten Ordner processing-pipelines 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. Sie wird später benötigt:

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

6. Labelerstellerdienst bereitstellen

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

Stellen Sie den Dienst im übergeordneten Ordner processing-pipelines 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. Sie wird später benötigt:

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, passt die Bildgröße mit ImageSharp an und speichert das Bild im Ausgabe-Bucket.

Stellen Sie den Dienst im übergeordneten Ordner processing-pipelines 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

Notieren Sie sich den timeout-Wert von 2 Minuten, damit die Größenänderungsfunktion zusätzliche Verarbeitungszeit hat.

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

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

8. Wasserzeichendienst bereitstellen

Dieser Cloud Functions-Dienst empfängt die Bucket-, Datei- und Labelinformationen, liest die Datei, fügt dem Bild mithilfe von ImageSharp die Labels als Wasserzeichen hinzu und speichert das Bild im Ausgabe-Bucket.

Stellen Sie den Dienst im übergeordneten Ordner processing-pipelines 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. Sie wird später benötigt:

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

An dieser Stelle sollten alle vier Cloud Functions-Funktionen bereitgestellt und ausgeführt werden:

76a218568982c90c.png

9. Workflow definieren und bereitstellen

Mit Workflows können Sie die Dienste für Filter, Labelersteller, Größenanpassungen und Wasserzeichen in einem Workflow zusammenführen. Workflows orchestrieren das Aufrufen dieser Dienste in der 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. Sie 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 Filterdienst auf, den wir zuvor bereitgestellt haben. Dann 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 Labelerstellerdienst auf und erfasst die Antwort (Top-3-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 zur Größenänderung auf und erfasst die Antwort (den Bucket und die Datei des in der Größe angepassten Bildes):

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

Im Schritt watermark ruft Workflows den Wasserzeichendienst mit dem skalierten Bild und den Beschriftungen auf und erfasst das Ergebnis (das Bild mit der geänderten Größe und mit dem Wasserzeichen):

  - 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 die Workflows den HTTP-Statuscode der Labelersteller-, Größen- und Wasserzeichendienste zurück:

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

Bereitstellen

Achten Sie vor der Bereitstellung des Workflows darauf, dass die Dienst-URLs durch die URLs der bereitgestellten Funktionen entweder manuell oder mit sed ersetzt werden:

Gehen Sie im Ordner der obersten Ebene processing-pipelines 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 wenigen Sekunden sollten Sie den Workflow in der Console sehen:

92cf4e758bdc3dde.png

10. Trigger erstellen

Nachdem der Workflow bereitgestellt wurde, muss er im letzten Schritt über einen Eventarc-Trigger mit Cloud Storage-Ereignissen verbunden werden.

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 werden.

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

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

Gewähren Sie die Rolle workflows.invoker, 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 die Rolle eventarc.eventReceiver zu, damit das Dienstkonto 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

Gewähren Sie dem Cloud Storage-Dienstkonto die Rolle pubsub.publisher. 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 zur Erstellung neuer Dateien aus dem Cloud Storage-Eingabe-Bucket und übergibt sie an den zuvor definierten Workflow:

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

Im Eventarc-Bereich der Cloud Console können Sie sehen, dass der Trigger erstellt und bereit ist:

14330c4fa2451bc0.png

11. Pipeline testen

Die Bildverarbeitungspipeline 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 hochgeladen haben, sollte eine Workflows-Ausführung im Status „Aktiv“ angezeigt werden:

36d07cb63c39e7d9.png

Nach etwa einer Minute sollten Sie sehen, dass die Ausführung erfolgreich war. Sie können auch die Ein- und Ausgabe des Workflows sehen:

229200c79d989c25.png

Wenn Sie den Inhalt des Ausgabe-Buckets auflisten, sollten Sie das größenangepasste Bild, das in der Größe angepasste und mit Wasserzeichen versehene Bild sowie die Bildlabels sehen:

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

Zur Überprüfung können Sie das in der Größe angepasste und mit Wasserzeichen versehene Bild öffnen, um das Ergebnis zu sehen:

75f3c0019ca842ce.jpeg

12. Glückwunsch

Glückwunsch, du hast das Codelab abgeschlossen.

Behandelte Themen

  • Eine Übersicht über Eventarc und Workflows
  • Cloud Functions-Dienste bereitstellen
  • Dienste mithilfe von Workflows orchestrieren
  • Workflows mit Eventarc auf Cloud Storage-Ereignisse reagieren lassen