Repository navigation
Releases: Dagyss/SD-Kubernetes-RabbitMQ
Release list
Hit #3
Sobel contenerizado asincrónico y escalable
Infraestructura Kubernetes en GKE
- Cluster principal: Desplegado con Terraform, maneja todos los recursos del sistema.
- Nodegroup Infraestructura: Aloja servicios críticos:
- RabbitMQ: Sistema de colas para coordinar split y joiner.
- Redis: Almacenamiento de estado y control de locks para tareas asíncronas.
- Nodegroup Aplicaciones: Aloja componentes de la aplicación:
- API REST para recepción de imágenes y estado, que divide la imagen en segmentos.
- Servicio reconstructor que recombina los segmentos en la imagen final.
- Máquinas Virtuales Externas: Provisionadas fuera del cluster:
- Instancias gestionadas por Terraform con autoscaling.
- Ejecutan los workers que aplican el filtro Sobel de forma asíncrona.
Pipelines de despliegue (GitHub Actions)
- Pipeline: Infraestructura Kubernetes
terraform init,plan,applypara crear el cluster y los nodegroups.- Despliegue de RabbitMQ y Redis vía manifiestos Kubernetes.
- kubectl apply de Deployment y Services.
- Creación de instancias con
user_datapara instalar Docker y lanzar el worker.
Flujo de ejecución y testeo
- Push al repositorio
- Desencadena los GitHub Actions de los pipelines configurados.
- Verificación de despliegue
- Comprobar el estado y logs en la sección Actions de GitHub.
- Prueba de la API REST
- Obtener la IP del servicio maestro:
kubectl get svc master -n apps -o jsonpath='{.status.loadBalancer.ingress[0].ip}' - Ejecutar:
- POST
/processAndPublish(form-data:imageypartes). - GET
/task/status/{id}. - GET
/task/images/{id}.
- POST
- Obtener la IP del servicio maestro:
Hit #2
Arquitectura de Despliegue
En esta implementación completamente en la nube usamos un único clúster GKE con dos node pools para separar:
- Control: servicios críticos que siempre deben estar activos.
- Cómputo masivo: workers Sobel que escalan según demanda.
| Servicio | Node Pool | Rol & Ubicación | Función principal |
|---|---|---|---|
| Master | base (1–2 nodos) | Eureka Server @ GKE (us-central1-a) | Divide la imagen en N partes y publica cada fragmento (bytes + metadata) en la cola “sobel-task”. |
| Workers Sobel | workers (0–5 nodos) | GKE (us-central1-a, taints “worker”) | Consumen “sobel-task”, aplican el filtro Sobel, suben el fragmento procesado a GCS y publican un mensaje en “sobel-metadata”. |
| Reconstructor | base (1–2 nodos) | Eureka Client @ GKE (us-central1-a) | Escucha “sobel-metadata”, registra el estado en Redis y, al recibir todos los fragmentos, descarga desde GCS y une la imagen final. |
| RabbitMQ (sobel-task / sobel-metadata) | base (1–2 nodos) | GKE (us-central1-a) | Cola de tareas: Master → Workers / Cola de estado: Workers → Reconstructor |
| Redis | base (1–2 nodos) | GKE (us-central1-a) | Guarda el progreso y recuento de fragmentos procesados |
| GCS Bucket | — | Google Cloud Storage | Almacenamiento duradero de fragmentos y de la imagen final |
Decisiones clave
-
Eureka para descubrimiento
- El Master expone un Eureka Server para que clientes (Reconstructor) descubran dinámicamente su endpoint.
- El Reconstructor actúa como Eureka Client, facilitando desacoplo y futura replicación horizontal.
-
Doble cola RabbitMQ
- sobel-task: Master envía fragmentos + metadata a los workers.
- sobel-metadata: comunica al reconstructor el estado/progreso de cada fragmento para coordinar el ensamblado.
-
Control de estado en Redis
- El Reconstructor lleva control de cada solicitud. Cuando todos los fragmentos están procesados, inicia la descarga de cada parte desde GCS y ensambla la imagen final.
-
Node pools especializados
- base (1–2 nodos): servicios permanentes + mensajería + caché.
- workers (0–5 nodos): procesamiento Sobel bajo demanda (autoscaling).
-
Almacenamiento desacoplado
- Google Cloud Storage ofrece durabilidad y aisla cargas de I/O del clúster de cómputo.
-
Infraestructura declarativa con Terraform
- Cluster, node pools y bucket se versionan y reproducen fácilmente.
Este diseño garantiza un flujo claro Master→Workers→Reconstructor, con control de estado en Redis y almacenamiento duradero en GCS, optimizando disponibilidad, escalabilidad y coste en GKE.
Flujo de ejecución para testeo
- Ingresar al directorio de Terraform:
cd terraform - Agregar credenciales:
cp path/to/terraform-sa-keys.json . - Inicializar Terraform:
terraform init
- Planificar la infraestructura:
terraform plan -out plan.tfplan
- Aplicar el plan:
terraform apply "plan.tfplan" - Configurar kubectl:
gcloud container clusters get-credentials gke-cluster
- Desplegar manifiestos de Kubernetes:
kubectl apply -f k8s-manifests/
- Verificar el servicio maestro:
kubectl get svc master # Obtener la IP pública del master - Consumir la API REST desde Postman o
curl:
| Endpoint | Método | Parámetros | Respuesta |
|---|---|---|---|
POST /task/processAndPublish |
POST | • Request param: partes (int) • Form-data: image (file) |
• id • message • links.statusUrl • links.imageUrl |
GET /task/status/{id} |
GET | • Path param: id |
• id • status |
GET /task/images/{id} |
GET | • Path param: id |
• Binary (imagen procesada) |
Ejemplo curl
curl "http://{{IP_ASIGNADA}}:8761/task/processAndPublish?partes=2" \
--form "image=@/ruta/a/imagen.jpg" curl "http://{{IP_ASIGNADA}}:8761/task/status/{id-imagen}" curl "http://{{IP_ASIGNADA}}:8761/task/images/{id-imagen}"Hit #1
Operador de Sobel
Se implementó un servicio que divide la imagen en N segmentos según el parámetro partes. Cada segmento se envía en paralelo a diferentes workers (a través de RabbitMQ), donde cada worker aplica el filtro de Sobel de forma concurrente. Una vez procesados, el maestro unifica los segmentos respetando su posición original y genera la imagen final resultante.
Flujo de ejecución para testeo
-
Descargar el source code del hit 1:
-
Construir el proyecto Maven sin ejecutar tests:
cd master mvn clean package -Dskiptests cd ..
-
Iniciar los contenedores Docker:
docker-compose up --scale worker=<cantidad de workers a levantar>
-
Esperar a que los workers esten listos.
-
Enviar la imagen a procesar (por ejemplo, con Postman):
- Método: POST a
http://localhost:8080/task/processAndPublish - Parámetro
partes: número de segmentos en que dividir la imagen - Body:
form-datacon:- Key:
image(archivo de imagen a procesar)
- Key:
- Método: POST a
-
La imagen aparece con el filtro sobel aplicado dentro de ./output
Comparativa de Rendimiento Sobel
| Tamaño Imagen | Workers | Partes | Publicado en Cola | Fin Proceso | Tiempo Total |
|---|---|---|---|---|---|
| 3 MB | 1 | 9 | 16:05:16 | 16:05:19 | 3 seg |
| 15 MB | 1 | 9 | 15:42:59 | 15:43:06 | 7 seg |
| 30 MB | 1 | 9 | 16:07:21 | 16:07:28 | 7 seg |
| 3 MB | 9 | 9 | 16:01:45 | 16:01:46 | 1 seg |
| 15 MB | 9 | 9 | 15:57:33 | 15:57:42 | 9 seg |
| 30 MB | 9 | 9 | 16:00:14 | 16:00:20 | 6 seg |
Conclusiones
- Efecto de paralelismo en imágenes pequeñas: Para la imagen de 3 MB, pasar de 1 worker a 9 reduce significativamente el tiempo de procesamiento (de 3 seg a 1 seg), demostrando que el overhead de distribución es pequeño comparado con la mejora por concurrencia.
- Sobrecarga en tamaños medios: Para la imagen de 15 MB, el procesamiento distribuido con 9 workers tarda más (9 seg) que la versión secuencial con 1 worker (7 seg). Esto sugiere que el costo de dividir y coordinar tareas supera el beneficio del paralelismo en tamaños intermedios.
- Balance en imágenes grandes: Para la imagen de 30 MB, el enfoque distribuido con 9 workers presenta una ligera mejora (6 seg) frente a la ejecución secuencial (7 seg), indicando que a mayor tamaño de datos, el paralelismo comienza a compensar el overhead de orquestación.
- Recomendación de configuración: Según el tamaño de las imágenes y la infraestructura, conviene:
- Usar múltiples workers para imágenes pequeñas (< 5 MB) para maximizar rendimiento.
- Evaluar caso a caso para imágenes de tamaño medio (≈ 15 MB), pues el overhead puede penalizar.
- Implementar distribución para imágenes grandes (> 25 MB) donde la ganancia paralela justifica la coordinación.
