Pic-a-daily: Лабораторная работа 5 — Очистка после удаления изображения

1. Обзор

В этой лабораторной работе с кодом вы создадите новую службу Cloud Run — сборщик мусора изображений, которая будет запускаться Eventarc — новой службой для получения событий в Cloud Run. Когда изображение удаляется из корзины изображений, служба получает событие от Eventarc. Затем он удаляет изображение из области миниатюр, а также из коллекции изображений Firestore.

d93345bfc235f81e.png

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

  • Облачный бег
  • Облачное хранилище
  • Облачный пожарный магазин
  • Эвентарк

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

Самостоятельная настройка среды

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

Запустить Cloud Shell

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

В консоли GCP щелкните значок Cloud Shell на верхней правой панели инструментов:

bce75f34b2c53987.png

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

f6ef2b5f13479f3a.png

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

3. Введение в Eventarc

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

776ed63706ca9683.png

Вы можете извлекать события из источников Google Cloud и пользовательских приложений, публикуя их в Cloud Pub/Sub, и доставлять их в приемники Google Cloud Run.

События из множества источников Google Cloud передаются посредством журналов облачного аудита. Задержка и доступность доставки событий из этих источников привязаны к журналам облачного аудита. При каждом возникновении события из источника Google Cloud создается соответствующая запись в журнале аудита облака.

Пользовательские приложения, публикующие в Cloud Pub/Sub, могут публиковать сообщения в указанной ими теме Pub/Sub в любом формате.

Триггеры событий — это механизм фильтрации, позволяющий указать, какие события в какой приемник доставлять.

Все события доставляются в формате CloudEvents v1.0 для обеспечения совместимости между сервисами.

4. Прежде чем начать

Включить API

Вам понадобится служба Eventarc для запуска службы Cloud Run. Убедитесь, что он включен:

gcloud services enable eventarc.googleapis.com

Вы должны увидеть успешное завершение операции:

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

Настройка учетных записей служб

Учетная запись службы вычислений по умолчанию будет использоваться в триггерах. Предоставьте роль eventarc.eventReceiver учетной записи службы вычислений по умолчанию:

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

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

Предоставьте роль pubsub.publisher учетной записи службы Cloud Storage. Это необходимо для триггера Eventarc Cloud Storage:

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

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

Если вы включили учетную запись службы Pub/Sub 8 апреля 2021 г. или ранее, предоставьте роль iam.serviceAccountTokenCreator учетной записи службы Pub/Sub:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

5. Клонируйте код

Клонируйте код, если вы еще этого не сделали в предыдущей лаборатории кода:

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

Затем вы можете перейти в каталог, содержащий службу:

cd serverless-photosharing-workshop/services/garbage-collector/nodejs

У вас будет следующий макет файла для сервиса:

services
 |
 ├── garbage-collector
      |
      ├── nodejs
           |
           ├── index.js
           ├── package.json

Внутри папки у вас есть 3 файла:

  • index.js содержит код Node.js.
  • package.json определяет зависимости библиотеки

6. Изучите код

Зависимости

Файл package.json определяет необходимые зависимости библиотеки:

{
  "name": "garbage_collector_service",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "cloudevents": "^4.0.1",
    "express": "^4.17.1",
    "@google/events": "^3.1.0",
    "@google-cloud/firestore": "^4.9.9",
    "@google-cloud/storage": "^5.8.3"
  }
}

Мы зависим от библиотеки Cloud Storage при удалении изображений в Cloud Storage. Мы объявляем зависимость от Cloud Firestore, чтобы также удалить метаданные изображений, которые мы сохранили ранее. Кроме того, мы зависим от CloudEvents SDK и библиотек Google Events для чтения CloudEvents, отправленных Eventarc. Express — это веб-фреймворк JavaScript/Node. Bluebird используется для обработки обещаний.

index.js

Давайте подробнее рассмотрим наш код index.js :

const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');

Нам требуются различные зависимости, необходимые для запуска нашей программы: Express — это веб-фреймворк Node, который мы будем использовать, Bluebird — это библиотека для обработки обещаний JavaScript, Storage и Firestore предназначены для работы соответственно с Google Cloud Storage (наши наборы изображений), и хранилище данных Cloud Firestore. Кроме того, мы требуем, чтобы CloudEvent прочитал CloudEvent, отправленный Eventarc StoreObjectData из библиотеки Google Events, чтобы прочитать тело события Cloud Storage CloudEvent.

const app = express();
app.use(express.json());

