Zdjęcia codziennie: moduł 5 – czyszczenie po usunięciu obrazu

1. Przegląd

W tym module utworzysz nową usługę Cloud Run, czyli odśmiecacz obrazów, która będzie aktywowana przez Eventarc, nową usługę do odbierania zdarzeń w Cloud Run. Gdy obraz zostanie usunięty z zasobnika na zdjęcia, usługa otrzyma zdarzenie z Eventarc. Następnie usuwa obraz z zasobnika miniatur i z kolekcji zdjęć Firestore.

d93345bfc235f81e.png

Czego się nauczysz

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Możesz go w dowolnym momencie zaktualizować.
  • Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i jest niezmienny (nie można go zmienić po ustawieniu). Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości modułów z kodem musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako PROJECT_ID). Jeśli Ci się nie podoba, wygeneruj inny losowy identyfikator lub spróbuj użyć własnego i sprawdź, czy jest dostępny. Po utworzeniu projektu jest on „zamrażany”.
  • Istnieje też trzecia wartość, czyli numer projektu, którego używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Aby wyłączyć zasoby i uniknąć naliczenia opłat po zakończeniu tego samouczka, postępuj zgodnie z instrukcjami „czyszczenia” na końcu ćwiczenia. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Uruchamianie Cloud Shell

Z Google Cloud można korzystać zdalnie na laptopie, ale w tym module praktycznym będziesz używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.

W konsoli GCP kliknij ikonę Cloud Shell na pasku narzędzi w prawym górnym rogu:

bce75f34b2c53987.png

Uzyskanie dostępu do środowiska i połączenie się z nim powinno zająć tylko kilka chwil. Po zakończeniu powinno wyświetlić się coś takiego:

f6ef2b5f13479f3a.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Wszystkie zadania w tym module możesz wykonać w przeglądarce.

3. Wprowadzenie do Eventarc

Eventarc ułatwia łączenie usług Cloud Run ze zdarzeniami z różnych źródeł. Zajmuje się pozyskiwaniem, dostarczaniem, zabezpieczaniem, autoryzacją i obsługą błędów.

776ed63706ca9683.png

Możesz pobierać zdarzenia ze źródeł Google Cloud i aplikacji niestandardowych publikujących w Cloud Pub/Sub i dostarczać je do miejsc docelowych Google Cloud Run.

Zdarzenia z wielu źródeł Google Cloud są dostarczane za pomocą logów kontrolnych Cloud. Opóźnienie i dostępność dostarczania zdarzeń z tych źródeł są powiązane z opóźnieniem i dostępnością logów kontrolnych Cloud. Za każdym razem, gdy zostanie wywołane zdarzenie ze źródła Google Cloud, tworzony jest odpowiedni wpis logu kontrolnego Cloud.

Aplikacje niestandardowe publikujące w Cloud Pub/Sub mogą publikować wiadomości w temacie Pub/Sub w dowolnym formacie.

Wywołania zdarzeń to mechanizm filtrowania, który określa, które zdarzenia mają być dostarczane do którego ujścia.

Wszystkie zdarzenia są dostarczane w formacie CloudEvents v1.0, co zapewnia interoperacyjność między usługami.

4. Zanim zaczniesz

Włącz interfejsy API

Aby wywołać usługę Cloud Run, musisz mieć usługę Eventarc. Sprawdź, czy jest włączona:

gcloud services enable eventarc.googleapis.com

Operacja powinna zakończyć się powodzeniem:

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

Skonfiguruj konta usługi

W aktywatorach będzie używane domyślne konto usługi Compute. Przypisz rolę eventarc.eventReceiver do domyślnego konta usługi obliczeniowej:

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

Przypisz rolę pubsub.publisher do konta usługi Cloud Storage. Jest to wymagane w przypadku aktywatora 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

Jeśli konto usługi Pub/Sub zostało włączone 8 kwietnia 2021 r. lub wcześniej, przypisz rolę iam.serviceAccountTokenCreator do konta usługi 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. Klonowanie kodu

Sklonuj kod, jeśli nie masz go jeszcze z poprzedniego modułu:

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

Następnie możesz przejść do katalogu zawierającego usługę:

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

Usługa będzie miała ten układ pliku:

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

W folderze znajdują się 3 pliki:

  • index.js zawiera kod Node.js.
  • package.json określa zależności biblioteki.

6. Poznaj kod

Zależności

Plik package.json określa wymagane zależności biblioteki:

{
  "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"
  }
}

Do usuwania obrazów w Cloud Storage używamy biblioteki Cloud Storage. Deklarujemy zależność od Cloud Firestore, aby usunąć również metadane obrazu, które wcześniej zapisaliśmy. Korzystamy też z pakietu SDK CloudEvents i bibliotek zdarzeń Google, aby odczytywać zdarzenia CloudEvents wysyłane przez Eventarc. Express to platforma internetowa JavaScript / Node. Biblioteka Bluebird służy do obsługi obietnic.

index.js

Przyjrzyjmy się bliżej naszemu index.js kodowi:

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');

