Exposing Services in Kubernetes
Ci sono diversi modi per esporre i servizi in Kubernetes in modo che entrambi gli endpoint interni ed esterni possano accedervi. Questa configurazione di Kubernetes è piuttosto critica in quanto l'amministratore potrebbe dare accesso a attaccanti a servizi a cui non dovrebbero poter accedere.
Enumerazione automatica
Prima di iniziare a enumerare i modi in cui K8s offre per esporre i servizi al pubblico, sappi che se puoi elencare i namespace, i servizi e gli ingressi, puoi trovare tutto ciò che è esposto al pubblico con:
ClusterIP
Un servizio ClusterIP è il servizio predefinito di Kubernetes. Ti fornisce un servizio all'interno del tuo cluster a cui altre applicazioni all'interno del cluster possono accedere. Non c'è accesso esterno.
Tuttavia, è possibile accedervi utilizzando il Proxy di Kubernetes:
Ora, puoi navigare attraverso l'API di Kubernetes per accedere ai servizi utilizzando questo schema:
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
Ad esempio, potresti utilizzare l'URL seguente:
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
per accedere a questo servizio:
Questo metodo richiede di eseguire kubectl
come un utente autenticato.
NodePort
Quando viene utilizzato NodePort, viene creato una porta designata su tutti i Nodi (che rappresentano le macchine virtuali). Il traffico diretto a questa porta specifica viene quindi instradato al servizio in modo sistematico. Tipicamente, questo metodo non è consigliato a causa dei suoi svantaggi.
Un esempio di specifica NodePort:
Se non specifici il nodePort nel file yaml (è la porta che verrà aperta) verrà utilizzata una porta nell'intervallo 30000-32767.
LoadBalancer
Espone il servizio esternamente utilizzando un bilanciatore di carico del provider cloud. Su GKE, questo creerà un Network Load Balancer che ti fornirà un singolo indirizzo IP che inoltrerà tutto il traffico al tuo servizio.
Dovrai pagare un LoadBalancer per ogni servizio esposto, il che può diventare costoso.
ExternalName
Dalla documentazione: I servizi di tipo ExternalName mappano un servizio a un nome DNS, non a un selettore tipico come my-service
o cassandra
. Specifici questi servizi con il parametro spec.externalName
.
Ad esempio, questa definizione di servizio mappa il servizio my-service
nel namespace prod
a my.database.example.com
:
Quando si cerca l'host my-service.prod.svc.cluster.local
, il servizio DNS del cluster restituisce un record CNAME
con il valore my.database.example.com
. L'accesso a my-service
funziona allo stesso modo degli altri servizi, ma con la differenza cruciale che il reindirizzamento avviene a livello DNS anziché tramite proxy o inoltro.
Indirizzi IP esterni
Il traffico che entra nel cluster con l'IP esterno (come IP di destinazione), sulla porta del servizio, verrà instradato verso uno degli endpoint del servizio. Gli externalIPs
non sono gestiti da Kubernetes e sono responsabilità dell'amministratore del cluster.
Nella specifica del servizio, gli externalIPs
possono essere specificati insieme a uno dei ServiceTypes
. Nell'esempio seguente, "my-service
" può essere accessibile dai client su "80.11.12.10:80
" (externalIP:port
)
Ingress
A differenza di tutti gli esempi precedenti, Ingress NON è un tipo di servizio. Invece, si trova di fronte a più servizi e agisce come un "router intelligente" o punto di ingresso 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 ingress predefinito di GKE creerà un HTTP(S) Load Balancer per te. Questo ti permetterà di fare routing basato sia su percorsi che su sottodomini verso i servizi di backend. Ad esempio, puoi inviare tutto su foo.tuodominio.com al servizio foo, e tutto sotto il percorso tuodominio.com/bar/ al servizio bar.
Il YAML per un oggetto Ingress su GKE con un L7 HTTP Load Balancer potrebbe apparire così:
Riferimenti
Last updated