N8n en Kubernetes con queue mode

Resumen

Montar n8n en Kubernetes con queue mode te permite escalar workers de forma horizontal y aprovechar la potencia de un clúster real. Aquí verás cómo configurar Postgres, Redis, los recursos de Kubernetes y los deployments de main y worker para que tu instancia quede lista para producción.

Esta guía es útil si ya conoces Docker Compose con n8n y quieres dar el salto a un entorno orquestado. Si no manejas Kubernetes, conviene que repases el curso de Platzi de Kubernetes antes de continuar.

Qué necesitas antes de instalar n8n en Kubernetes

El punto de partida es tener un clúster funcionando. En la clase se usa k3d, una herramienta ligera para correr Kubernetes en local, aunque también sirven Minikube u otras alternativas [01:00].

  • k3d instalado y verificado con k3d version.
  • kubectl listo, comprobado con kubectl version.
  • Helm disponible para instalar Postgres y Redis desde Bitnami.

El clúster se crea con un comando que expone el puerto 80 del equipo hacia el load balancer interno: k3d cluster create demo --port 8080@loadbalancer. Después confirmas que todo responde con kubectl cluster-info.

¿Qué es k3d? Es una distribución ligera de Kubernetes pensada para correr clústeres en local sobre Docker. Funciona bien para pruebas y desarrollo sin necesidad de infraestructura cloud.

Cómo instalar Postgres y Redis con Bitnami en el clúster

En lugar de levantar bases de datos externas, se usan los charts de Bitnami con Helm. Para Postgres defines usuario n8n, contraseña, base de datos n8n y un máximo de 5 GB de almacenamiento [03:30]. Redis se instala con un comando equivalente.

Para confirmar que ambos pods están corriendo:

  • kubectl get pods muestra el estado de cada contenedor.
  • kubectl logs <nombre> revisa los registros puntuales.
  • kubectl logs -f <nombre> sigue los logs en vivo.

Cuando Redis muestra ready to accept connection TCP, ya tienes los dos componentes base listos para que n8n se conecte.

Cómo configurar el ConfigMap y el volumen para n8n

El ConfigMap centraliza todas las variables de entorno que luego leerán los pods. Aquí defines el tipo de base de datos, el host de Postgres construido como nombre-servicio.namespace.svc.cluster.local, el puerto 5432, las credenciales y la conexión a Redis en el puerto 6379 [06:30].

Dentro del mismo recurso van también:

  • executionMode con valor queue para activar el modo de colas.
  • n8n_basicAuthActive, usuario y contraseña para proteger el editor.
  • webhookUrl y webhookTestUrl con el dominio público.
  • timezone ajustado a tu región, por ejemplo Europe/Madrid.
  • n8n_trustProxy y n8n_proxyHops, necesarios al trabajar en local.

Luego creas un PersistentVolumeClaim llamado n8n-data que guardará la información persistente del main. Ambos recursos se aplican con kubectl apply -f.

¿Por qué usar queue mode en n8n? Porque separa el proceso principal de los workers que ejecutan los flujos. Así puedes escalar workers de forma independiente y soportar más ejecuciones concurrentes.

Cómo definir los deployments de main y worker en Kubernetes

El deployment del worker apunta a la imagen n8n/n8n:latest, recibe el argumento worker y una concurrencia de 1. Las variables de entorno se inyectan con envFrom apuntando al ConfigMap n8n-config, evitando repetir cada valor [12:00].

Los recursos quedan así:

  • Requests: 512 Mi de memoria y 250 m de CPU.
  • Limits: 1 Gi de memoria y 500 m de CPU.
  • livenessProbe con exec que valida un string interno del worker.
  • readinessProbe con delay inicial de 10 segundos.

El deployment del main parte del mismo archivo, pero cambia el argumento a start, elimina la concurrencia y reemplaza las probes por un httpGet al endpoint /healthz en el puerto 5678. Ese endpoint es el que n8n expone para verificar salud cuando corre como instancia principal [16:30].

Por qué el main usa httpGet y el worker usa exec

El main expone una API HTTP, así que tiene sentido validarlo con una petición a /healthz. El worker no expone puerto público, por eso se inspecciona desde dentro del contenedor con un comando que busca un string específico en sus procesos.

Cómo exponer n8n con Service e Ingress

El Service solo se crea para el main, porque es el único componente que necesita ser accesible. Usa un selector app=n8n-main, el puerto 5678 y el tipo ClusterIP.

El Ingress utiliza Traefik, que viene por defecto con k3d, aunque podrías usar nginx con ajustes adicionales. Define una regla con host localhost, pathType Prefix y dirige el tráfico al servicio n8n-main en el puerto 5678 [20:00].

El orden de aplicación es importante:

  1. ConfigMap.
  2. PersistentVolumeClaim.
  3. Service.
  4. Deployment del main.
  5. Deployment del worker.
  6. Ingress.

Es normal que el ingress muestre advertencias iniciales mientras los pods terminan de arrancar. Con kubectl get pods confirmas que todo esté en estado Running y con kubectl logs del main verás la URL lista para abrir en el navegador.

¿Cuánto tarda en estar disponible n8n? Suele tomar entre uno y dos minutos, ya que el main debe conectarse a Postgres, Redis y validar que los workers respondan antes de exponerse.

Qué ganas al correr n8n con escalado horizontal

Con esta arquitectura tienes un main, un worker, sistema de colas, Postgres y Redis funcionando en Kubernetes. El siguiente paso natural es activar Horizontal Pod Autoscaler sobre el deployment del worker para que escale según carga de CPU o memoria.

Si has llegado hasta aquí, cuéntame en los comentarios qué ingress controller prefieres usar y si planeas mover esta configuración a un clúster gestionado como EKS o GKE.