Qual è la differenza tra i tipi di servizio ClusterIP, NodePort e LoadBalancer in Kubernetes?


230

1 - Sto leggendo la documentazione e sono leggermente confuso con la formulazione. Dice:

ClusterIP : espone il servizio su un IP interno al cluster. La scelta di questo valore rende il servizio raggiungibile solo all'interno del cluster. Questo è il tipo di servizio predefinito

NodePort : espone il servizio sull'IP di ciascun nodo su una porta statica (NodePort). Viene creato automaticamente un servizio ClusterIP a cui indirizzerà il servizio NodePort. Sarai in grado di contattare il servizio NodePort, dall'esterno del cluster, richiedendo <NodeIP>:<NodePort>.

LoadBalancer : espone il servizio esternamente utilizzando il bilanciamento del carico di un provider cloud. I servizi NodePort e ClusterIP, ai quali indirizzerà il bilanciamento del carico esterno, vengono creati automaticamente.

Il tipo di servizio NodePort utilizza ancora ClusterIPma solo su una porta diversa, aperta a client esterni? Quindi in questo caso è <NodeIP>:<NodePort>uguale a <ClusterIP>:<NodePort>?

Oppure NodeIPl'IP viene effettivamente trovato durante l'esecuzione kubectl get nodese non l'IP virtuale utilizzato per il tipo di servizio ClusterIP?

2 - Anche nello schema dal link seguente:

http://kubernetes.io/images/docs/services-iptables-overview.svg

C'è qualche motivo particolare per cui Clientè dentro Node? Ho pensato che avrebbe dovuto essere all'interno di un Clustercaso nel caso di un tipo di servizio ClusterIP.

Se lo stesso schema è stato redatto per NodePort, sarebbe valida per disegnare il cliente completamente al di fuori sia del Nodee Clustero sono io manca completamente il punto?

Risposte:


217

Un ClusterIP espone quanto segue:

  • spec.clusterIp:spec.ports[*].port

È possibile accedere a questo servizio solo all'interno del cluster. È accessibile dal suo spec.clusterIpporto. Se spec.ports[*].targetPortè impostato, verrà instradato dalla porta a targetPort. L'IP-CLUSTER che si ottiene quando si chiama kubectl get servicesè l'IP assegnato a questo servizio all'interno del cluster internamente.

Un NodePort espone quanto segue:

  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

Se accedi a questo servizio su un nodePort dall'IP esterno del nodo, indirizzerà la richiesta a spec.clusterIp:spec.ports[*].port, che a sua volta indirizzerà al tuospec.ports[*].targetPort , se impostato. È possibile accedere a questo servizio allo stesso modo di ClusterIP.

I tuoi NodeIP sono gli indirizzi IP esterni dei nodi. Non puoi accedere al tuo servizio da <ClusterIP>:spec.ports[*].nodePort.

Un LoadBalancer espone quanto segue:

  • spec.loadBalancerIp:spec.ports[*].port
  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

È possibile accedere a questo servizio dall'indirizzo IP del bilanciamento del carico, che inoltra la richiesta a nodePort, che a sua volta inoltra la richiesta alla porta clusterIP. Puoi accedere a questo servizio come faresti con un NodePort o un servizio ClusterIP.


3
Potresti commentare come externalIPscambia l'equazione qui? In particolare, è possibile assegnare un externalIPsarray a un ClusterIPservizio di tipo e quindi il servizio diventa accessibile anche sull'IP esterno? Quando sceglieresti questo su un NodePort?
Bosh,

La domanda non menziona gli IP esterni - penso che probabilmente ti conviene pubblicare questo post come una nuova domanda.
Kellanburket,

39
Questo post è in realtà più utile per chiarire queste differenze rispetto alla stessa documentazione ufficiale di Kubernetes.
adrpino,

@kellanburket, come fa questo lavoro: spec.clusterIp. ClusterIP può essere esplicitamente menzionato in service.yaml. E allo stesso modospec.loadBalancerIp
samshers

mi hai reso felice con la tua risposta, grazie mille! (come nota a
margine

103

Chiarire per chiunque cerchi qual è la differenza tra i 3 a un livello più semplice. Puoi esporre il tuo servizio con ClusterIp minimo (all'interno del cluster k8s) o un'esposizione maggiore con NodePort (all'interno del cluster esterno al cluster k8s) o LoadBalancer (mondo esterno o qualunque cosa tu abbia definito nel tuo LB).

Esposizione ClusterIp <Esposizione NodePort <Esposizione LoadBalancer

  • ClusterIp
    Esporre il servizio tramite il cluster k8s conip/name:port
  • NodePort
    Esporre il servizio tramite VM di rete interne anche esterne a k8ip/name:port
  • LoadBalancer
    Esporre il servizio attraverso il mondo esterno o qualunque cosa tu abbia definito nel tuo LB.

53

ClusterIP: i servizi sono raggiungibili da pod / servizi nel cluster
Se creo un servizio chiamato myservice nello spazio dei nomi predefinito di tipo: ClusterIP, verrà creato il seguente indirizzo DNS statico prevedibile per il servizio:

myservice.default.svc.cluster.local (o solo myservice.default o dai pod nello spazio dei nomi predefinito funzionerà solo "myservice")

E quel nome DNS può essere risolto solo da pod e servizi all'interno del cluster.

NodePort: i servizi sono raggiungibili dai client sulla stessa LAN / client che possono eseguire il ping dei nodi host K8 (e pod / servizi nel cluster) (Nota per sicurezza i nodi host del tuo k8 dovrebbero essere su una sottorete privata, quindi i client su Internet hanno vinto non
riesco a raggiungere questo servizio) Se creo un servizio chiamato mynodeportservice nello spazio dei nomi mynamespace di tipo: NodePort su un cluster Kubernetes a 3 nodi. Quindi verrà creato un servizio di tipo: ClusterIP e sarà raggiungibile dai client all'interno del cluster al seguente indirizzo DNS statico prevedibile:

mynodeportservice.mynamespace.svc.cluster.local (o solo mynodeportservice.mynamespace)

Per ogni porta che mynodeportservice ascolta su un nodeport nell'intervallo 30000 - 32767 verrà scelto casualmente. In modo che i client esterni esterni al cluster possano accedere al servizio ClusterIP esistente all'interno del cluster. Diciamo che i nostri 3 nodi host K8 hanno IP 10.10.10.1, 10.10.10.2, 10.10.10.3, il servizio Kubernetes è in ascolto sulla porta 80 e il Nodeport scelto a caso era 31852.

Un client che esiste al di fuori del cluster potrebbe visitare 10.10.10.1:31852, 10.10.10.2:31852 o 10.10.10.3:31852 (poiché NodePort è ascoltato da ogni nodo host Kubernetes) Kubeproxy inoltrerà la richiesta alla porta 80 di mynodeportservice.

LoadBalancer: i servizi sono raggiungibili da chiunque sia connesso a Internet * (l'architettura comune è L4 LB è accessibile pubblicamente su Internet inserendolo in una DMZ o assegnandogli un IP privato e pubblico e i nodi host k8 sono su una sottorete privata) Se si effettua mylbservice, quindi verrà generata una VM L4 LB (un servizio IP del cluster e anche un servizio NodePort verranno generati implicitamente). Questa volta il nostro NodePort è 30222. l'idea è che L4 LB avrà un IP pubblico di 1.2.3.4 e caricherà il bilanciamento e inoltrerà il traffico ai 3 nodi host K8 che hanno indirizzi IP privati. (10.10.10.1:30222, 10.10.10.2:30222, 10.10.10.3:30222) e quindi Kube Proxy lo inoltrerà al servizio di tipo ClusterIP che esiste all'interno del cluster.
( Nota: questo è l'unico tipo di servizio che non funziona nel 100% delle implementazioni di Kubernetes, come Kubernetes bare metal, funziona quando Kubernetes ha integrazioni di provider cloud.)


Hai anche chiesto: il tipo di servizio NodePort utilizza ancora ClusterIP? Sì *
O il NodeIP è effettivamente l'IP trovato quando si eseguono kubectl get nodes? Anche Sì *

Consente di disegnare un parallelo tra Fondamenti:
un contenitore è all'interno di un baccello. un pod si trova all'interno di un replicaset. un replicaset si trova all'interno di una distribuzione.
Allo stesso modo:
un servizio ClusterIP fa parte di un servizio NodePort. Un servizio NodePort fa parte di un servizio di bilanciamento del carico.


Nel diagramma che hai mostrato, il client sarebbe un pod all'interno del cluster.


Sulla base delle tue domande di follow-up, avevo l'impressione che volessi sapere come il traffico è entrato nel cluster. Mi sono preso la libertà di fare un Q&A su questo se sei interessato. stackoverflow.com/questions/52241501/...
neokyle

1
Ehi, spiegazione davvero buona, mi chiedo di LoadBalancer. LoadBalancer inoltrerà tutto il traffico a un NodeIP: NodePort (quel nodo che è il prossimo nel round robin) e come procede la chiamata su quel nodo? Come fa la porta del nodo a sapere che si tratta di una chiamata di servizio e che dovrebbe distribuirla tramite il proxy kube all'IP virtuale del servizio? Il proxy kube creerà un semplice port forward?
ItFreak

kube-proxy svolge 3 ruoli principali: 1. rendere i servizi esistenti / funzionanti facendo corrispondere gli iptables sul nodo allo stato desiderato dei servizi in etcd. 2. è responsabile del mapping della porta del nodo al servizio al pod (la mia comprensione è che lo fa tramite iptables) + rimappaggi delle porte 3. assicurarsi che ogni pod abbia un IP univoco. Il nodeport potrebbe entrare in 1 nodo, le definizioni di servizio esistono nelle iptabili di ogni nodo / i servizi esistono su ogni nodo, i pod di solito sono su una rete di overlay virtualizzata e i nodi raddoppiano come router, quindi anche se il traffico arriva su 1 nodo viene indirizzato al pod esistente su un altro nodo.
neokyle,

Sapere come funziona a un livello più profondo di questo è inutile, perché kubernetes è fatto di pezzi modulari, e come il modo in cui Linux ha sapori / distro che funzionano tutti in modo leggermente diverso con alcuni temi generali, ogni distribuzione di K8 è leggermente diversa. Esempio cilium cni sta cercando di sostituire del tutto il proxy kube, il che significa che il modo in cui funziona dietro le quinte è un obiettivo mobile, quindi non vale la pena capire a meno che tu non stia effettivamente contribuendo al progetto / cercando di correggere un bug.
neokyle,

C'è un modo per contattarti? Sto scrivendo una tesi di laurea sulla sicurezza in k8 e mi piacerebbe conoscere le funzioni interne del proxy, ad esempio come distribuisce gli indirizzi IP a nodi e pod e come i servizi ottengono il loro IP virtuale
ItFreak

45

Supponiamo che tu abbia creato una VM Ubuntu sul tuo computer locale. Il suo indirizzo IP è 192.168.1.104 .

Accedi alla VM e hai installato Kubernetes. Quindi hai creato un pod in cui l'immagine nginx è in esecuzione su di esso.

1- Se si desidera accedere a questo pod nginx all'interno della propria VM, si creerà un ClusterIP associato a quel pod, ad esempio:

$ kubectl expose deployment nginxapp --name=nginxclusterip --port=80 --target-port=8080

Quindi sul tuo browser puoi digitare l'indirizzo IP di nginxclusterip con la porta 80, come:

http://10.152.183.2:80

2- Se si desidera accedere a questo pod nginx dal proprio computer host, sarà necessario esporre la distribuzione con NodePort . Per esempio:

$ kubectl expose deployment nginxapp --name=nginxnodeport --port=80 --target-port=8080 --type=NodePort

Ora dal tuo computer host puoi accedere a nginx come:

http://192.168.1.104:31865/

Nella mia dashboard appaiono come:

inserisci qui la descrizione dell'immagine

Di seguito è riportato un diagramma che mostra la relazione di base.

inserisci qui la descrizione dell'immagine


Da dove viene 31865? generato?
HoaPhan,

1
@HoaPhan Puoi specificare esplicitamente la tua porta nel range di 30000-32767 o lasciarla scelta casualmente da Kubernetes in questo intervallo
Mohammad Torkashvand

20

Anche se questa domanda ha già una risposta, ne fornirò un'altra, forse con qualche altra foto per avere una migliore comprensione.

1. ClusterIP è il tipo di servizio predefinito in Kubernetes e questo tipo ti fornisce un servizio all'interno del cluster. Usando questo, altre applicazioni dal cluster possono accedere al servizio tramite il proxy Kubernetes.

Vorrei menzionare che questo tipo di servizio non dovrebbe essere utilizzato per esporre i servizi di produzione. Tuttavia, può essere utilizzato per

  • integrazione di debug tra servizi;
  • accesso ai servizi interni che espongono dati non connessi all'attività (dashboard di monitoraggio).

Il modo in cui la richiesta va è il seguente: traffico -> proxy K8s -> servizio K8s (ClusterIP) -> pods e viene mostrato nella figura seguente.

inserisci qui la descrizione dell'immagine

2. NodePort è il modo più primitivo per accettare il traffico esterno e inoltrarlo ai servizi di kubernetes. Come suggerisce il nome, il tipo di servizio NodePort apre una porta specifica su tutte le macchine virtuali, che sono in realtà i nodi Kubernetes, per consentire al traffico che viene inviato a quella porta specifica di essere inoltrato al servizio.

Il tipo di servizio NodePort ha alcuni aspetti negativi:

  • è necessario disporre di un solo servizio per porta;
  • se l'ip della macchina virtuale verrà modificato, è necessario apportare alcune modifiche nel cluster;
  • è possibile utilizzare solo la porta tra 3000-32767.

La richiesta è la seguente: traffico -> porta esposta su macchina virtuale -> servizio K8s (NodePort) -> pod e viene visualizzata nella seguente immagine:

inserisci qui la descrizione dell'immagine

3. LoadBalancer è il modo standard per esporre un servizio a Internet. Se il tuo desiderio è quello di esporre direttamente un servizio e tutto il traffico su una porta specifica da inoltrare al servizio, allora questo è il modo per farlo. Inoltre, il tipo di servizio LoadBalancer non comporta alcun filtro o routing. Inoltre, puoi inviare ad esso traffico TCP, UDP, HTTP gRPC.

Unico inconveniente: ogni servizio esposto tramite LoadBalancer avrà il proprio indirizzo IP e ogni servizio sarà esposto tramite un singolo LoadBalancer che può diventare costoso.

La richiesta ha il seguente percorso: traffico -> LoadBalancer -> Servizio K8s -> pods ed è visualizzata nella figura seguente.

inserisci qui la descrizione dell'immagine


7
  1. clusterIP: IP accessibile all'interno del cluster (tra i nodi all'interno del cluster d).
nodeA : pod1 => clusterIP1, pod2 => clusterIP2
nodeB : pod3 => clusterIP3.

pod3 può parlare con pod1 tramite la sua rete clusterIP.

  1. nodeport: per rendere i pod accessibili dall'esterno del cluster tramite nodeIP: nodeport, creerà / manterrà clusterIP sopra come rete clusterIP.
nodeA => nodeIPA : nodeportX
nodeB => nodeIPB : nodeportX

è possibile accedere al servizio su pod1 tramite nodeIPA: nodeportX OPPURE nodeIPB: nodeportX. Ad ogni modo funzionerà perché kube-proxy (che è installato in ciascun nodo) riceverà la tua richiesta e la distribuirà [reindirizzarla (termine iptables)] su nodi usando la rete clusterIP.

  1. Bilanciamento del carico

fondamentalmente semplicemente mettendo LB in primo piano, in modo che il traffico in entrata sia distribuito su nodeIPA: nodeportX e nodeIPB: nodeportX, quindi continui con il flusso di processo numero 2 sopra.

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.