Wymagamy różnych zależności potrzebnych do działania naszego programu: Express to platforma internetowa Node, której będziemy używać, Bluebird to biblioteka do obsługi obietnic JavaScript, Storage i Firestore służą odpowiednio do pracy z Google Cloud Storage (naszymi zasobnikami obrazów) i magazynem danych Cloud Firestore. Dodatkowo wymagamy, aby CloudEvent odczytywał CloudEvent wysłany przez Eventarc StoreObjectData z biblioteki zdarzeń Google, aby odczytać treść zdarzenia Cloud Storage w 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);
    }
});

Powyżej znajduje się struktura naszego modułu obsługi Node.js: aplikacja odpowiada na żądania HTTP POST. Odczytuje ona CloudEvent z żądania HTTP i obsługuje błędy, które mogą wystąpić. Przyjrzyjmy się teraz, co znajduje się w środku tej konstrukcji.

Następnym krokiem jest pobranie i przeanalizowanie treści CloudEvent oraz pobranie nazwy obiektu:

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

const objectName = storageObjectData.name;

Gdy poznamy nazwę obrazu, możemy go usunąć z zasobnika miniatur:

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}.`);
}

Na koniec usuń metadane obrazu z kolekcji 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}'.`);

Teraz czas, aby skrypt Node nasłuchiwał przychodzących żądań. Sprawdź też, czy zostały ustawione wymagane zmienne środowiskowe:

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

7. Testowanie lokalne

Przetestuj kod lokalnie, aby sprawdzić, czy działa, zanim wdrożysz go w chmurze.

W folderze garbage-collector/nodejs zainstaluj zależności npm i uruchom serwer:

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

Jeśli wszystko przebiegło pomyślnie, serwer powinien zostać uruchomiony na porcie 8080:

Started service on port 8080

Aby wyjść, użyj CTRL-C.

8. Kompilowanie i wdrażanie w Cloud Run

Przed wdrożeniem w Cloud Run ustaw region Cloud Run na jeden z obsługiwanych regionów, a platformę na managed:

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

Możesz sprawdzić, czy konfiguracja jest ustawiona:

gcloud config list

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

Zamiast ręcznie tworzyć i publikować obraz kontenera za pomocą Cloud Build, możesz też polegać na Cloud Run, który utworzy obraz kontenera za pomocą pakietów kompilacji Google Cloud.

Uruchom to polecenie, aby utworzyć obraz kontenera za pomocą pakietów kompilacji Google Cloud, a następnie wdrożyć go w Cloud Run:

SERVICE_NAME=garbage-collector-service

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

Zwróć uwagę na flagę –-source. Oznacza to, że Cloud Run ma używać pakietów kompilacji Google Cloud do tworzenia obrazu kontenera bez pliku Dockerfile.. Flaga --no-allow-unauthenticated sprawia, że usługa Cloud Run jest usługą wewnętrzną, która będzie wywoływana tylko przez określone konta usługi. Później utworzysz aktywator z domyślnym kontem usługi Compute, które ma rolę run.invoker do wywoływania wewnętrznych usług Cloud Run.

9. Tworzenie aktywatora

W Eventarc aktywator określa, która usługa powinna otrzymywać zdarzenia określonego typu. W tym przypadku chcesz, aby usługa otrzymywała zdarzenia, gdy plik zostanie usunięty z zasobnika.

Ustaw lokalizację aktywatora w tym samym regionie co zasobnik przesłanych zdjęć:

gcloud config set eventarc/location eu

Utwórz aktywator AuditLog, aby filtrować zdarzenia storage.objects.delete i wysyłać je do usługi 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

Możesz sprawdzić, czy aktywator został utworzony, za pomocą tego polecenia:

gcloud eventarc triggers list

10. Testowanie usługi

Aby sprawdzić, czy usługa działa, otwórz kosz uploaded-pictures i usuń jedno ze zdjęć. W logach usługi powinna pojawić się informacja o usunięciu odpowiedniego zdjęcia z zasobnika thumbnails oraz usunięciu dokumentu z kolekcji pictures Firestore.

519abf90e7ea4d12.png

11. Zwalnianie miejsca (opcjonalnie)

Jeśli nie zamierzasz kontynuować pracy z innymi ćwiczeniami z tej serii, możesz usunąć zasoby, aby zaoszczędzić pieniądze i być dobrym użytkownikiem chmury. Możesz zwolnić miejsce, czyszcząc poszczególne zasoby w ten sposób:

Usuń usługę:

gcloud run services delete $SERVICE_NAME -q

Usuń aktywator Eventarc:

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

Możesz też usunąć cały projekt:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

12. Gratulacje!

Gratulacje! Utworzono usługę Cloud Run, moduł odśmiecania obrazów, która jest aktywowana przez Eventarc, nową usługę do odbierania zdarzeń w Cloud Run. Gdy obraz zostanie usunięty z zasobnika na zdjęcia, usługa otrzyma zdarzenie z Eventarc. Następnie usuwa obraz z zasobnika miniatur i z kolekcji zdjęć Firestore.

Omówione zagadnienia

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc