Questo tutorial illustra come costruire una service mesh multicluster privata con Istio 1.5 e Service Mesh Hub per la federazione delle mesh. Il tutto sfruttando un Internal Load Balancer (ILB) per collegare i workloads Istio in esecuzione su cluster Private Google Kubernetes Engine (GKE) distribuiti su più region.

Introduzione
Istio 1.5 è uscito il 5 marzo e questa major release porta con sé diverse novità importanti; il supporto a Hashicorp Vault come CA esterna, però, è ancora in lavorazione. Ho quindi cominciato a esplorare quali altre strade fossero percorribili per gestire in sicurezza la root CA condivisa, e mi sono imbattuto nel progetto open-source di solo.io: Service Mesh Hub. Si tratta di una soluzione che permette di unificare l'identità di root tra più installazioni di service mesh: tutte le CA intermedie risultano firmate dalla stessa Root CA e l'mTLS end-to-end tra cluster e servizi può essere stabilito correttamente.
Come funziona
In questo tutorial:
realizzeremo la seguente architettura:

Le ragioni per isolare i cluster Google Kubernetes Engine (GKE) dall'accesso a internet sono diverse, ma la principale è la sicurezza. In un cluster privato i nodi hanno solo indirizzi privati RFC 1918 e dialogano con l'endpoint privato del master attraverso una rete privata, impedendo qualsiasi accesso dall'esterno, autorizzato o meno.
L'Internal Load Balancer TCP/UDP offre una funzionalità beta poco conosciuta: Global Access. Consente ai client di qualsiasi region della rete VPC di raggiungere l'Internal Load Balancer TCP/UDP. Senza Global Access, il traffico generato dai client all'interno della VPC deve restare nella stessa region del load balancer. Nei cluster Kubernetes privati, Global Access si abilita per ogni singolo Service tramite questa annotazione:
networking.gke.io/internal-load-balancer-allow-global-access:"true".
Nell'implementazione di esempio annoteremo direttamente il Kubernetes Service ingressGateway per fare il provisioning di un ILB GCP con Global Access. Una volta applicato Global Access, avremo connettività di rete tra i cluster privati distribuiti in region differenti.
Fatto! Notiamo che il servizio A (sleep.foo.cluster-1) deve dialogare con il servizio B (httpbin.bar.cluster-2), che si trova in un'altra mesh. Quando un servizio in una mesh ha bisogno di un servizio appartenente a un'altra mesh, identità e trust devono essere federati tra le due. Per riuscirci occorre scambiare il trust bundle tra le mesh.
Service Mesh Hub permette di raggruppare più mesh in un oggetto chiamato VirtualMesh. Creando questa risorsa si indica alla Service Mesh di stabilire un'identità di root condivisa tra i cluster della Virtual Mesh e di federare i servizi.
Come funziona il processo di root condivisa

Con la creazione della risorsa VirtualMesh:
- Service Mesh Hub avvia il processo per unificare l'identità con una root condivisa.
- Service Mesh Hub usa un agent CSR (Certificate Signing Request) su ciascun cluster per generare una nuova coppia chiave/certificato che diventerà la CA intermedia. La CA intermedia di ogni cluster sarà presente e utilizzata dalla mesh di quel cluster.
- Crea quindi una Certificate Signing Request, rappresentata dalla CR VirtualMeshCertificateSigningRequest.
- Service Mesh Hub firma poi il certificato con la Root CA indicata nella VirtualMesh.
- Completato il processo, è necessario riavviare il control plane
istiod: il control plane di Istio carica la CA per Citadel ma non la ruota con la frequenza necessaria. È un aspetto che verrà migliorato nelle prossime versioni di Istio.
Stabilito il trust, Service Mesh Hub inizia a federare i servizi, generando automaticamente le service entry al posto vostro! rendendoli così raggiungibili tra cluster diversi.

In questo tutorial il flag enforceAccessControl è disabilitato: sarà argomento di uno dei prossimi articoli, dove vedremo come Istio metta a disposizione funzionalità di sicurezza per un'identità solida, policy efficaci e strumenti di authentication, authorization e audit (AAA) a tutela di servizi e dati.
Codice del tutorial
Le istruzioni passo passo di questo tutorial sono disponibili qui:
Riferimenti
- Codice di implementazione — https://github.com/palimarium/multicluster-istio-smh-private-gke
- GCP — Private GKE Clusters — https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters
- GCP — TCP/UDP Internal Load Balancer — https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing
- Istio — Configurare il servizio di esempio — https://istio.io/docs/setup/install/multicluster/gateways/#configure-the-example-services
- Service Mesh Hub — Concetti — https://docs.solo.io/service-mesh-hub/latest/concepts/
In questo tutorial ho mostrato quanto sia semplice implementare una service mesh con comunicazione intra-mesh. La comunicazione service-to-service avviene internamente tramite traffico mTLS sicuro, senza mai uscire dalla Global Network di Google Cloud.