En este documento, se describe cómo implementar la arquitectura de referencia que se describe en Integra microservicios con Pub/Sub y GKE. La arquitectura está diseñada para manejar procesos de larga duración mediante contenedores y mensajería asíncrona.
En el documento, se usa una aplicación de uso compartido de fotos de ejemplo que genera miniaturas de fotos. Implementa la aplicación mediante Google Kubernetes Engine (GKE) y usa Pub/Sub para invocar procesos de larga duración de forma asíncrona. También puedes usar las notificaciones de Pub/Sub para Cloud Storage a fin de agregar trabajos complementarios sin modificar el código de la aplicación.
Cloud Build aloja la aplicación en contenedores y la almacena en Artifact Registry. Usa Cloud Vision para detectar imágenes inadecuadas.
Arquitectura
En el siguiente diagrama, se ilustra el diseño de la aplicación de álbum de fotos de ejemplo que implementa la arquitectura de referencia.
Figura 1. Arquitectura para el procesamiento de imágenes basada en el uso de contenedores y mensajería asíncrona.
En el diagrama anterior, se muestra cómo se genera la miniatura:
- Un cliente sube una imagen a la aplicación.
- La aplicación almacena la imagen en Cloud Storage.
- Se genera una solicitud para la miniatura.
- El generador de miniaturas genera la miniatura.
- La respuesta correcta se envía a la aplicación de álbum de fotos.
- La respuesta correcta se envía al cliente y puedes encontrar la miniatura en Cloud Storage.
En el siguiente diagrama, se muestra cómo la aplicación implementa la generación de miniaturas como un servicio independiente de manera asíncrona.
Figura 2. Arquitectura del proceso de extracción de miniaturas.
Usas Pub/Sub para enviar solicitudes al servicio de generación de miniaturas. Esta arquitectura nueva logra que la llamada de servicio sea asíncrona para que se cree una miniatura en segundo plano después de que la aplicación envía la respuesta a un cliente. Este diseño también permite que el servicio de generación de miniaturas se escale para que varios trabajos puedan ejecutarse en paralelo.
Objetivos
- Implementar una aplicación de álbum de fotos de ejemplo en GKE
- Realizar llamadas de servicio asíncronas desde la aplicación
- Usar las notificaciones de Pub/Sub para Cloud Storage a fin de activar la aplicación cuando se suba un archivo nuevo al bucket de Cloud Storage
- Usar Pub/Sub para realizar más tareas sin modificar la aplicación
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
- Cloud Storage
- Cloud SQL
- Pub/Sub
- Instancias de Compute Engine que usa GKE
- Tarifa de administración de clústeres para GKE
- Cloud Load Balancing
- Cloud Build
- Artifact Registry
- Vision
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando termines de compilar la aplicación de ejemplo, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
- Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Habilita las API de GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Habilita las API de GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Configure el entorno
En esta sección, dasignarás la configuración predeterminada para los valores que se usarán en todo el documento. Si cierras la sesión de Cloud Shell, perderás la configuración del entorno.
En Cloud Shell, establece tu proyecto de Google Cloud predeterminado:
gcloud config set project PROJECT_ID
Reemplaza
PROJECT_ID
por el ID del proyecto de Google Cloud.Configura la región de Compute Engine predeterminada:
gcloud config set compute/region REGION export REGION=REGION
Reemplaza
REGION
por una región cercana a ti. Para obtener más información, consulta Regiones y zonas.Configura la zona predeterminada de Compute Engine:
gcloud config set compute/zone ZONE export ZONE=ZONE
Reemplaza
ZONE
por una zona cercana a ti.Descarga los archivos de aplicación de ejemplo y configura el directorio actual:
git clone https://github.com/GoogleCloudPlatform/gke-photoalbum-example cd gke-photoalbum-example
Crea un bucket de Cloud Storage y sube la imagen en miniatura predeterminada
En Cloud Shell, crea un bucket de Cloud Storage para almacenar las imágenes y las miniaturas originales:
export PROJECT_ID=$(gcloud config get-value project) gsutil mb -c regional -l ${REGION} gs://${PROJECT_ID}-photostore
Sube el archivo de miniaturas predeterminado:
gsutil cp ./application/photoalbum/images/default.png \ gs://${PROJECT_ID}-photostore/thumbnails/default.png
- Las imágenes que se subieron se almacenan en el siguiente formato:
gs://PROJECT_ID-photostore/FILENAME
; en este caso,FILENAME
representa el nombre del archivo de imagen que se sube. - Las miniaturas generadas se almacenan en el siguiente formato:
gs://PROJECT_ID-photostore/thumbnails/FILENAME
. - La imagen original y la miniatura correspondiente tienen el mismo
FILENAME
, pero la miniatura se almacena en el bucketthumbnails
. Mientras se crea la miniatura, se muestra la siguiente imagen en miniatura del marcador de posición
default.png
en la aplicación de álbum de fotos.
- Las imágenes que se subieron se almacenan en el siguiente formato:
Haz público el archivo de miniatura:
gsutil acl ch -u AllUsers:R \ gs://${PROJECT_ID}-photostore/thumbnails/default.png
Crea una instancia de Cloud SQL y una base de datos de MySQL
En Cloud Shell, crea la instancia de Cloud SQL:
gcloud sql instances create photoalbum-db --region=${REGION} \ --database-version=MYSQL_8_0
Recupera el nombre de la conexión:
gcloud sql instances describe photoalbum-db \ --format="value(connectionName)"
Toma nota del nombre porque lo usarás más adelante.
Establece la contraseña para el usuario
root@%
de MySQL:gcloud sql users set-password root --host=% --instance=photoalbum-db \ --password=PASSWORD
Reemplaza
PASSWORD
por una contraseña segura para el usuarioroot@%
.Conéctate a la instancia de Cloud SQL:
gcloud sql connect photoalbum-db --user=root --quiet
Cuando se te solicite, ingresa la contraseña que configuraste en el paso anterior.
Crea una base de datos llamada
photo_db
, en la que el usuario seaappuser
y la contraseña seapas4appuser
:create database photo_db; create user 'appuser'@'%' identified by 'pas4appuser'; grant all on photo_db.* to 'appuser'@'%' with grant option; flush privileges;
Confirma el resultado y sal de MySQL:
show databases; select user from mysql.user; exit
En la salida, confirma que se hayan creado la base de datos
photo_db
y el usuarioappuser
:mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | photo_db | | sys | +--------------------+ 5 rows in set (0.16 sec) mysql> \t Outfile disabled. mysql> select user from mysql.user; +-------------------+ | user | +-------------------+ | appuser | | cloudsqlreplica | | cloudsqlsuperuser | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlapplier | | cloudsqlimport | | mysql.infoschema | | mysql.session | | mysql.sys | | root | +-------------------+ 18 rows in set (0.16 sec) mysql> exit Bye
Crea un tema y una suscripción de Pub/Sub
En Cloud Shell, crea un tema de Pub/Sub llamado
thumbnail-service
:gcloud pubsub topics create thumbnail-service
La aplicación de álbum de fotos envía solicitudes al servicio de generación de miniaturas mediante la publicación de un mensaje en el tema
thumbnail-service
.Crea una suscripción a Pub/Sub llamada
thumbnail-workers
:gcloud pubsub subscriptions create --topic thumbnail-service thumbnail-workers
El servicio de generación de miniaturas recibe solicitudes de la suscripción
thumbnail-workers
.
Crea un clúster de GKE
En Cloud Shell, crea un clúster de GKE que tenga permiso para llamar a las APIs:
gcloud container clusters create "photoalbum-cluster" \ --scopes "https://www.googleapis.com/auth/cloud-platform" \ --num-nodes "5"
Obtén credenciales de acceso configuradas para que puedas administrar el clúster con el comando
kubectl
en pasos posteriores:gcloud container clusters get-credentials photoalbum-cluster
Muestra la lista de nodos:
kubectl get nodes
En el resultado, confirma que haya cinco nodos cuyo valor
STATUS
seaReady
:NAME STATUS ROLES AGE VERSION gke-photoalbum-cluster-default-pool-d637570a-2pfh Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-3rm4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-f7l4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-qb2z Ready <none> 2m53s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-rvnp Ready <none> 2m54s v1.24.10-gke.2300
Crea el repositorio de Artifact Registry
En Cloud Shell, crea un repositorio para almacenar imágenes de contenedor:
gcloud artifacts repositories create photoalbum-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
Compila imágenes para la aplicación
En un editor de texto, abre el archivo
application/photoalbum/src/auth_decorator.py
y actualiza el nombre de usuario y la contraseña:USERNAME = 'username' PASSWORD = 'passw0rd'
En Cloud Shell, compila una imagen para la aplicación de álbum de fotos con el servicio de Cloud Build:
gcloud builds submit ./application/photoalbum -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app
Crea una imagen para el servicio de generación de miniaturas
thumbnail-worker
con el servicio de Cloud Build:gcloud builds submit ./application/thumbnail -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker
Implementa la aplicación de álbum de fotos
En Cloud Shell, actualiza los manifiestos de implementación de Kubernetes para el álbum de fotos y el generador de miniaturas con los valores de tu entorno:
connection_name=$(gcloud sql instances describe photoalbum-db \ --format "value(connectionName)") digest_photoalbum=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_photoalbum}/" \ config/photoalbum-deployment.yaml digest_thumbnail=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_thumbnail}/" \ config/thumbnail-deployment.yaml
Crea recursos de implementación para iniciar la aplicación de álbum de fotos y el servicio de generación de miniaturas:
kubectl create -f config/photoalbum-deployment.yaml kubectl create -f config/thumbnail-deployment.yaml
Crea un recurso de servicio para asignar una dirección IP externa a la aplicación:
kubectl create -f config/photoalbum-service.yaml
Verifica los resultados de los pods:
kubectl get pods
En el resultado, confirma que haya tres pods para cada pod de
photoalbum-app
ythumbail-worker
, y que su valor deSTATUS
seaRunning
:NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 2m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 2m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 0 2m thumbnail-worker-86bd95cd68-728k5 2/2 Running 0 2m thumbnail-worker-86bd95cd68-hqxqr 2/2 Running 0 2m thumbnail-worker-86bd95cd68-xnxhc 2/2 Running 0 2m
Los pods
thumbnail-worker
suscriben solicitudes de generación de miniaturas de la suscripciónthumbnail-workers
. Para obtener más información, consulta cómo se usa la funcióncallback
en el código fuente.Verifica los resultados de los servicios:
kubectl get services
En el resultado, confirma que haya una dirección IP externa en la columna
EXTERNAL-IP
del serviciophotoalbum-service
. Es posible que tome unos minutos en ejecutarse.NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 20m photoalbum-service LoadBalancer 10.23.253.241 146.148.111.115 80:32657/TCP 2m
Toma nota de la dirección IP externa, ya que se usará más adelante. En este ejemplo, es
146.148.111.115
.
Prueba la aplicación de álbum de fotos
Para acceder a la aplicación implementada en un navegador web, ve a la siguiente URL y, luego, ingresa el nombre de usuario y la contraseña que configuraste antes:
http://EXTERNAL_IP
Reemplaza
EXTERNAL_IP
por la dirección IP que copiaste en el paso anterior.Para subir un archivo de imagen, haz clic en Subir.
El marcador de posición de la miniatura aparecerá en la pantalla.
En segundo plano, el servicio de generación de miniaturas crea una miniatura de la imagen subida. Para ver la miniatura generada, haz clic en Refresh (Actualizar). La API de Cloud Vision agrega etiquetas de imagen que detecta.
Para ver la imagen original, haz clic en la miniatura.
Agrega una función de detección de imágenes inadecuadas
En la siguiente imagen, se muestra cómo puedes usar las notificaciones de Pub/Sub para Cloud Storage a fin de activar un servicio que detecte contenido inadecuado. Esta función desenfoca la imagen cuando se almacena un archivo nuevo con contenido inadecuado en el bucket de Cloud Storage.
En la imagen anterior, el servicio usa la función de detección de SafeSearch de la API de Vision para detectar contenido inadecuado en una imagen.
La aplicación de fotos activa el generador de miniaturas y el verificador de imágenes de forma asíncrona. Como resultado, no hay garantía de que se ejecuten en un orden específico. Si la generación de miniaturas ocurre antes de que se difumine la imagen, es posible que veas una miniatura inapropiada durante un tiempo breve. Sin embargo, el verificador de imágenes finalmente difumina la imagen inadecuada y la miniatura inadecuada.
Crea un tema, una suscripción y una notificación de Pub/Sub
En Cloud Shell, crea un tema de Pub/Sub llamado
safeimage-service
:gcloud pubsub topics create safeimage-service
Crea una suscripción a Pub/Sub llamada
safeimage-workers
:gcloud pubsub subscriptions create --topic safeimage-service \ safeimage-workers
Configura una notificación de Pub/Sub para que se envíe un mensaje al tema
safeimage-service
cuando se suba un archivo nuevo al depósito de Cloud Storage:gsutil notification create -t safeimage-service -f json \ gs://${PROJECT_ID}-photostore
Compila e implementa la imagen del trabajador
En Cloud Shell, compila una imagen de contenedor para la suscripción
safeimage-workers
con Cloud Build:gcloud builds submit ./application/safeimage \ -t us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker
Actualiza los manifiestos de implementación de Kubernetes para el servicio de imagen segura con tu ID del proyecto de Google Cloud, el nombre de la conexión de Cloud SQL y los resúmenes de imágenes de contenedor:
digest_safeimage=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_safeimage}/" \ config/safeimage-deployment.yaml
Crea un recurso de implementación
Crea un recurso de implementación llamado
safeimage-deployment
para implementar el temasafeimage-service
:kubectl create -f config/safeimage-deployment.yaml
Verifica los resultados:
kubectl get pods
En el resultado, confirma que haya tres pods
safeimage-worker
cuyo valorSTATUS
seaRunning
.NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 30m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 30m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 8 30m safeimage-worker-7dc8c84f54-6sqzs 1/1 Running 0 2m safeimage-worker-7dc8c84f54-9bskw 1/1 Running 0 2m safeimage-worker-7dc8c84f54-b7gtp 1/1 Running 0 2m thumbnail-worker-86bd95cd68-9wrpv 2/2 Running 0 30m thumbnail-worker-86bd95cd68-kbhsn 2/2 Running 2 30m thumbnail-worker-86bd95cd68-n4rj7 2/2 Running 0 30m
Los pods
safeimage-worker
se suscriben a solicitudes de detección de imágenes inapropiadas de la suscripciónsafeimage-workers
. Para obtener más información, consulta cómo se usa la funcióncallback
en el código fuente.
Prueba la función de detección de imágenes inadecuada
En esta sección, subirás una imagen de prueba para verificar que la función de detección de SafeSearch desenfoque una imagen inadecuada. La imagen de prueba es de una niña vestida de zombi (con licencia de CC0 de Pixaby).
- Descarga la imagen de prueba.
- Para subir la imagen, ve a
http://EXTERNAL_IP
y haz clic en Upload (Subir). Haz clic en Actualizar. La aplicación muestra una miniatura difuminada.
Para ver que la imagen subida también está desenfocada, haz clic en la miniatura.
Limpia
Si no deseas conservar los recursos de Google Cloud que creaste para la aplicación de ejemplo, puedes quitarlos a fin de que no se te facture por ellos en el futuro. Puedes borrar el proyecto por completo o borrar los recursos del clúster y, luego, borrar el clúster.
Borra el proyecto
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
Borra los recursos individuales
En lugar de borrar el proyecto, puedes borrar los recursos individuales que creaste.
Borra recursos de GKE:
kubectl delete -f config/safeimage-deployment.yaml kubectl delete -f config/photoalbum-service.yaml kubectl delete -f config/thumbnail-deployment.yaml kubectl delete -f config/photoalbum-deployment.yaml
Borra el clúster de GKE:
gcloud container clusters delete photoalbum-cluster --quiet
Borra el repositorio de Artifact Registry:
gcloud artifacts repositories delete photoalbum-repo --location us-central1 --quiet
Borra suscripciones y temas de Pub/Sub:
gcloud pubsub subscriptions delete safeimage-workers gcloud pubsub topics delete safeimage-service gcloud pubsub subscriptions delete thumbnail-workers gcloud pubsub topics delete thumbnail-service
Borra la instancia de Cloud SQL:
gcloud sql instances delete photoalbum-db --quiet
Borra el bucket de Cloud Storage:
gsutil rm -r gs://${PROJECT_ID}-photostore gsutil rm -r gs://${PROJECT_ID}_cloudbuild
Borra los archivos:
cd .. rm -rf gke-photoalbum-example
¿Qué sigue?
- Lee sobre DevOps y obtén más información sobre la capacidad de la Arquitectura relacionada con esta arquitectura de referencia.
- Realiza la verificación rápida de DevOps para comprender cuál es tu posición en comparación con el resto de la industria.
- Para obtener más información sobre las arquitecturas de referencia, los diagramas y las prácticas recomendadas, explora Cloud Architecture Center.