NodePort vs. LoadBalancer vs. Ingress: Scegliere la Migliore Esposizione del Servizio

Naviga la scelta critica di esporre i Servizi Kubernetes esternamente confrontando NodePort, LoadBalancer e Ingress. Questa guida dettaglia l'architettura, il livello operativo (L4 vs. L7), i casi d'uso e le differenze chiave in termini di costo e complessità per ciascun metodo. Impara quando utilizzare il semplice NodePort per test, il LoadBalancer dedicato per servizi singoli o il potente Ingress per un routing centralizzato ed economico di Livello 7 e ambienti multi-servizio complessi.

NodePort vs. LoadBalancer vs. Ingress: Scegliere la Migliore Esposizione del Servizio

Kubernetes assegna IP temporanei ai Pod, poi utilizza i Servizi per fornire un modo stabile per raggiungerli. All'interno del cluster, un normale Servizio ClusterIP è spesso sufficiente. La domanda diventa più interessante quando qualcosa al di fuori del cluster deve connettersi.

I tre nomi che ricorrono più spesso sono NodePort, LoadBalancer e Ingress. Sono correlati, ma non sono intercambiabili. NodePort apre una porta su ogni nodo. LoadBalancer chiede al provider di infrastruttura un bilanciatore di carico esterno. Ingress definisce regole di routing HTTP e necessita di un controller Ingress per rendere reali tali regole.


1. Tipo di Esposizione del Servizio: NodePort

Il tipo di servizio NodePort è il modo più semplice e primitivo per esporre un servizio esternamente. Quando definisci un servizio come NodePort, Kubernetes apre una specifica porta statica su ogni nodo del cluster. Qualsiasi traffico diretto a quella porta su qualsiasi nodo viene instradato direttamente al servizio.

Come Funziona NodePort

  1. Una porta casuale all'interno di un intervallo designato (default: 30000-32767) viene selezionata automaticamente.
  2. Questa porta viene aperta su tutti i nodi del cluster.
  3. Il Servizio ascolta su questa NodePort, inoltrando il traffico ai Pod appropriati.

Per accedere all'applicazione, si utilizza http://<IP_Nodo>:<NodePort>.

Casi d'Uso e Limitazioni

Caratteristica Descrizione
Caso d'Uso Sviluppo, ambienti di test, o dove il bilanciamento del carico esterno è gestito da un apparato esterno non cloud.
Complessità Molto Bassa.
Costo Zero (se si ignorano i costi sottostanti delle VM).
Limitazione Richiede la gestione manuale delle regole del firewall esterno. Gli IP dei nodi sono spesso dinamici. Restrizione dell'intervallo di porte (30000-32767).

Esempio NodePort

apiVersion: v1
kind: Service
metadata:
  name: my-app-nodeport
spec:
  type: NodePort
  selector:
    app: my-web-app
  ports:
    - port: 80
      targetPort: 8080
      # Opzionale: specificare una NodePort, altrimenti ne viene scelta una automaticamente
      # nodePort: 30001 

Attenzione: NodePort espone il servizio tramite gli IP dei nodi e una porta alta. Può essere utile dietro il proprio bilanciatore di carico esterno, specialmente su bare metal, ma è scomodo come interfaccia pubblica per un'app web di produzione.


2. Tipo di Esposizione del Servizio: LoadBalancer

Il tipo di servizio LoadBalancer è il metodo standard per esporre applicazioni a internet pubblico in ambienti cloud (AWS EKS, GCP GKE, Azure AKS).

Quando un servizio è definito come LoadBalancer, Kubernetes chiede all'integrazione del bilanciatore di carico del cluster di fornire un bilanciatore di carico esterno. Nei cluster cloud gestiti, ciò spesso significa un cloud L4 load balancer. Nei cluster bare-metal, potrebbe significare un progetto come MetalLB o un'altra integrazione locale. Il risultato è solitamente un indirizzo esterno stabile che inoltra il traffico al Servizio.

Integrazione con il Provider Cloud

Il fattore chiave di differenziazione di LoadBalancer è la profonda integrazione con l'infrastruttura cloud sottostante. Il provider cloud gestisce il ciclo di vita del bilanciatore di carico, i controlli di integrità e il routing.

Casi d'Uso e Implicazioni di Costo

Caratteristica Descrizione
Caso d'Uso Applicazioni semplici rivolte al pubblico che richiedono un indirizzo IP dedicato e stabile. Adatto per protocolli non HTTP/S (TCP/UDP).
Complessità Bassa (a livello di configurazione).
Costo Spesso più alto in ambienti cloud perché ogni Servizio può creare una risorsa di bilanciamento del carico separata.
Vantaggio Fornisce immediata alta disponibilità e controlli di integrità automatici.

Esempio LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: my-app-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: my-api-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Alla creazione, il cluster assegnerà un indirizzo IP esterno (visibile nello stato del servizio) gestito dal provider cloud.


3. Ingress Kubernetes: Routing di Livello 7

Ingress è fondamentalmente diverso da NodePort e LoadBalancer. Ingress non è un tipo di Servizio ma piuttosto un oggetto API che definisce regole per l'accesso esterno, tipicamente HTTP e HTTPS (Livello 7).

Ingress agisce come un punto di ingresso centrale, consentendo un routing sofisticato basato su nomi host e percorsi URL. Questo approccio è essenziale per gestire più servizi dietro un singolo indirizzo IP.

Il Ruolo del Controller Ingress

Affinché le regole Ingress funzionino, è necessario prima distribuire un Controller Ingress come ingress-nginx, Traefik, HAProxy o un controller del provider cloud. Service mesh come Istio possono anche fornire una gestione del traffico di tipo gateway, ma non sono la stessa cosa dell'API Ingress di base di Kubernetes.

Il controller Ingress stesso è solitamente esposto utilizzando un singolo Servizio LoadBalancer o NodePort.

Funzionalità Avanzate di Ingress

Ingress eccelle quando sono necessarie funzionalità avanzate di gestione del traffico:

  1. Ottimizzazione dei Costi: Utilizzare un singolo LoadBalancer cloud (per esporre il Controller) invece di un LoadBalancer per servizio applicativo.
  2. Hosting Virtuale: Instradare il traffico in base ai nomi host (api.example.com va al Servizio A; www.example.com va al Servizio B).
  3. Routing Basato sul Percorso: Instradare il traffico in base ai percorsi URL (/v1/users va al Servizio A; /v2/posts va al Servizio B).
  4. Terminazione SSL/TLS: Gestire centralmente la gestione dei certificati e la decrittazione.

Esempio di Risorsa Ingress

Questo esempio instrada il traffico per api.example.com/v1 al servizio my-api-v1.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  ingressClassName: nginx # Specifica il controller in uso
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: my-api-v1
            port:
              number: 80
  # ... altre regole per diversi servizi/host

4. Guida al Confronto e alla Selezione

Scegliere il metodo ottimale implica valutare fattori come ambiente, complessità, set di funzionalità e costo operativo.

Tabella di Confronto delle Caratteristiche

Caratteristica NodePort LoadBalancer Ingress
Livello L4 (TCP/UDP) L4 (TCP/UDP) L7 (HTTP/S)
Stabilità (IP) Instabile (usa IP Nodo) Stabile (IP Cloud Dedicato) Stabile (Usa IP del Controller)
Costo Basso (Overhead operativo alto) Alto (Costo risorsa per servizio) Moderato (Un LoadBalancer per il Controller)
Logica di Routing Semplice inoltro porta Semplice inoltro porta Nome Host, Percorso, Terminazione SSL
Dipendenza dal Cloud Nessuna Dipende dall'integrazione del provider Dipende dal controller e dal metodo di esposizione
Pronto per la Produzione A volte, solitamente dietro un altro bilanciatore di carico Sì per esposizione L4 semplice Sì per routing HTTP/S

Criteri di Decisione: Scegliere il Metodo di Esposizione

  1. Solo per Uso Interno o Test: Se hai semplicemente bisogno di testare la connettività all'interno del tuo cluster, o se gestisci tu stesso il networking esterno (es. in un ambiente bare-metal), usa NodePort.

  2. Per Esposizione L4 Semplice e Dedicata: Se la tua applicazione utilizza protocolli non HTTP (come protocolli TCP personalizzati o UDP) o se hai una sola applicazione pubblica che necessita di accesso L4 immediato e dedicato, usa LoadBalancer.

  3. Per Esposizione L7 Complessa e Multi-Servizio: Se hai più servizi da esporre, necessiti di routing basato su percorso o nome host, hai bisogno di terminazione SSL centralizzata o vuoi minimizzare i costi cloud condividendo un singolo IP esterno, usa Ingress.

Per molte applicazioni HTTP/S di produzione, Ingress è la scelta usuale perché centralizza certificati e routing. Per database, broker di messaggi, server di gioco, servizi TCP grezzi o qualsiasi cosa non sia realmente HTTP, un Servizio LoadBalancer potrebbe essere più chiaro. Per cluster bare-metal, NodePort potrebbe ancora far parte del progetto, ma è comunemente posto dietro un appropriato bilanciatore di carico esterno o una regola del firewall.

Come si Integrano nei Cluster Reali

Una parte confusa è che queste opzioni possono essere impilate l'una sull'altra. Un oggetto Ingress non espone pacchetti da solo. Il controller riceve il traffico in qualche modo, e quel "qualche modo" è spesso un Servizio LoadBalancer in un cluster cloud:

Internet
  -> Cloud Load Balancer
  -> Servizio tipo LoadBalancer per ingress-nginx
  -> Pod del controller Ingress
  -> Regola Ingress
  -> Servizio ClusterIP
  -> Pod dell'applicazione

Su bare metal, il percorso potrebbe invece utilizzare NodePort:

Internet o rete aziendale
  -> Bilanciatore di carico esterno / firewall
  -> NodeIP:NodePort
  -> Pod del controller Ingress
  -> Servizio dell'applicazione

Ecco perché dire "usa Ingress invece di LoadBalancer" è un po' impreciso. Ingress spesso utilizza ancora un bilanciatore di carico, ma permette a molte applicazioni HTTP di condividere un punto di ingresso.

Esempi Pratici

Usa NodePort quando stai eseguendo il debug di un cluster di laboratorio, esponendo un servizio temporaneamente a una rete privata o integrandoti con hardware di bilanciamento del carico che già gestisci. Non far ricordare agli utenti https://app.example.com:31427 a meno che non sia veramente uno strumento interno.

Usa LoadBalancer quando un servizio necessita di un indirizzo esterno stabile e l'inoltro L4 è sufficiente. Un'API TCP pubblica, un servizio UDP o un singolo endpoint amministrativo interno possono essere più semplici in questo modo. È anche utile quando il protocollo dell'applicazione non si adatta al normale routing HTTP host/path.

Usa Ingress quando hai applicazioni web. Se api.example.com, docs.example.com e app.example.com vivono tutti nello stesso cluster, Ingress ti offre un unico posto per gestire il routing degli host e TLS. Aggiungi cert-manager e il rinnovo dei certificati può diventare un normale flusso di lavoro del cluster invece di un'attività manuale sul server.

Controlli di Sicurezza e Operativi

L'oggetto di esposizione è solo una parte della decisione di produzione. Devi anche chiederti chi può raggiungere l'endpoint, dove termina TLS, come vengono preservati gli IP di origine e come vengono osservati i guasti.

