Installa n8n su Kubernetes con Helm: guida passo passo

banner

Dopo aver cercato in lungo e in largo una guida che spiegasse in modo chiaro e dettagliato come installare n8n su Kubernetes, ho deciso di scriverla per condividere con voi i passaggi necessari per l’installazione di n8n su Kubernetes utilizzando Helm.

Per installare n8n su Kubernetes, è possibile utilizzare Helm, un gestore di pacchetti per Kubernetes. Di seguito sono riportati i passaggi per l’installazione di n8n su Kubernetes utilizzando Helm.

Aggiungi il repository Helm

Uno dei repository più aggiornato per n8n è il repository “community-charts”. Per aggiungere questo repository e aggiornare la cache dei chart, esegui i seguenti comandi:

helm repo add community-charts https://community-charts.github.io/helm-charts
helm repo update

Crea un namespace (opzionale)

Questa è facile: ti basterà eseguire questo comando per creare un namespace dedicato a n8n:

kubectl create namespace n8n-test

Configurazione Secret

N8N usa una chiave di crittografia per proteggere i dati sensibili, come le credenziali e i segreti. È importante generare una chiave di crittografia sicura e creare un secret Kubernetes per n8n.

Esegui questo comando per generare una key casuale usando PowerShell:

$N8N_ENCRYPTION_KEY = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | ForEach-Object {[char]$_})

Write-Host "Generated Encryption Key: $N8N_ENCRYPTION_KEY"

Oppure usa questo comando in bash:

N8N_ENCRYPTION_KEY=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 32)
echo "Generated Encryption Key: $N8N_ENCRYPTION_KEY"

A questo punto, puoi usare il comando seguente per creare un secret Kubernetes che contiene la chiave di crittografia e il segreto JWT per n8n. Assicurati di sostituire $N8N_ENCRYPTION_KEY con una chiave di crittografia appena generata.

kubectl create secret generic n8n-secrets `
  --namespace=n8n-automation `
--from-literal=N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY `
  --from-literal=N8N_USER_MANAGEMENT_JWT_SECRET=$N8N_ENCRYPTION_KEY `
--dry-run=client -o yaml | kubectl apply -f -

Installazione

Siamo pronti per installare n8n. Per l’ambiente creato in precedenza, puoi eseguire il seguente comando:

helm install my-test-n8n community-charts/n8n -n n8n-test

Usando questo comando, andrai a utilizzare i valori di default del chart. Per personalizzare la configurazione, puoi creare un file values.yaml e passarlo al comando di installazione con l’opzione -f values.yaml.

Tieni conto che il file values.yaml contiene le configurazioni specifiche, come la configurazione del database, le variabili d’ambiente e le risorse, e permette di personalizzare l’installazione in base alle esigenze del tuo ambiente.

Vediamo quali sono le configurazioni più importanti da utilizzare nel file values.yaml.

Per semplicità, troverai all’interno del file dei commenti che spiegano il significato di ogni configurazione e forniscono consigli su come personalizzarla in base alle esigenze del tuo ambiente (test o produzione): in ogni caso, soprattutto per la configurazione del database, è importante personalizzare i valori per garantire prestazioni ottimali e sicurezza: nella documentazione ufficiale che trovi qui, vengono fornite le indicazioni per la configurazione di un database esterno o interno al cluster, ma in questo esempio, per semplificare l’installazione, utilizzeremo il chart di PostgreSQL incluso come dipendenza del chart di n8n, che è già preconfigurato per funzionare con n8n.

# -----------------------------------------------------------------------------
# IMAGE CONFIGURATION
# -----------------------------------------------------------------------------
image:
  repository: n8nio/n8n
  tag: "2.13.0" # MODIFICARE CON LA VERSIONE DESIDERATA
  pullPolicy: IfNotPresent

imagePullSecrets: []

nameOverride: ""
fullnameOverride: ""

# -----------------------------------------------------------------------------
# SERVICE ACCOUNT
# -----------------------------------------------------------------------------
serviceAccount:
  create: true
  annotations: {}
  name: ""

# -----------------------------------------------------------------------------
# POD CONFIGURATION
# -----------------------------------------------------------------------------
serviceMonitor:
  enabled: false

podAnnotations:
  prometheus.io/scrape: "false" # Cambia a "true" se vuoi abilitare lo scraping da parte di Prometheus
  prometheus.io/port: "5678"
  prometheus.io/path: "/metrics"

podLabels: {}