app.post('/', async (req, res) => {
    try {
        const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
        console.log(cloudEvent);


        /* ... */

    } catch (err) {
        console.log(`Error: ${err}`);
        res.status(500).send(err);
    }
});

Выше у нас есть структура нашего обработчика Node: наше приложение отвечает на запросы HTTP POST. Он считывает CloudEvent из HTTP-запроса, и мы немного обрабатываем ошибки на случай, если что-то пойдет не так. Давайте теперь посмотрим, что находится внутри этой структуры.

Следующий шаг — получить и проанализировать тело CloudEvent и получить имя объекта:

const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);

const objectName = storageObjectData.name;

Как только мы узнаем имя изображения, мы сможем удалить его из области миниатюр:

try {
    await storage.bucket(bucketThumbnails).file(objectName).delete();
    console.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}

В качестве последнего шага также удалите метаданные изображения из коллекции Firestore:

try {
    const pictureStore = new Firestore().collection('pictures');
    const docRef = pictureStore.doc(objectName);
    await docRef.delete();

    console.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}

res.status(200).send(`Processed '${objectName}'.`);

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

app.listen(PORT, () => {
    if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
    console.log(`Started service on port ${PORT}`);
});

7. Тестируйте локально

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

Внутри папки garbage-collector/nodejs установите зависимости npm и запустите сервер:

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

Если все прошло успешно, сервер должен запуститься на порту 8080:

Started service on port 8080

Используйте CTRL-C для выхода.

8. Сборка и развертывание в Cloud Run

Перед развертыванием в Cloud Run укажите в качестве региона Cloud Run один из поддерживаемых регионов и платформу для managed :

REGION=europe-west1
gcloud config set run/region $REGION
gcloud config set run/platform managed

Вы можете проверить, что конфигурация установлена:

gcloud config list

...
[run]
platform = managed
region = europe-west1

Вместо создания и публикации образа контейнера вручную с помощью Cloud Build вы также можете положиться на Cloud Run, который создаст образ контейнера за вас с помощью Google Cloud Buildpacks .

Выполните следующую команду, чтобы создать образ контейнера с помощью Google Cloud Buildpack , а затем разверните образ контейнера в Cloud Run:

SERVICE_NAME=garbage-collector-service

gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

Обратите внимание на флаг –-source . Это означает, что Cloud Run будет использовать пакеты Google Cloud Buildpacks для создания образа контейнера без Dockerfile. Флаг --no-allow-unauthenticated делает службу Cloud Run внутренней службой, которая будет запускаться только определенными учетными записями служб. Позже вы создадите триггер с учетной записью службы вычислений по умолчанию, которая имеет роль run.invoker для вызова внутренних служб Cloud Run.

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

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

Установите расположение триггера в том же регионе, что и сегмент загруженных изображений:

gcloud config set eventarc/location eu

Создайте триггер AuditLog для фильтрации событий storage.objects.delete и отправки в службу Cloud Run:

BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT

gcloud eventarc triggers create trigger-$SERVICE_NAME \
  --destination-run-service=$SERVICE_NAME \
  --destination-run-region=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.deleted" \
  --event-filters="bucket=$BUCKET_IMAGES" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

Вы можете дважды проверить, что триггер создан с помощью этой команды:

gcloud eventarc triggers list

10. Протестируйте сервис

Чтобы проверить, работает ли сервис, перейдите в корзину uploaded-pictures и удалите одно из изображений. В журналах службы вы должны увидеть, что она удалила соответствующее изображение в области thumbnails , а также удалила свой документ из коллекции pictures Firestore.

519abf90e7ea4d12.png

11. Очистка (необязательно)

Если вы не собираетесь продолжать другие лабораторные работы из этой серии, вы можете очистить ресурсы, чтобы сэкономить средства и стать в целом хорошим гражданином облака. Вы можете очистить ресурсы по отдельности следующим образом.

Удалить услугу:

gcloud run services delete $SERVICE_NAME -q

Удалите триггер Eventarc:

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

Альтернативно, вы можете удалить весь проект:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

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

Поздравляем! Вы создали службу Cloud Run, сборщик мусора изображений, которая запускается Eventarc — новой службой для получения событий в Cloud Run. Когда изображение удаляется из корзины изображений, служба получает событие от Eventarc. Затем он удаляет изображение из области миниатюр, а также из коллекции изображений Firestore.

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

  • Облачный бег
  • Облачное хранилище
  • Облачный пожарный магазин
  • Эвентарк