Con NodePort, controlla attentamente le regole del firewall. Kubernetes potrebbe aprire la porta su ogni nodo, ma la tua rete decide ancora se il mondo esterno può raggiungerla. Negli ambienti cloud, i gruppi di sicurezza o le regole del firewall spesso devono consentire l'intervallo NodePort. Su bare metal, la stessa preoccupazione può risiedere in un firewall perimetrale. Se intendi che uno strumento amministrativo privato sia raggiungibile solo da una VPN, imponilo al di fuori di Kubernetes così come al suo interno.

Con LoadBalancer, ispeziona le annotazioni specifiche del provider. Spesso controllano se il bilanciatore di carico è interno o rivolto a internet, quale protocollo utilizza, quale percorso di health check sonda e se preserva l'IP di origine del client. Questi dettagli variano da provider a provider, quindi non dare per scontato che un manifest copiato da un cloud si comporti allo stesso modo in un altro.

Con Ingress, il centro operativo si sposta sul controller. Hai bisogno di log e metriche dai pod del controller, non solo dai pod dell'applicazione. Se una route fallisce, il Servizio e i Pod potrebbero essere integri mentre il controller ha rifiutato la regola, ha usato la classe ingress sbagliata, ha perso un segreto TLS o ha instradato verso il backend sbagliato. Una checklist rapida aiuta:

kubectl get ingress
kubectl describe ingress example-ingress
kubectl get svc -n ingress-nginx
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller

Sii anche chiaro su TLS. Ingress comunemente termina HTTPS al controller e invia HTTP al Servizio backend. Questo va bene per molti cluster interni, ma alcuni team richiedono la crittografia fino al pod dell'applicazione. Se questo è il tuo requisito, configura intenzionalmente il backend TLS invece di presumere che Ingress lo fornisca automaticamente.

Modalità di Guasto Comuni

Se un NodePort funziona da un nodo ma non da un altro, verifica se kube-proxy o il CNI del cluster è integro sul nodo che fallisce. Controlla anche se il firewall esterno consente il traffico verso ogni IP del nodo che intendi utilizzare.

Se un Servizio LoadBalancer rimane in Pending, probabilmente il cluster non può fornire il bilanciatore di carico esterno. In Kubernetes gestito, ciò può significare integrazione del controller cloud mancante, permessi, tag di subnet, quota o impostazioni specifiche del provider. In Kubernetes bare-metal, di solito significa che non è installata alcuna implementazione del bilanciatore di carico.

Se un Ingress restituisce una pagina di backend predefinita o un 404 dal controller, la richiesta ha raggiunto il controller ma non ha corrisposto alla tua regola host o path. Controlla DNS, l'intestazione Host, ingressClassName, il tipo di path e se il nome del Servizio e la porta sono corretti. Se ottieni un certificato TLS per il nome host sbagliato, controlla il segreto referenziato dall'Ingress e se un'altra regola Ingress sta rivendicando lo stesso host.

Una Scorciatoia Decisionale Semplice

Inizia dal protocollo. Se è HTTP o HTTPS e più di un'app potrebbe eventualmente condividere il punto di ingresso, usa Ingress. Se è TCP o UDP grezzo e necessita di un indirizzo esterno stabile, usa LoadBalancer. Se stai testando, integrandoti con la tua apparecchiatura di rete o costruendo un percorso bare-metal, NodePort potrebbe far parte della risposta.

Poi controlla il modello operativo. Un piccolo team che gestisce una singola API pubblica potrebbe preferire un LoadBalancer perché è ovvio e facile da debuggare. Un team di piattaforma che ospita dozzine di servizi web preferirà solitamente Ingress perché il routing condiviso, i certificati e le policy contano più del livello extra del controller.

Note Finali

Scegli in base al protocollo e alle operazioni, non a quale oggetto sembra più avanzato. NodePort è un elemento costitutivo. LoadBalancer è un accesso L4 esterno diretto. Ingress è il routing HTTP/S tramite un controller. In un piccolo cluster, tutti e tre possono apparire nello stesso progetto, e va bene finché ognuno ha un compito chiaro.