podSecurityContext:
  runAsNonRoot: true # Assicurati che l'utente non sia root, per girare con privilegi minimi (necessario, ad esempio, per OpenShift)
  runAsUser: 1000 # L'utente con cui n8n girerà all'interno del container (1000 è un valore comune per applicazioni non root)
  fsGroup: 1000 # Il gruppo con cui n8n avrà accesso ai volumi (deve corrispondere all'utente)
  seccompProfile:
    type: RuntimeDefault

securityContext:
  allowPrivilegeEscalation: false # Non permettere l'escalation dei privilegi
  readOnlyRootFilesystem: false # N8N ha bisogno di scrivere su disco per i dati temporanei, quindi non possiamo rendere il filesystem root read-only
  capabilities:
    drop:
      - ALL

# -----------------------------------------------------------------------------
# N8N APPLICATION CONFIGURATION
# -----------------------------------------------------------------------------

timezone: "Europe/Rome" # Imposta il timezone per n8n (importante per la gestione delle date e degli orari nei flussi di lavoro)
webhook:
  url: "https://n8n.<YOUR_DOMAIN>"

db:
  type: postgresdb # Usa PostgreSQL come database (consigliato per produzione), oppure MySQL per ambienti di test o sviluppo
  logging:
    enabled: true # Abilita i log del database per facilitare il debug
    options: error
    maxQueryExecutionTime: 1000 # Logga solo query che impiegano più di 1000ms (1 secondo) per essere eseguite, per identificare eventuali colli di bottiglia

postgresql:
  enabled: true
  architecture: replication # Configura PostgreSQL in modalità replica per alta disponibilità, consigliato per ambienti di produzione

  auth:
    password: "<POSTGRES_PASSWORD>" # Se non specificato, il chart genererà una password casuale
    replicationPassword: "<POSTGRES_REPLICATION_PASSWORD>" # Idem
    database: "<DB_NAME>"
    username: "<DB_USERNAME>"

  primary:
    resources:
      requests:
        memory: 1Gi
        cpu: 500m
      limits:
        memory: 4Gi
        cpu: 2000m
    persistence:
      enabled: true
      storageClass: "mystorageclass" # Sostituisci con lo storage class del tuo cluster
      size: 10Gi
    extendedConfiguration: |
      max_connections = 100 # Numero massimo di connessioni al database: in ambienti di produzione, è consigliabile aumentare questo valore per supportare un maggior numero di connessioni simultanee, mentre in ambienti di test o sviluppo, puoi mantenerlo a un valore più basso per risparmiare risorse
      shared_buffers = 1GB # Memoria condivisa per il database: in ambienti di produzione, è consigliabile allocare più memoria per migliorare le prestazioni, mentre in ambienti di test o sviluppo, puoi ridurre questo valore per risparmiare risorse
      wal_level = replica # Livello di logging per la replica: necessario per abilitare la replica, consigliato per ambienti di produzione
      max_wal_senders = 10 # Numero massimo di processi di invio WAL: indovina? In ambienti di produzione, è consigliabile aumentare questo valore per supportare più repliche, mentre in ambienti di test o sviluppo, puoi mantenerlo a un valore più basso
      max_replication_slots = 10 # Numero massimo di slot di replica: in ambienti di produzione, è consigliabile aumentare questo valore per supportare più repliche, mentre in ambienti di test o sviluppo, puoi mantenerlo a un valore più basso
      synchronous_commit = on      

  readReplicas:
    replicaCount: 2 # Numero di repliche di sola lettura (consigliato almeno 2 per bilanciare il carico di lettura)
    resources:
      requests:
        memory: 1Gi
        cpu: 500m
      limits:
        memory: 4Gi
        cpu: 2000m
    extendedConfiguration: |
      max_connections = 100 
      shared_buffers = 1GB
      hot_standby = on
      synchronous_commit = on      
    persistence:
      enabled: true
      storageClass: "mystorageclass" # Sostituisci con lo storage class del tuo cluster
      size: 5Gi
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app.kubernetes.io/component: read
              topologyKey: kubernetes.io/hostname

  backup: # Configurazione del backup automatico di PostgreSQL: consigliato per ambienti di produzione, non necessario per ambienti di test
    enabled: true
    cronjob:
      schedule: "0 2 * * *"
      concurrencyPolicy: Forbid
      storage:
        storageClass: "acloud"
        size: 10Gi

# -----------------------------------------------------------------------------
# ENVIRONMENT VARIABLES
# -----------------------------------------------------------------------------
main:
  extraEnvVars: # Se stai usando il chart ufficiale di n8n, queste variabili sono già preconfigurate; se invece stai usando un chart custom, assicurati di configurare tutte le variabili necessarie per la connessione al database e per il funzionamento di n8n
    DB_POSTGRESDB_HOST: "<RELEASE_NAME>-postgresql-primary"
    N8N_HOST: "n8n.<YOUR_DOMAIN>"
    N8N_PROTOCOL: "https" # Solo se stai usando un Ingress con TLS; altrimenti, usa "http"
    N8N_EDITOR_BASE_URL: "n8n.<YOUR_DOMAIN>/"
    N8N_SECURE_COOKIE: "true"
    N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
    EXECUTIONS_MODE: "regular"
  # -----------------------------------------------------------------------------
  # RESOURCES
  # -----------------------------------------------------------------------------
  resources: # Configura le risorse per il container n8n: in ambienti di produzione, è consigliabile allocare più risorse per garantire prestazioni ottimali, mentre in ambienti di test o sviluppo, puoi ridurre le risorse per risparmiare costi
    limits:
      cpu: 1000m
      memory: 1Gi
    requests:
      cpu: 250m
      memory: 512Mi

  # -----------------------------------------------------------------------------
  # PROBES
  # -----------------------------------------------------------------------------
  livenessProbe:
    httpGet:
      path: "/healthz"
      port: "http"
      scheme: HTTP
    initialDelaySeconds: 60
    periodSeconds: 30
    timeoutSeconds: 5
    failureThreshold: 3

  readinessProbe:
    httpGet:
      path: "/healthz" # Questo, nella versione del chart ufficiale, presenta un endpoint diverso da quello di liveness che però non funziona: in questo caso, lo forziamo a usare lo stesso endpoint di liveness, che invece è funzionante
      port: "http"
      scheme: HTTP
    initialDelaySeconds: 30
    periodSeconds: 10
    timeoutSeconds: 5
    failureThreshold: 3



# -----------------------------------------------------------------------------
# SERVICE CONFIGURATION
# -----------------------------------------------------------------------------
service:
  type: ClusterIP
  port: 5678

Facciamo un piccolo recap: questa installazione andrà a creare un deployment di n8n con un database PostgreSQL in modalità replica, configurato con risorse adeguate e con una configurazione di backup automatico. Inoltre, il servizio sarà esposto come ClusterIP, quindi sarà necessario utilizzare il port forwarding o un Ingress per accedere all’interfaccia utente di n8n.

Tieni presente che in ambienti di test o sviluppo, puoi semplificare la configurazione riducendo le risorse allocate, disabilitando la replica del database e il backup automatico, e utilizzando un database più leggero come SQLite o MySQL, a seconda delle tue esigenze. Trovi tutto nella documentazione riportata in precedenza!

E ora?

Configurazione dell’accesso all’interfaccia utente

Dopo l’installazione, è possibile accedere all’interfaccia utente di n8n per configurare i flussi di lavoro. Per accedere all’interfaccia utente, è necessario esporre il servizio n8n utilizzando un LoadBalancer o un Ingress.

Per l’ambiente di test, è possibile esporre il servizio n8n utilizzando un LoadBalancer:

kubectl expose deployment my-test-n8n --type=LoadBalancer --name=my-test-n8n-service -n n8n-test

o accedere tramite port forwarding:

kubectl port-forward deployment/my-test-n8n 5678:5678 -n n8n-test

A questo punto, puoi accedere all’interfaccia utente di n8n aprendo un browser e navigando all’indirizzo http://localhost:5678 (se stai usando il port forwarding) o all’indirizzo del LoadBalancer (se stai usando un LoadBalancer).

Più facile di così! Se vuoi, puoi anche configurare un Ingress per esporre n8n con un nome di dominio personalizzato e con TLS, ma questa è un’altra storia che affronteremo magari in un prossimo articolo!

TheRedCode.it - Il mondo #tech a piccoli #bit

Partners

Community, aziende e persone che supportano attivamente il blog

Logo di GrUSP
Logo di Python Milano
Logo di Schrodinger Hat
Logo di Python Biella Group
Logo di Fuzzy Brains
Logo di Django Girls Italy
Logo di Improove
Logo de Il Libro Open Source
Logo di NgRome
Logo de La Locanda del Tech
Logo di Tomorrow Devs
Logo di DevDojo

Vuoi diventare #tech content creator? 🖊️

Se vuoi raccontare la tua sul mondo #tech con dei post a tema o vuoi condividere la tua esperienza con la community, sei nel posto giusto! 😉

Manda una mail a collaborazioni[at]theredcode.it con la tua proposta e diventa la prossima penna del blog!

Ma sì, facciamolo!