Instalación de n8n en Kubernetes con PostgreSQL y Redis

Clase 12 de 13Curso de n8n Self-Hosted para Empresas

Resumen

Instala y ejecuta n8n en Kubernetes con KubeMode, conectándolo a PostgreSQL y Redis para un entorno listo para escalar. Aquí verás cómo crear el clúster con K3D, definir recursos clave como ConfigMap, PVC, Service, Deployment e Ingress, y validar con kubectl que todo queda operativo.

¿Cómo preparar Kubernetes y servicios base?

Primero se valida el entorno local con K3D y kubectl y se crea un clúster mapeando un puerto público al load balancer. Después se despliegan Postgres y Redis con Helm (chart de “Bitnami” en el ejemplo) y se comprueba que los pods están en estado “Running”.

¿Qué comandos iniciales necesitas?

  • Verificar versiones con comandos: k3d version y kubectl version.
  • Crear clúster y exponer puerto: k3d cluster create demo --port 8080@loadbalancer.
  • Ver información del clúster: kubectl cluster-info.
# Instalar PostgreSQL con Helm
helm install postgres vitnami/postgres \
  --set postgresqlUsername=n8n \
  --set postgresqlPassword="mi clave" \
  --set postgresqlDatabase=n8n

# Verificar estado de pods
a) kubectl get pods
b) kubectl logs -f 

¿Qué datos y puertos son críticos?

  • PostgreSQL: puerto 5432, base de datos y usuario: n8n, contraseña: “mi clave”.
  • Redis: puerto 6379, listo cuando muestra “ready to accept connections”.
  • Mapear 8080 al load balancer del clúster para acceder desde el host.

¿Qué recursos de Kubernetes definen n8n en KubeMode?

La configuración se centraliza en un ConfigMap que expone variables para DB (host, puerto, base y credenciales), Redis y KubeMode. Se añade un PersistentVolumeClaim (PVC) para persistir /home/node/.n8n. El Service expone solo el pod main en el puerto 5678 usando ClusterIP.

¿Cómo configurar variables con ConfigMap?

  • Tipo y conexión de base: host del servicio de Postgres (formato servicio.namespace.svc.cluster.local), puerto 5432, base n8n, usuario n8n, contraseña “mi clave”.
  • Conexión a Redis: host del servicio y puerto 6379.
  • Modo de ejecución: KubeMode activo para usar worker y main.
  • Red en local: N8N_TRUST_PROXY y N8N_PROXY_HOPS habilitados.
  • Seguridad: autenticación básica del editor con usuario admin y contraseña admin.
  • Rutas de webhooks: URL base para “test” y “producción”.
# configmap-n8n.yaml (fragmento)
apiVersion: v1
kind: ConfigMap
metadata:
  name: n8nconfig
data:
  # DB: host/puerto/base/usuario/clave
  # Redis: host/puerto
  # KubeMode y ajustes de proxy local
  # Auth básica y webhooks

¿Cómo persistir datos con PVC y exponer el servicio?

  • PVC: solicita almacenamiento y modo de acceso para el directorio de trabajo de n8n.
  • Service (main): selecciona app: n8n y expone el puerto 5678 como ClusterIP.
# pvc-n8n-data.yaml (fragmento)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: n8n-data
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 5Gi
# service-n8n-main.yaml (fragmento)
apiVersion: v1
kind: Service
metadata:
  name: n8n-main
spec:
  selector:
    app: n8n
  ports:
    - port: 5678
  type: ClusterIP

¿Cómo desplegar y verificar con deployments e ingress?

Se crean dos Deployments: uno para worker y otro para main. El worker corre con concurrency=1, lee entorno desde el ConfigMap, define requests/limits (memoria 512Mi/1Gi, CPU 250m/500m) y monta el PVC. Usa liveness y readiness probes por exec. El main arranca con start, expone 5678 y define probes HTTP GET a /healthz con delays mayores porque depende de Redis y Postgres.

¿Qué especificaciones clave usa cada deployment?

  • Imagen: n8n:latest para worker y main.
  • Worker: argumento worker y --concurrency=1.
  • Main: endpoint de salud /healthz en 5678 con httpGet.
  • Recursos: requests y limits para memoria y CPU.
  • Almacenamiento: montar PVC en /home/node/.n8n.
# deployment-n8n-worker.yaml (fragmento)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: n8n-worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: n8n
      role: worker
  template:
    metadata:
      labels:
        app: n8n
        role: worker
    spec:
      containers:
        - name: n8n-worker
          image: n8n:latest
          args: ["worker", "--concurrency=1"]
          envFrom:
            - configMapRef:
                name: n8nconfig
          resources:
            requests: { memory: "512Mi", cpu: "250m" }
            limits:   { memory: "1Gi",   cpu: "500m" }
          volumeMounts:
            - name: n8n-data
              mountPath: /home/node/.n8n
      volumes:
        - name: n8n-data
          persistentVolumeClaim:
            claimName: n8n-data
# deployment-n8n-main.yaml (fragmento)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: n8n-main
spec:
  replicas: 1
  selector:
    matchLabels:
      app: n8n
      role: main
  template:
    metadata:
      labels:
        app: n8n
        role: main
    spec:
      containers:
        - name: n8n-main
          image: n8n:latest
          args: ["start"]
          ports:
            - containerPort: 5678
          readinessProbe:
            httpGet: { path: "/healthz", port: 5678 }
            initialDelaySeconds: 30
          livenessProbe:
            httpGet: { path: "/healthz", port: 5678 }
            initialDelaySeconds: 30
          volumeMounts:
            - name: n8n-data
              mountPath: /home/node/.n8n
      volumes:
        - name: n8n-data
          persistentVolumeClaim:
            claimName: n8n-data

¿Cómo publicar con ingress y aplicar en orden?

  • Ingress con Traefik (por defecto en K3D), host localhost, path: /, backend n8n-main:5678.
# ingress-n8n-localhost.yaml (fragmento)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: n8n
spec:
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: n8n-main
                port:
                  number: 5678
  • Aplicar recursos en orden: ConfigMap, PVC, Service, Deployments (primero main, luego worker) e Ingress.
kubectl apply -f configmap-n8n.yaml
kubectl apply -f pvc-n8n-data.yaml
kubectl apply -f service-n8n-main.yaml
kubectl apply -f deployment-n8n-main.yaml
kubectl apply -f deployment-n8n-worker.yaml
kubectl apply -f ingress-n8n-localhost.yaml
  • Validar con kubectl get pods hasta ver disponibles. Revisar con kubectl logs el main. Abrir el navegador y completar el registro con correo y contraseña fuerte.

¿Quieres que profundicemos en el autoescalado horizontal en Kubernetes para n8n y sus workers? Cuéntame tu escenario y lo vemos paso a paso.