Crea una organización controlada por eventos con Eventarc y flujos de trabajo

1. Introducción

cb762f29e9183a3f.png 1c05e3d0c2bd2b45.png a03f943ca09ac4c.png

Eventarc facilita la conexión de los servicios de Cloud Run con eventos de varias fuentes. Le permite compilar arquitecturas basadas en eventos en las que los microservicios se vinculan y distribuyen de manera flexible. Se encarga de la transferencia, entrega, seguridad, autorización y manejo de errores de eventos por ti.

Workflows es una plataforma de organización completamente administrada que ejecuta servicios en el orden que definas: un flujo de trabajo. Estos flujos de trabajo pueden combinar servicios alojados en Cloud Run o Cloud Functions, servicios de Google Cloud, como Cloud Vision AI y BigQuery, y cualquier API basada en HTTP.

En este codelab, compilarás una organización de microservicios controlada por eventos para procesar imágenes. Usará Workflows para organizar el orden, las entradas y las salidas de 4 procesamientos de imágenesCloud Functions , Luego, habilitará la organización para responder a los eventos de Cloud Storage de manera flexible con Eventarc.

Al final, terminará con una arquitectura sin servidores flexible y estructurada para procesar imágenes.

e372ceed8c26c5fb.png

Qué aprenderás

  • Descripción general de Eventarc y flujos de trabajo
  • Cómo implementar los servicios de Cloud Functions
  • Cómo organizar servicios con flujos de trabajo
  • Cómo hacer que los flujos de trabajo respondan a eventos de Cloud Storage con Eventarc

2. Configuración y requisitos

Canjear créditos

cae48e4b2e19921d.png

En el diálogo siguiente, haz clic en el botón "Aceptar y continuar" para aceptar las Condiciones del Servicio:

27d87930a0daf2f8.png

Después de aceptar las condiciones del servicio, se te redireccionará a una página de resumen de facturación que incluye un panel como el que se muestra cerca de la esquina inferior derecha:

2076ea7aa9bf3f65.png

Por último, cuando crees tu primer proyecto, verás un cuadro de diálogo que te permitirá asignar una cuenta de facturación a tu proyecto. Selecciona la cuenta de facturación asociada con tus créditos gratuitos y haz clic en el botón de crear:

dd3b0e795843296.png

En resumen, ahora tienes una cuenta de facturación y un proyecto, y ambas entidades están vinculadas, de modo que cualquier trabajo que realices en el codelab de hoy se financiará con tus créditos gratuitos**.**

Configuración del entorno a su propio ritmo

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o Google Workspace, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
  • El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única. por lo general, no importa lo que sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (y suele identificarse como PROJECT_ID). Por lo tanto, si no te gusta, genera otro aleatorio, o puedes probar el tuyo al mismo tiempo. está disponible. Luego, se "congela" después de crear el proyecto.
  • Hay un tercer valor, un número de proyecto que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberá habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no incurrir en la facturación después de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa de prueba gratuita de USD 300.

Inicie Cloud Shell

Si bien Google Cloud se puede operar de forma remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

En Google Cloud Console, haga clic en el ícono de Cloud Shell en la barra de herramientas superior derecha:

55efc1aaa7a4d3ad.png

El aprovisionamiento y la conexión al entorno debería llevar solo unos minutos. Cuando termine, debería ver algo como lo siguiente:

7ffe5cbb04455448.png

Esta máquina virtual está cargada con todas las herramientas para desarrolladores que necesitará. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora enormemente el rendimiento y la autenticación de la red. Puede realizar todo su trabajo en este lab usando un navegador.

Configura gcloud

En Cloud Shell, establezca el ID del proyecto y la región en la que desea implementar su aplicación. Guárdalas como variables PROJECT_ID y REGION. Consulta las ubicaciones de Cloud Functions para conocer las regiones disponibles.

PROJECT_ID=[YOUR-PROJECT-ID]
REGION=[YOUR-REGION]
gcloud config set core/project $PROJECT_ID
gcloud config set functions/region $REGION

Habilita los servicios

Habilita todos los servicios necesarios:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  vision.googleapis.com \
  workflows.googleapis.com \
  workflowexecutions.googleapis.com

Obtén el código fuente

