Acerca de este codelab
1. Descripción general
En este codelab, crearás un nuevo servicio de Cloud Run, un recolector de elementos no utilizados de imagen, que se activará con Eventarc, un servicio nuevo para recibir eventos en Cloud Run. Cuando se borra una foto del bucket de imágenes, el servicio recibe un evento de Eventarc. Luego, borra la imagen del bucket de miniaturas y también la quita de la colección de fotos de Firestore.
Qué aprenderás
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc
2. Configuración y requisitos
Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.
- 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, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser
PROJECT_ID
). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar. - Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás 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 se te facture más allá 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 Prueba gratuita de USD 300.
Inicia Cloud Shell
Si bien Google Cloud y Spanner se pueden operar de manera 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 GCP Console, haga clic en el ícono de Cloud Shell en la barra de herramientas superior derecha:
El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:
Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Puedes realizar todo tu trabajo en este lab usando simplemente un navegador.
3. Introducción a Eventarc
Eventarc facilita la conexión de los servicios de Cloud Run con eventos de una variedad de fuentes. Se encarga de la transferencia de eventos, la entrega, la seguridad, la autorización y el manejo de errores por ti.
Puedes extraer eventos de fuentes de Google Cloud y aplicaciones personalizadas que publican en Cloud Pub/Sub y entregarlos a receptores de Google Cloud Run.
Los eventos de una gran variedad de fuentes de Google Cloud se entregan a través de Registros de auditoría de Cloud. La latencia y la disponibilidad de la entrega de eventos de estas fuentes están vinculadas a las de los Registros de auditoría de Cloud. Cada vez que se activa un evento de una fuente de Google Cloud, se crea la entrada correspondiente de los Registros de auditoría de Cloud.
Las aplicaciones personalizadas que publican en Cloud Pub/Sub pueden publicar mensajes en un tema de Pub/Sub que especifiquen en cualquier formato.
Los activadores de eventos son el mecanismo de filtrado para especificar qué eventos entregar a qué receptor.
Todos los eventos se entregan en el formato CloudEvents v1.0 para la interoperabilidad entre servicios.
4. Antes de comenzar
Habilita las APIs
Necesitarás el servicio de Eventarc para activar el servicio de Cloud Run. Asegúrate de que esté habilitada:
gcloud services enable eventarc.googleapis.com
Deberías ver que la operación finaliza correctamente:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
Configurar cuentas de servicio
La cuenta de servicio de procesamiento predeterminada se usará en los activadores. Otorga el rol eventarc.eventReceiver
a la cuenta de servicio de procesamiento predeterminada:
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
Otorga el rol 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
Si habilitaste la cuenta de servicio de Pub/Sub el 8 de abril de 2021 o antes de esa fecha, otorga el rol iam.serviceAccountTokenCreator
a la cuenta de servicio de 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. Clona el código
Clona el código, si aún no lo hiciste en el codelab anterior:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
Luego, puedes ir al directorio que contiene el servicio:
cd serverless-photosharing-workshop/services/garbage-collector/nodejs
Tendrás el siguiente diseño de archivo para el servicio:
services | ├── garbage-collector | ├── nodejs | ├── index.js ├── package.json
Dentro de la carpeta, tienes 3 archivos:
index.js
contiene el código de Node.js.package.json
define las dependencias de la biblioteca.
6. Cómo explorar el código
Dependencias
El archivo package.json
define las dependencias de biblioteca necesarias:
{
"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"
}
}
Dependemos de la biblioteca de Cloud Storage para borrar imágenes en Cloud Storage. Declaramos una dependencia en Cloud Firestore para borrar también los metadatos de fotos que almacenamos anteriormente. Además, dependemos del SDK de CloudEvents y las bibliotecas de Eventos de Google para leer los CloudEvents que envía Eventarc. Express es un framework web de JavaScript / Node. Bluebird se usa para administrar promesas.
index.js
Analicemos con más detalle nuestro código 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');
Exigimos las diversas dependencias necesarias para que nuestro programa se ejecute: Express es el framework web de Node que usaremos, Bluebird es una biblioteca para manejar promesas de JavaScript, Storage y Firestore se usan para trabajar respectivamente con Google Cloud Storage (nuestros buckets de imágenes) y el almacén de datos de Cloud Firestore. Además, es necesario que CloudEvent lea el CloudEvent que envió Eventarc StoreObjectData desde la biblioteca de Google Events para leer el cuerpo del evento de Cloud Storage del 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);
}
});
Arriba, tenemos la estructura de nuestro controlador de Node: nuestra app responde a las solicitudes HTTP POST. Lee el CloudEvent de la solicitud HTTP y realizamos un poco de manejo de errores en caso de que algo salga mal. Ahora, veamos qué contiene esta estructura.
El siguiente paso es recuperar y analizar el cuerpo de CloudEvent y recuperar el nombre del objeto:
const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);
const objectName = storageObjectData.name;
Una vez que sabemos el nombre de la imagen, podemos borrarla del bucket de miniaturas:
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}.`);
}
Como último paso, borra también los metadatos de las fotos de la colección de 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}'.`);
Ahora, es momento de hacer que nuestra secuencia de comandos de Node escuche las solicitudes entrantes. Además, verifica que estén configuradas las variables de entorno necesarias:
app.listen(PORT, () => {
if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
console.log(`Started service on port ${PORT}`);
});
7. Realiza pruebas locales
Prueba el código de forma local para asegurarte de que funciona antes de implementarlo en la nube.
En la carpeta garbage-collector/nodejs
, instala las dependencias de npm y, luego, inicia el servidor:
export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT npm install; npm start
Si todo salió bien, debería iniciar el servidor en el puerto 8080:
Started service on port 8080
Usa CTRL-C
para salir.
8. Compila e implementa en Cloud Run
Antes de realizar implementaciones en Cloud Run, configura la región de Cloud Run en una de las regiones y la plataforma compatibles en managed
:
REGION=europe-west1 gcloud config set run/region $REGION gcloud config set run/platform managed
Puedes verificar que la configuración esté establecida:
gcloud config list ... [run] platform = managed region = europe-west1
En lugar de compilar y publicar la imagen de contenedor con Cloud Build de forma manual, también puedes confiar en que Cloud Run compilará la imagen de contenedor por ti con Google Cloud Buildpacks.
Ejecuta el siguiente comando para compilar la imagen de contenedor con los Google Cloud Buildpacks y, luego, impleméntala en Cloud Run:
SERVICE_NAME=garbage-collector-service gcloud run deploy $SERVICE_NAME \ --source . \ --no-allow-unauthenticated \ --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
Observa la marca –-source
. Esto indica que Cloud Run use paquetes de Google Cloud Build para compilar la imagen de contenedor sin un Dockerfile.
. La marca --no-allow-unauthenticated
hace que el servicio de Cloud Run sea un servicio interno que solo se activará mediante cuentas de servicio específicas. Más adelante, crearás un activador con la cuenta de servicio de procesamiento predeterminada que tiene el rol run.invoker
para llamar a los servicios internos de Cloud Run.
9. Crea un activador
En Eventarc, un activador define qué servicio debería obtener el tipo de eventos. En este caso, quieres que el servicio reciba eventos cuando se borre un archivo de un bucket.
Establece la ubicación del activador en la misma región que el bucket de imágenes subidas:
gcloud config set eventarc/location eu
Crea un activador AuditLog para filtrar los eventos storage.objects.delete
y enviarlos al servicio de 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
Puedes verificar que el activador se cree con este comando:
gcloud eventarc triggers list
10. Prueba el servicio
Para probar si funciona el servicio, ve al bucket uploaded-pictures
y borra una de las fotos. En los registros del servicio, deberías ver que borró la foto relevante del bucket thumbnails
y el documento de la colección pictures
de Firestore.
11. Limpieza (opcional)
Si no pretendes continuar con los otros labs de la serie, puedes liberar recursos para ahorrar costos y ser un buen ciudadano de la nube en general. Puedes limpiar los recursos de forma individual de la siguiente manera.
Borra el servicio:
gcloud run services delete $SERVICE_NAME -q
Borrar el activador de Eventarc:
gcloud eventarc triggers delete trigger-$SERVICE_NAME -q
También puedes borrar todo el proyecto:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
12. ¡Felicitaciones!
¡Felicitaciones! Creaste un servicio de Cloud Run, recolector de elementos no utilizados de imagen, que se activa mediante Eventarc, un servicio nuevo para recibir eventos en Cloud Run. Cuando se borra una foto del bucket de imágenes, el servicio recibe un evento de Eventarc. Luego, borra la imagen del bucket de miniaturas y también la quita de la colección de fotos de Firestore.
Temas abordados
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc