Создайте управляемую событиями оркестрацию с помощью Eventarc и Workflows.

1. Введение

f2f35f5c40b91a3c.pngc637dcc97f298e7e.pngc4a9d5b95f111710.png

Eventarc упрощает подключение сервисов Cloud Run к событиям из различных источников. Он позволяет создавать архитектуры, управляемые событиями, в которых микросервисы слабо связаны и распределены. Eventarc берет на себя обработку событий, их доставку, безопасность, авторизацию и обработку ошибок.

Workflows — это полностью управляемая платформа оркестровки, которая выполняет сервисы в порядке, заданном вами: рабочий процесс. Эти рабочие процессы могут объединять сервисы, размещенные на Cloud Run или Cloud Functions, сервисы Google Cloud, такие как Cloud Vision AI и BigQuery, а также любые API на основе HTTP.

В этом практическом занятии вы создадите событийно-ориентированную оркестровку микросервисов для обработки изображений. Вы будете использовать рабочие процессы (Workflows) для организации порядка, входных и выходных данных 4 облачных функций обработки изображений. Затем вы настроите оркестровку для реагирования на события облачного хранилища в слабосвязанном режиме с помощью Eventarc.

В итоге вы получите гибкую, но структурированную бессерверную архитектуру для обработки изображений.

b75a14a4268cbe73.png

Что вы узнаете

  • Обзор Eventarc и рабочих процессов.
  • Как развернуть сервисы Cloud Functions
  • Как организовать работу сервисов с помощью рабочих процессов.
  • Как настроить рабочие процессы на реагирование на события облачного хранилища с помощью Eventarc

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы всегда можете его изменить.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта (обычно обозначается как PROJECT_ID ). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он сохраняется на протяжении всего проекта.
  • К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
  1. Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.

В консоли Google Cloud нажмите на значок Cloud Shell на панели инструментов в правом верхнем углу:

Активировать Cloud Shell

Подготовка и подключение к среде займут всего несколько минут. После завершения вы должны увидеть что-то подобное:

Скриншот терминала Google Cloud Shell, показывающий, что среда подключена.

Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Вся работа в этом практическом задании может выполняться в браузере. Вам не нужно ничего устанавливать.

Настройте gcloud

В Cloud Shell укажите идентификатор проекта и регион, в который вы хотите развернуть приложение. Сохраните их как переменные PROJECT_ID и REGION . Список доступных регионов см. в разделе «Расположения Cloud Functions» .

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

Получите исходный код

Исходный код приложения находится в папке processing-pipelines репозитория eventarc-samples .

Клонируйте репозиторий:

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

Перейдите в папку eventarc-samples/processing-pipelines :

cd eventarc-samples/processing-pipelines

3. Обзор архитектуры

Архитектура приложения выглядит следующим образом:

7b810e1505054c0c.png

  1. Изображение сохраняется во входной сегмент, что приводит к генерации события создания в Cloud Storage.
  2. Событие создания объекта Cloud Storage считывается Eventarc через триггер Cloud Storage и передается в рабочие процессы в виде объекта CloudEvent.
  3. На первом этапе рабочего процесса сервис облачных функций Filter использует API Vision для определения безопасности изображения. Если изображение безопасно, рабочий процесс переходит к следующим шагам.
  4. На втором этапе рабочего процесса сервис облачных функций Labeler извлекает метки изображения с помощью Vision API и сохраняет их в выходной буфер.
  5. На третьем этапе Resizer , еще один сервис облачных функций, изменяет размер изображения с помощью ImageSharp и сохраняет измененное изображение в выходной буфер.
  6. На последнем этапе сервис облачных функций Watermarker добавляет к измененному размеру изображению водяной знак из меток, полученных с помощью Labeler, используя ImageSharp, и сохраняет изображение в выходной буфер.

Приложение запускается событием из облачного хранилища, поэтому оно является событийно-ориентированным. Обработка изображений происходит в рамках рабочего процесса, поэтому это оркестровка. В конечном итоге, это событийно-ориентированная оркестровка для гибкой, но структурированной бессерверной архитектуры для обработки изображений.

4. Создайте корзины.

Создайте входной сегмент для загрузки изображений пользователями и выходной сегмент для сохранения обработанных изображений в конвейере обработки изображений.

Выполните следующие действия в 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. Разверните службу фильтра.

Начнём с развертывания первого сервиса. Этот сервис Cloud Functions получает информацию о корзине и файле, определяет, является ли изображение безопасным, с помощью Vision API и возвращает результат.

Во-первых, включите необходимые сервисы для Cloud Functions gen2 и Vision API:

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

Внутри корневой папки processing-pipelines разверните службу:

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

После развертывания функции задайте URL-адрес сервиса в переменной, он понадобится нам позже:

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

6. Разверните службу маркировки.

Вторая служба Cloud Functions получает информацию о сегменте и файле, извлекает метки изображения с помощью Vision API и сохраняет метки в выходной сегмент.

Внутри корневой папки processing-pipelines разверните службу:

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

После развертывания функции задайте URL-адрес сервиса в переменной, он понадобится нам позже:

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

7. Разверните службу изменения размера.

Этот сервис Cloud Functions получает информацию о хранилище и файле, изменяет размер изображения с помощью ImageSharp и сохраняет изображение в выходное хранилище.

Внутри корневой папки processing-pipelines разверните службу:

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

Обратите внимание на значение timeout в 2 минуты, которое дает функции изменения размера дополнительное время для обработки.

После развертывания функции задайте URL-адрес сервиса в переменной, он понадобится нам позже:

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

8. Разверните службу водяных знаков.

Этот сервис Cloud Functions получает информацию о корзине, файле и метках, считывает файл, добавляет метки в качестве водяного знака к изображению с помощью ImageSharp и сохраняет изображение в выходную корзину.

Внутри корневой папки processing-pipelines разверните службу:

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

После развертывания функции задайте URL-адрес сервиса в переменной, он понадобится нам позже:

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

На данном этапе все четыре облачные функции должны быть развернуты и работать:

fe662925cb0121e9.png

9. Определите и разверните рабочий процесс.

Используйте рабочие процессы, чтобы объединить сервисы фильтрации, разметки, изменения размера и добавления водяных знаков в один рабочий процесс. Рабочие процессы будут организовывать вызов этих сервисов в том порядке и с параметрами, которые мы определим.

Во-первых, включите необходимые службы для рабочих процессов:

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

Определять

Workflows получает в качестве параметра объект CloudEvent. Этот объект будет получен из Eventarc после создания триггера. На первых двух шагах Workflows регистрирует событие и извлекает из него информацию о корзине и файле:

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}

На этапе filter Workflows обращается к службе фильтрации, развернутой ранее. Затем она регистрирует данные и проверяет безопасность файла:

  - 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

На этапе label Workflows обращается к службе добавления меток и получает ответ (три верхние метки):

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

На этапе resize Workflows обращается к службе изменения размера и получает ответ (корзину и файл изображения измененного размера):

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

На этапе watermark рабочие процессы вызывают службу нанесения водяных знаков, используя измененное изображение и метки, и получают результат (измененное изображение с водяным знаком):

  - 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

На final этапе Workflows возвращает код состояния HTTP от служб разметки, изменения размера и водяных знаков:

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

Развертывать

Перед развертыванием рабочего процесса убедитесь, что URL-адреса служб заменены URL-адресами развернутых функций либо вручную, либо с помощью sed :

Внутри корневой папки processing-pipelines перейдите в папку image-v3 , где находится файл workflows.yaml :

cd image-v3/

Запустите команду sed , чтобы заменить URL-адреса-заполнители фактическими URL-адресами развернутых служб:

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

Разверните рабочий процесс:

WORKFLOW_NAME=image-processing

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

Через несколько секунд вы увидите развернутый рабочий процесс в консоли:

a5f537f2b3f3bd3.png

10. Создайте триггер

Теперь, когда рабочий процесс развернут, последний шаг — подключить его к событиям Cloud Storage с помощью триггера Eventarc.

Одноразовая настройка

Сначала включите необходимые службы для Eventarc:

gcloud services enable \
 eventarc.googleapis.com

Создайте учетную запись службы, которую вы будете использовать в триггере Eventarc.

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

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

Предоставьте учетной записи службы роль workflows.invoker , чтобы она могла вызывать рабочие процессы из Eventarc:

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

Предоставьте учетной записи службы роль eventarc.eventReceiver , чтобы ее можно было использовать в

Триггер облачного хранилища:

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

Предоставьте учетной записи службы Cloud Storage роль pubsub.publisher . Это необходимо для работы триггера Cloud Storage в 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

Создавать

Выполните следующие действия, чтобы создать триггер. Этот триггер будет фильтровать события создания новых файлов из входного сегмента Cloud Storage и передавать их в рабочий процесс, который мы определили ранее:

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

В разделе Eventarc консоли Cloud Console вы можете убедиться, что триггер создан и готов к работе:

a5f4301863d7d9e4.png

11. Протестируйте конвейер.

Конвейер обработки изображений готов к приему событий из облачного хранилища. Для тестирования конвейера загрузите изображение во входной сегмент:

gsutil cp beach.jpg gs://$BUCKET1

Как только вы загрузите изображение, вы должны увидеть сообщение о выполнении рабочего процесса в активном состоянии:

2c914341950b5fde.png

Примерно через минуту вы увидите сообщение об успешном завершении выполнения. Также вы сможете увидеть входные и выходные данные рабочего процесса:

9abba6c28c51a9b5.png

Если вы выведете содержимое выходного хранилища, вы увидите уменьшенное изображение, уменьшенное изображение с водяным знаком и подписи к изображению:

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

Для перепроверки вы можете открыть уменьшенное изображение с водяным знаком, чтобы увидеть результат:

46d375cb05a8aae4.jpeg

12. Поздравляем!

Поздравляем, вы завершили практическое занятие!

Что мы рассмотрели

  • Обзор Eventarc и рабочих процессов.
  • Как развернуть сервисы Cloud Functions
  • Как организовать работу сервисов с помощью рабочих процессов.
  • Как настроить рабочие процессы на реагирование на события облачного хранилища с помощью Eventarc