El código fuente de la aplicación se encuentra en la carpeta processing-pipelines del repositorio eventarc-samples.

Clone el repositorio:

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

Navega a la carpeta eventarc-samples/processing-pipelines:

cd eventarc-samples/processing-pipelines

3. Descripción general de la arquitectura

La arquitectura de la aplicación es la siguiente:

6aa6fbc7721dd6b6.png

  1. Una imagen se guarda en un bucket de entrada que genera un evento de creación de Cloud Storage.
  2. Eventarc lee el evento de creación de Cloud Storage mediante un activador de Cloud Storage y lo pasa a Workflows como CloudEvent.
  3. En el primer paso del flujo de trabajo, Filter, un servicio de Cloud Functions, usa la API de Vision para determinar si la imagen es segura. Si la imagen es segura, los flujos de trabajo continuarán con los siguientes pasos.
  4. En el segundo paso del flujo de trabajo, Labeler, un servicio de Cloud Functions, extrae las etiquetas de la imagen con la API de Vision y las guarda en el bucket de salida.
  5. En el tercer paso, Resizer, otro servicio de Cloud Functions, cambia el tamaño de la imagen con ImageSharp y la guarda en el bucket de salida.
  6. En el último paso, WaterMarker, otro servicio de Cloud Functions, agrega una marca de agua de las etiquetas de Labeler a la imagen redimensionada con ImageSharp, y la guarda en el bucket de salida.

Un evento de Cloud Storage activa la aplicación, por lo que se controla mediante un evento. El procesamiento de imágenes se realiza en un flujo de trabajo, por lo que es una organización. Al fin y al cabo, es una organización controlada por eventos para una arquitectura flexible y sin servidores estructurada con la que se procesan las imágenes.

4. Crear depósitos

Crear un bucket de entrada para que los usuarios suban las imágenes y un bucket de salida a fin de que la canalización de procesamiento de imágenes guarde las imágenes procesadas

En Cloud Shell, ejecute lo siguiente:

BUCKET1=$PROJECT_ID-images-input
BUCKET2=$PROJECT_ID-images-output
gsutil mb -l $REGION gs://$BUCKET1
gsutil mb -l $REGION gs://$BUCKET2

5. Implementa el servicio de filtro

Comencemos por implementar el primer servicio. Este servicio de Cloud Functions recibe la información del archivo y el bucket, y determina si la imagen es segura con la API de Vision y muestra el resultado.

Dentro de la carpeta de nivel superior processing-pipelines, implementa el servicio:

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

Una vez implementada la función, configura la URL del servicio en una variable, ya que la necesitaremos más adelante:

FILTER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

6. Implementa el servicio de etiquetador

El segundo servicio de Cloud Functions recibe la información del archivo y el bucket, extrae etiquetas de la imagen con la API de Vision y las guarda en el bucket de salida.

Dentro de la carpeta de nivel superior processing-pipelines, implementa el servicio:

SERVICE_NAME=labeler
gcloud functions deploy $SERVICE_NAME \
  --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 vez implementada la función, configura la URL del servicio en una variable, ya que la necesitaremos más adelante:

LABELER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

7. Implementa el servicio de cambio de tamaño

Este servicio de Cloud Functions recibe la información del archivo y el bucket, cambia el tamaño de la imagen con ImageSharp y la guarda en el bucket de salida.

Dentro de la carpeta de nivel superior processing-pipelines, implementa el servicio:

SERVICE_NAME=resizer
gcloud functions deploy $SERVICE_NAME \
  --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

Una vez implementada la función, configura la URL del servicio en una variable, ya que la necesitaremos más adelante:

RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

8. Implementa el servicio de marca de agua

Este servicio de Cloud Functions recibe la información del bucket, el archivo y las etiquetas, lee el archivo, agrega las etiquetas como marca de agua a la imagen con ImageSharp y la guarda en el bucket de salida.

Dentro de la carpeta de nivel superior processing-pipelines, implementa el servicio:

SERVICE_NAME=watermarker
gcloud functions deploy $SERVICE_NAME \
  --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 vez implementada la función, configura la URL del servicio en una variable, ya que la necesitaremos más adelante:

WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

En este punto, se deben implementar y ejecutar las cuatro Cloud Functions:

