Ingress vs Load Balancer


212

Sono piuttosto confuso riguardo al ruolo di Ingress e Load Balancer in Kubernetes.

Per quanto ne so, Ingress viene utilizzato per mappare il traffico in entrata da Internet ai servizi in esecuzione nel cluster.

Il ruolo del bilanciamento del carico è di inoltrare il traffico a un host. A tale proposito, in che modo l'ingresso differisce dal bilanciamento del carico? Inoltre, qual è il concetto di bilanciamento del carico all'interno delle kubernet rispetto ad Amazon ELB e ALB?


Risposte:


183

Load Balancer: un servizio LoadBalancer di kubernetes è un servizio che punta a bilanciatori di carico esterni che NON si trovano nel cluster di kubernetes, ma esistono altrove. Possono funzionare con i tuoi pod, supponendo che i tuoi pod siano instradabili esternamente. Google e AWS forniscono questa funzionalità in modo nativo. In termini di Amazon, questo viene mappato direttamente con ELB e kubernetes durante l'esecuzione in AWS può automaticamente eseguire il provisioning e configurare un'istanza ELB per ciascun servizio LoadBalancer distribuito.

Ingresso: un ingresso è in realtà solo un insieme di regole da passare a un controller che li sta ascoltando. È possibile distribuire un sacco di regole di ingresso, ma non accadrà nulla a meno che non si disponga di un controller in grado di elaborarle. Un servizio LoadBalancer potrebbe attendere le regole di ingresso, se è configurato per farlo.

È anche possibile creare un servizio NodePort , che ha un IP instradabile esternamente all'esterno del cluster, ma punta a un pod esistente all'interno del cluster. Questo potrebbe essere un controller Ingress.

Un Ingress Controller è semplicemente un pod configurato per interpretare le regole di ingresso. Uno dei controller di ingresso più popolari supportati da kubernetes è nginx. In termini di Amazon, ALB può essere utilizzato come controller di ingresso.

Ad esempio, questo controller nginx è in grado di importare le regole di ingresso che hai definito e tradurle in un file nginx.conf che carica e avvia nel suo pod.

Supponiamo ad esempio che tu abbia definito un ingresso come segue:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
   ingress.kubernetes.io/rewrite-target: /
 name: web-ingress
spec:
  rules:
  - host: kubernetes.foo.bar
    http:
      paths:
      - backend:
          serviceName: appsvc
          servicePort: 80
        path: /app

Se poi controlli il pod del controller nginx vedrai la seguente regola definita in /etc/nginx.conf:

server {
    server_name kubernetes.foo.bar;
    listen 80;
    listen [::]:80;
    set $proxy_upstream_name "-";
    location ~* ^/web2\/?(?<baseuri>.*) {
        set $proxy_upstream_name "apps-web2svc-8080";
        port_in_redirect off;

        client_max_body_size                    "1m";

        proxy_set_header Host                   $best_http_host;

        # Pass the extracted client certificate to the backend

        # Allow websocket connections
        proxy_set_header                        Upgrade           $http_upgrade;
        proxy_set_header                        Connection        $connection_upgrade;

        proxy_set_header X-Real-IP              $the_real_ip;
        proxy_set_header X-Forwarded-For        $the_x_forwarded_for;
        proxy_set_header X-Forwarded-Host       $best_http_host;
        proxy_set_header X-Forwarded-Port       $pass_port;
        proxy_set_header X-Forwarded-Proto      $pass_access_scheme;
        proxy_set_header X-Original-URI         $request_uri;
        proxy_set_header X-Scheme               $pass_access_scheme;

        # mitigate HTTPoxy Vulnerability
        # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
        proxy_set_header Proxy                  "";

        # Custom headers

        proxy_connect_timeout                   5s;
        proxy_send_timeout                      60s;
        proxy_read_timeout                      60s;

        proxy_redirect                          off;
        proxy_buffering                         off;
        proxy_buffer_size                       "4k";
        proxy_buffers                           4 "4k";

        proxy_http_version                      1.1;

        proxy_cookie_domain                     off;
        proxy_cookie_path                       off;

    rewrite /app/(.*) /$1 break;
    rewrite /app / break;
    proxy_pass http://apps-appsvc-8080;

    }

Nginx ha appena creato una regola da instradare http://kubernetes.foo.bar/appper puntare al servizio appsvcnel cluster.

Ecco un esempio di come implementare un cluster kubernetes con un controller di ingresso nginx. Spero che questo ti aiuti!


1
Ottengo la differenza tra ingress e controller di ingresso e i loro rispettivi ruoli. In effetti, il bilanciamento del carico è anche responsabile di indirizzare il traffico verso i miei pod di kubernetes tramite una serie di regole definite. Potresti per favore far luce su come il controller di ingresso differisce con il bilanciamento del carico in questo senso? Forse un esempio in cui vengono utilizzati sia l'ingresso che il bilanciamento del carico dovrebbe aiutare.
Arunkjn,

Un controller di ingresso non è un tipo di kubernet ufficiale, è solo una distribuzione di un'immagine LB (nginx è solo un esempio) in grado di interpretare le regole di ingresso. Credo che la maggior parte delle persone supponga che un controller di ingresso sia anche un LB interno che vive all'interno del cluster. In realtà non ho provato a creare un bilanciamento del carico esterno che interpreti le regole di ingresso. Immagino sia possibile, ma potrei sbagliarmi completamente :)
Lindsay Landry,

6
Nella mia attuale applicazione ho esposto la distribuzione di nginx come servizio LoadBalancer su GKE e facendo il proxy inverso da nginx a tutti gli altri servizi in esecuzione nel cluster. Dovrei usare l'ingresso invece dell'approccio sopra?
rigale,

ciao @rigal nel tuo proxy nginx come sono le regole del proxy? Vengono risolti da kube-dns?
Arunkjn,

@arunkjn sì. Le regole si presentano così: location / api / url / {proxy_pass nome-servizio: 80 / api / url ; }
rigale

59

Ho trovato questo articolo molto interessante che spiega le differenze tra NodePort, LoadBalancer e Ingress.

Dal contenuto presente nell'articolo:

LoadBalancer:

Un servizio LoadBalancer è il modo standard per esporre un servizio a Internet. Su GKE, questo genererà un bilanciamento del carico di rete che ti darà un singolo indirizzo IP che inoltrerà tutto il traffico al tuo servizio.

Se si desidera esporre direttamente un servizio, questo è il metodo predefinito. Tutto il traffico sulla porta specificata verrà inoltrato al servizio. Non esiste alcun filtro, nessun instradamento, ecc. Ciò significa che è possibile inviare praticamente qualsiasi tipo di traffico, come HTTP, TCP, UDP, Websocket, gRPC o altro.

Il grande svantaggio è che ogni servizio che esponi con LoadBalancer riceverà il proprio indirizzo IP e dovrai pagare un LoadBalancer per servizio esposto, che può essere costoso!

Ingresso:

Ingress NON è in realtà un tipo di servizio. Al contrario, si trova di fronte a più servizi e funge da "router intelligente" o entra nel tuo cluster.

Puoi fare molte cose diverse con un Ingress e ci sono molti tipi di controller Ingress che hanno capacità diverse.

Il controller di ingresso GKE predefinito farà girare un bilanciamento del carico HTTP (S) per te. Ciò ti consentirà di eseguire sia il routing basato sul percorso sia quello basato sul sottodominio verso i servizi di back-end. Ad esempio, puoi inviare tutto su foo.yourdomain.com al servizio foo e tutto sotto il percorso yourdomain.com/bar/ al servizio bar.

Ingress è probabilmente il modo più potente per esporre i tuoi servizi, ma può anche essere il più complicato. Esistono molti tipi di controller Ingress, da Google Cloud Load Balancer, Nginx, Contour, Istio e altri. Esistono anche plug-in per i controller Ingress, come cert-manager, che possono automaticamente fornire certificati SSL per i tuoi servizi.

Ingress è il più utile se si desidera esporre più servizi con lo stesso indirizzo IP e tutti questi servizi utilizzano lo stesso protocollo L7 (in genere HTTP). Paghi solo per un bilanciamento del carico se stai utilizzando l'integrazione GCP nativa e poiché Ingress è "intelligente" puoi ottenere molte funzionalità pronte all'uso (come SSL, Auth, Routing, ecc.)


2
Si prega di assicurarsi di non violare il copyright di nessuno quando si citano più paragrafi alla lettera. Non sono un esperto di questo, questo caso potrebbe andare bene, ma è sicuramente qualcosa di cui essere consapevoli.
nodo

14

TL: DR

  1. Ingress si colloca tra la rete pubblica (Internet) e i servizi Kubernetes che espongono pubblicamente l'implementazione della nostra Api.
  2. Ingress è in grado di fornire bilanciamento del carico, terminazione SSL e hosting virtuale basato sul nome.
  3. Le funzionalità di ingresso consentono di esporre in modo sicuro più API o applicazioni da un singolo nome di dominio.

Cominciamo con un caso d'uso pratico: hai più API supportate da pacchetti di implementazione del servizio (ASIP per chiarezza e brevità) da distribuire sotto un unico nome di dominio. Dato che sei uno sviluppatore all'avanguardia, hai implementato un'architettura di micro-servizi che richiede distribuzioni separate per ciascun ASIP in modo che possano essere aggiornati o ridimensionati individualmente. Naturalmente, questi ASIP sono incapsulati in un singolo contenitore docker e disponibili per Kubernetes (K8) dal repository di contenitori.

Diciamo ora che vuoi distribuire questo sui GKE K8 di Google. Per implementare la disponibilità sostenuta, ogni istanza ASIP (replica) viene distribuita su nodi diversi (VM) in cui ogni VM ha il proprio indirizzo IP interno cloud. Ogni distribuzione ASIP è configurata in un file "deploy.yaml" con nome appropriato in cui si specifica in modo dichiarativo, tra le altre cose, il numero di repliche dei K8 ASIP dati che devono essere distribuiti.

Il prossimo passo è esporre l'API al mondo esterno e incanalare le richieste a una delle istanze ASIP distribuite. Poiché abbiamo molte repliche dello stesso ASIP in esecuzione su nodi diversi, abbiamo bisogno di qualcosa che distribuisca la richiesta tra quelle repliche. Per risolvere questo problema, possiamo creare e applicare un file "service.yaml" che configurerà un servizio K8s (KServ) che sarà esposto esternamente e accessibile attraverso un indirizzo IP. Questo KServ si occuperà della distribuzione delle richieste dell'API tra i suoi ASIP configurati. Si noti che un KServ verrà automaticamente riconfigurato dal master K8s quando un nodo ASIP fallisce e viene riavviato. In tal caso, l'indirizzo IP interno non viene mai riutilizzato e KServ deve essere informato della posizione di distribuzione del nuovo ASIP.

Ma abbiamo altri pacchetti di servizi Api che devono essere esposti con lo stesso nome di dominio. La rotazione di un nuovo KServ creerà un nuovo indirizzo IP esterno e non saremo in grado di esporlo sullo stesso nome di dominio. Bene, è qui che entra in scena Ingress.

L'ingresso è tra Internet e tutti i servizi K che esponiamo al mondo esterno. Ingress è in grado di fornire bilanciamento del carico, terminazione SSL e hosting virtuale basato sul nome. Quest'ultima capacità è in grado di indirizzare una richiesta in arrivo al servizio giusto analizzandone l'URL. Naturalmente, Ingress deve essere configurato e applicato con un file ... "ingress.yaml" che specificherà le riscritture e le rotte richieste per inviare una richiesta al giusto KServ.

Internet -> Ingressi -> Servizi K8s -> Repliche

Quindi, con la giusta configurazione di ingresso, KServices e ASIP, possiamo esporre in modo sicuro molte API usando lo stesso nome di dominio.


9
internet -> loadbalancer -> controller di ingresso -> regole di ingresso -> k8s-services -> Repliche
c4f4t0r


@sofjake, cosa vorresti dire?
c4f4t0r

9

Esistono 4 modi per consentire ai pod nel cluster di ricevere traffico esterno:
1.) Pod utilizzando HostNetworking: true e (Consente a 1 pod per nodo di ascoltare direttamente le porte sul nodo host. Minikube, bare metal e rasberry a volte vanno questa route che può consentire al nodo host di essere in ascolto sulla porta 80/443 consente di non utilizzare un bilanciamento del carico o configurazioni avanzate di bilanciamento del carico cloud, ignora anche i servizi di Kubernetes che possono essere utili per evitare SNAT / ottenere effetti simili di externalTrafficPolicy: Local in scenari dove non è supportato come su AWS.)
2.) Servizio NodePort
3.) Servizio LoadBalancer (che si basa sul servizio NodePort)
4.) Ingress Controller + Ingress Objects (che si basa su quanto sopra)

Diciamo che hai 10 siti web ospitati nel tuo cluster e che vuoi esporli tutti al traffico esterno.
* Se usi il servizio LoadBalancer di tipo genererai 10 bilanciatori del carico di HA Cloud (ognuno costa denaro)
* Se usi il tipo Ingress Controller genererai un bilanciamento del carico di HA Cloud (risparmi) e indicherà un Ingress Controller in esecuzione nel cluster.

Un controller Ingress è:

  • Un servizio di tipo Load Balancer supportato da una distribuzione di pod in esecuzione nel cluster.
  • Ogni pod fa 2 cose:
    1. Funziona come un bilanciamento del carico di livello 7 in esecuzione all'interno del cluster. (Disponibile in molti gusti Nginx è popolare)
    2. Si configura dinamicamente in base agli oggetti Ingress nel cluster
      (gli oggetti Ingress possono essere considerati frammenti di configurazione dichiarativi di un bilanciamento del carico di livello 7).

Il controller LB / Ingress L7 all'interno del cluster Bilance di carico / invio proxy del traffico verso i servizi IP del cluster all'interno del cluster, può anche terminare HTTPS se si dispone di un segreto Kubernetes di tipo TLS cert e oggetto Ingress che fa riferimento a esso.)

inserisci qui la descrizione dell'immagine


1
Se qualcuno cerca
neokyle

quale sarebbe la differenza tra metallb e controller di ingresso?
ImranRazaKhan

1
L'idea del controller di ingresso è che è un pod L7 LB in esecuzione nella rete del cluster interno. E di solito è esposto alla LAN tramite un LB che esiste sulla rete LAN. MetalLB è un software che puoi installare sui nodi Kube che può dare l'illusione di essere una LAN con indirizzo IP virtuale / VIP che è raggiungibile sulla LAN, per ricoprire il ruolo dell'LB che esiste sulla LAN.
neokyle

6

Ingress: Ingress Object + Ingress Controller

Oggetto di ingresso:

Proprio come un oggetto servizio, tranne che non fa nulla da solo. Un oggetto Ingress descrive semplicemente un modo per instradare il traffico di livello 7 nel cluster, specificando cose come il percorso di richiesta, il dominio di richiesta e il servizio kubernetes di destinazione, mentre un oggetto di servizio crea effettivamente servizi

Ingress Controller:

Un servizio che:

  1. listens on specific ports (usually 80 and 443) for web traffic
  2. Listens for the creation, modification, or deletion of Ingress Objects
  3. Creates internal L7 routing rules based on these Ingress Objects

Ad esempio, Nginx Ingress Controller, potrebbe utilizzare un servizio per ascoltare sulla porta 80 e 443 e quindi leggere nuovi oggetti Ingress e analizzarli in nuove sezioni del server {} che inserisce dinamicamente nel suo nginx.conf

LoadBalancer: provider di bilanciamento del carico esterno + tipo di servizio

Fornitore di bilanciamento del carico esterno:

I provider di bilanciamento del carico esterno sono generalmente configurati in cloud come AWS e GKE e forniscono un modo per assegnare IP esterni attraverso la creazione di bilanciatori di carico esterni. Questa funzionalità può essere utilizzata designando un servizio come tipo "LoadBalancer".

Tipo di servizio:

Quando il tipo di servizio è impostato su LoadBalancer, Kubernetes tenta di creare e quindi programmare un bilanciamento del carico esterno con voci per i pod Kubernetes, assegnando così loro IP esterni.

Il controller del servizio Kubernetes automatizza la creazione del bilanciamento del carico esterno, i controlli dello stato (se necessario), le regole del firewall (se necessario) e recupera l'IP esterno del LoadBalancer appena creato o configurato che è stato allocato dal provider cloud e lo popola nel oggetto di servizio.

rapporti:

I servizi di controller di ingresso sono spesso forniti come tipo LoadBalancer, in modo che le richieste http e https possano essere inoltrate / instradate a servizi interni specifici attraverso un ip esterno.

Tuttavia, un LoadBalancer non è strettamente necessario per questo. Poiché, tramite hostNetwork o hostPort, è possibile associare tecnicamente una porta sull'host a un servizio (che consente di visitarlo tramite l'ip esterno: porta dell'host). Anche se ufficialmente questo non è raccomandato in quanto utilizza le porte sul nodo effettivo.

Riferimenti:

https://kubernetes.io/docs/concepts/configuration/overview/#services

https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/

https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#external-load-balancer-providers

https://kubernetes.io/docs/concepts/services-networking/ingress/


3

In parole semplici, il bilanciamento del carico distribuisce le richieste tra più servizi back-end (dello stesso tipo) mentre l'ingresso è più simile a un gateway API (proxy inverso) che indirizza la richiesta a un servizio back-end specifico basato, ad esempio, sull'URL.


Per seguire la tua risposta, nel caso in cui il bilanciamento del carico e il controller di ingresso siano separati, il controller di ingresso si trova in ogni caso dietro il bilanciamento del carico.
AQuirky,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.