5d7d4061e04c91bb.png

9. Defina e implemente el flujo de trabajo

Usar flujos de trabajo para reunir los servicios de filtro, etiquetador, cambio de tamaño y marca de agua en un flujo de trabajo Los flujos de trabajo organizarán las llamadas a estos servicios en el orden y con los parámetros que definamos.

Definir

Los flujos de trabajo reciben un CloudEvent como parámetro. Esto provendrá de Eventarc una vez que creemos un activador. En los primeros dos pasos, los flujos de trabajo registran el evento y extraen la información del archivo y del bucket:

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}

En el paso filter, los flujos de trabajo llaman al servicio de filtros que implementamos antes. Luego, registra y verifica la seguridad del archivo:

  - 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

En el paso label, los flujos de trabajo hacen una llamada al servicio de etiquetador y capturan la respuesta (las 3 etiquetas principales):

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

En el paso resize, los flujos de trabajo llaman al servicio de cambio de tamaño y captura la respuesta (el bucket y el archivo de la imagen a la que se le cambió el tamaño):

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

En el paso watermark, los flujos de trabajo llaman al servicio de marca de agua con la imagen y las etiquetas con el tamaño cambiado, y capturan el resultado (la imagen redimensionada y con marca de agua):

  - 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

En el paso final, los flujos de trabajo muestran el código de estado HTTP de los servicios de etiquetador, cambio de tamaño y marca de agua:

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

Deploy

Antes de implementar el flujo de trabajo, asegúrate de que las URL del servicio se reemplacen por las URL de las funciones implementadas de forma manual o mediante sed:

Dentro de la carpeta de nivel superior processing-pipelines, navega a la carpeta image-v3 donde se encuentra el archivo workflows.yaml:

cd image-v3/

Ejecuta sed para reemplazar las URL del marcador de posición por las URL reales de los servicios implementados:

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

Implementa el flujo de trabajo:

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

En pocos segundos, debería ver el flujo de trabajo implementado en la consola:

92cf4e758bdc3dde.png

10. Crear activador

Ahora que el flujo de trabajo está implementado, el último paso es conectarlo a los eventos de Cloud Storage con un activador de Eventarc.

Configuración única

Se usará la cuenta de servicio de procesamiento predeterminada para el activador. Asegúrate de que tenga la función eventarc.eventReceiver:

PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

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

Otorga la función pubsub.publisher a la cuenta de servicio de Cloud Storage. Esto es necesario para el activador de Cloud Storage de Eventarc:

SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_NUMBER)"

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

Crear

Ejecute los siguientes comandos para crear un activador. Este activador filtra los eventos nuevos de creación de archivos desde el bucket de entrada de Cloud Storage y los pasa al flujo de trabajo que definimos antes:

TRIGGER_NAME=trigger-$WORKFLOW_NAME
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=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

Puede ver que el activador se creó y está listo en la sección Eventarc de Cloud Console:

14330c4fa2451bc0.png

11. Pruebe la canalización

La canalización de procesamiento de imágenes está lista para recibir eventos de Cloud Storage. Para probar la canalización, suba una imagen al bucket de entrada:

gsutil cp beach.jpg gs://$BUCKET1

Apenas subas la foto, deberías ver una ejecución de flujos de trabajo en estado activo:

36d07cb63c39e7d9.png

Después de aproximadamente un minuto, deberías ver que la ejecución se realizó de forma correcta. También puede ver la entrada y salida del flujo de trabajo:

229200c79d989c25.png

Si muestra el contenido del bucket de salida, debería ver la imagen redimensionada, la etiqueta redimensionada y las etiquetas de la imagen, como se muestra a continuación:

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

A fin de volver a revisar, puedes abrir la imagen con el tamaño cambiado y con una marca de agua para ver el resultado:

75f3c0019ca842ce.jpeg

12. Felicitaciones

¡Felicitaciones! Completaste el codelab.

Temas abordados

  • Descripción general de Eventarc y flujos de trabajo
  • Cómo implementar los servicios de Cloud Functions
  • Cómo organizar servicios con flujos de trabajo
  • Cómo hacer que los flujos de trabajo respondan a eventos de Cloud Storage con Eventarc