Scopri i componenti di GCP Load Balancing e configura passo dopo passo un load balancer multi-cluster GKE disponibile a livello globale.

Una delle funzionalità che apprezzo di più di GCP è l'HTTP(S) Load Balancing esterno: un load balancer globale che fornisce un singolo indirizzo IP anycast (niente più DNS load balancing, finalmente!). Le richieste entrano nella rete globale di Google in uno dei point of presence (POP) edge più vicini all'utente¹ e vengono inoltrate via proxy alla regione più vicina con capacità disponibile. Il risultato è un setup di load balancing ad alta disponibilità, distribuito globalmente, scalabile e completamente gestito. Si può inoltre potenziare con la protezione DDoS e WAF di Cloud Armor, con Cloud CDN o con Identity-Aware Proxy (IAP) per mettere in sicurezza l'accesso alle applicazioni web.

A questo punto viene subito da pensare al load balancing multi-cluster con GKE, un tema che ricorre spesso fra le richieste dei nostri clienti. E sebbene al momento non esista un supporto nativo in GKE/Kubernetes,² GCP mette a disposizione tutti i building block necessari per configurarlo in autonomia.
Nella prima parte vedremo da vicino i componenti di GCP Load Balancing: seguiremo il percorso di una richiesta dal momento in cui entra nel sistema, capendo cosa rappresenta ciascun mattone del load balancing. Nella seconda parte configureremo passo dopo passo il load balancing su due cluster GKE.
Panoramica di GCP Load Balancing

Fig. 1: Panoramica di GCP Load Balancing
Partiamo da una panoramica ad alto livello del flusso di Load Balancing. La connessione HTTP(S) dal client viene terminata in una location edge dai Google Front End (GFE),³ in base alla configurazione del Target Proxy HTTP(S) e della Forwarding Rule. Il Target Proxy consulta le definizioni associate di URL Map e Backend Service per stabilire come instradare il traffico. Dai GFE viene poi aperta una nuova connessione e il traffico transita sulla rete Google fino al Backend integro più vicino con capacità disponibile. All'interno della regione, il traffico viene distribuito tra i singoli Backend Endpoint in base alla loro capacità.
Componenti di GCP Load Balancing

Fig. 2: Componenti di GCP Load Balancing
- Forwarding Rule — ogni regola è associata a un IP e a una porta specifici. Trattandosi di HTTP(S) load balancing globale, l'indirizzo sarà un IP globale anycast (eventualmente un IP statico riservato). La porta associata è quella su cui il load balancer accetta traffico dai client esterni.⁴
- Target HTTP(S) Proxy — il traffico viene terminato in base alla configurazione del Target Proxy. Ogni Target Proxy è collegato a una sola URL Map (relazione N:1). Nel caso del proxy HTTPS occorre inoltre associare almeno un certificato SSL e configurare la SSL Policy.
- URL Map — è il componente principale per la gestione del traffico e consente di instradare il traffico in ingresso tra diversi Backend Service (inclusi i bucket GCS). Il routing di base è per hostname e path, ma sono possibili logiche più avanzate: redirect URL, riscrittura URL e routing basato su header e parametri di query. Ogni regola indirizza il traffico verso un singolo Backend Service.
- Backend Service — è il raggruppamento logico dei backend di uno stesso servizio, con le relative opzioni di configurazione: distribuzione del traffico tra i singoli Backend, protocolli, session affinity o funzionalità come Cloud CDN, Cloud Armor o IAP. A ogni Backend Service è associato anche un Health Check.
- Health Check — definisce come vengono verificati i singoli backend endpoint per stabilire se sono attivi e serve a calcolare lo stato di salute complessivo di ciascun Backend. Al momento della creazione vanno indicati protocollo e porta, oltre ad alcuni parametri opzionali come intervallo di controllo, soglie di healthy e unhealthy o timeout. Un dettaglio importante: devono essere presenti regole firewall che consentano il traffico di health check da una serie di intervalli IP interni.⁵
- Backend — rappresenta un gruppo di endpoint in una determinata location. Nel caso di GKE, i nostri backend saranno Network Endpoint Group (NEG),⁶ uno per ciascuna zona del cluster GKE (i NEG di GKE sono zonali, mentre alcuni altri tipi di backend sono regionali).
- Backend Endpoint — è una combinazione di indirizzo IP e porta; nel caso di GKE con container-native load balancing⁷ punta direttamente ai singoli Pod.
Setup
Configureremo il load balancing multi-cluster per due servizi — Foo e Bar — distribuiti su due cluster (fig. 3). Useremo semplici regole basate sul path: ogni richiesta verso /foo/* andrà al servizio Foo e ogni richiesta verso /bar/* al servizio Bar.

Fig. 3: GKE Multi-Cluster Foo Bar
Prerequisiti
- 2 cluster GKE in modalità VPC-native, che chiameremo primary e secondary ⁸
- Un record DNS che punti all'IP statico
- Una versione recente della gcloud CLI
- Un clone del repository stepanstipl/gke-multi-cluster-native ⁹
git clone https://github.com/stepanstipl/gke-multi-cluster-native.gitcd gke-multi-cluster-native
Distribuire applicazioni e servizi sui cluster GKE

Fig. 4: K8s Demo App
Iniziamo distribuendo alcune semplici applicazioni demo su ciascun cluster. L'applicazione mostra i dettagli del cluster e della regione che servono la richiesta; il codice sorgente è disponibile su stepanstipl/k8s-demo-app.
Ripeti i passaggi seguenti su ciascun cluster.
Ottenere le credenziali per kubectl
gcloud container clusters get-credentials [cluster] \
--region [cluster-region]
Distribuire le applicazioni Foo e Bar
kubectl apply -f deploy-foo.yaml
kubectl apply -f deploy-bar.yaml
Puoi verificare che i Pod di entrambi i servizi siano attivi con kubectl get pods.
Creare i Service K8s per entrambe le applicazioni
kubectl apply -f svc-foo.yaml kubectl apply -f svc-bar.yaml
Nota l'annotazione cloud.google.com/neg: '{"exposed_ports": {"80":{}}}' sui servizi: indica a GKE di creare un NEG per il Service.
Per verificare che i servizi siano configurati correttamente, puoi inoltrare una porta locale con kubectl port-forward service/foo 8888:80 e accedere al servizio all'indirizzo http://localhost:8888/.
Ricordati di ripetere quanto sopra su tutti i cluster.
Configurare i componenti di Load Balancing (GCLB)
Creare un Health Check
gcloud compute health-checks create http health-check-foobar \
--use-serving-port \
--request-path="/healthz"
Creare i Backend Service
Crea un backend service per ciascun servizio, più uno aggiuntivo da usare come backend predefinito per il traffico che non corrisponde alle regole basate sul path.
gcloud compute backend-services create backend-service-default \
--globalgcloud compute backend-services create backend-service-foo \
--global \
--health-checks health-check-foobargcloud compute backend-services create backend-service-bar \
--global \
--health-checks health-check-foobar
Creare la URL Map
gcloud compute url-maps create foobar-url-map \
--global \
--default-service backend-service-default
Aggiungere le regole di path alla URL Map
gcloud compute url-maps add-path-matcher foobar-url-map \
--global \
--path-matcher-name=foo-bar-matcher \
--default-service=backend-service-default \
--backend-service-path-rules='/foo/*=backend-service-foo,/bar/*=backend-service-bar'
Riservare un indirizzo IP statico
gcloud compute addresses create foobar-ipv4 \
--ip-version=IPV4 \
--global
Configurare il DNS
Punta il tuo DNS all'indirizzo IP statico riservato in precedenza. Annota l'indirizzo IP che hai richiesto:
gcloud compute addresses list --global
Crea un record A foobar.[your_domain_name] che punti a questo IP. Per gestire il record puoi usare Cloud DNS o qualsiasi altro servizio di tua preferenza. Completa questo passaggio prima di procedere.¹⁰
Creare un certificato SSL gestito
gcloud beta compute ssl-certificates create foobar-cert \
--domains "foobar.[your_domain_name]"
Creare il Target HTTPS Proxy
gcloud compute target-https-proxies create foobar-https-proxy \
--ssl-certificates=foobar-cert \
--url-map=foobar-url-map
Creare la Forwarding Rule
gcloud compute forwarding-rules create foobar-fw-rule \
--target-https-proxy=foobar-https-proxy \
--global \
--ports=443 \
--address=foobar-ipv4
Verificare il certificato TLS
L'intero processo di provisioning del certificato può richiedere un po' di tempo. Puoi verificarne lo stato con:
gcloud beta compute ssl-certificates describe foobar-cert
Se la configurazione è corretta, managed.status dovrebbe passare ad ACTIVE entro circa 60 minuti, di solito anche prima.
Collegare i Service K8s al Load Balancer
GKE ha effettuato il provisioning dei NEG per ciascun Service K8s distribuito con l'annotazione cloud.google.com/neg. Ora dobbiamo aggiungere questi NEG come backend ai backend service corrispondenti.
Recuperare i nomi dei NEG creati
kubectl get svc \
-o custom-columns='NAME:.metadata.name,NEG:.metadata.annotations.cloud\.google\.com/neg-status'
Annota nome del NEG e zone per ciascun servizio.
Ripeti l'operazione su tutti i cluster GKE.
Aggiungere i NEG ai Backend Service
Ripeti i comandi seguenti per ogni NEG e ogni zona di entrambi i cluster. Assicurati di usare solo i NEG appartenenti al servizio Foo.
gcloud compute backend-services add-backend backend-service-foo \
--global \
--network-endpoint-group [neg_name] \
--network-endpoint-group-zone=[neg_zone] \
--balancing-mode=RATE \
--max-rate-per-endpoint=100
Stessa cosa per il servizio Bar: ripeti per entrambi i cluster, per ogni NEG e ogni zona:
gcloud compute backend-services add-backend backend-service-bar \
--global \
--network-endpoint-group [neg_name] \
--network-endpoint-group-zone=[neg_zone] \
--balancing-mode=RATE \
--max-rate-per-endpoint=100
Consentire il traffico GCLB
gcloud compute firewall-rules create fw-allow-gclb \
--network=[vpc_name] \
--action=allow \
--direction=ingress \
--source-ranges=130.211.0.0/22,35.191.0.0/16 \
--rules=tcp:8080
Verificare che i backend siano integri
gcloud compute backend-services get-health \
--global backend-service-foo gcloud compute backend-services get-health \
--global backend-service-bar
In genere dovresti vedere 6 backend (3 per cluster,¹¹ 1 per ogni zona) per ciascun backend service, con healthState: HEALTHY. Dopo aver aggiunto le regole firewall potrebbe volerci un po' prima che tutti i backend risultino integri.
Verificare che tutto funzioni
Esegui curl sul tuo nome DNS https://foobar.[your-domain] (o aprilo nel browser). Sulla root dovresti ricevere un 502, perché non abbiamo aggiunto backend per il servizio predefinito.
curl -v "https://foobar.[your-domain]"
Ora prova con curl sui path dei singoli servizi, https://foobar.[your-domain]/foo/ oppure https://foobar.[your-domain]/bar/: dovresti ricevere un 200 e il contenuto del servizio corrispondente.
curl -v "https://foobar.[your-domain]/foo/"
curl -v "https://foobar.[your-domain]/bar/"
Riprovando più volte, dovresti vedere il traffico servito da Pod e cluster diversi.¹²
Se simuli un po' di traffico — ad esempio con uno dei miei strumenti CLI preferiti, vegeta — puoi osservare con chiarezza la distribuzione del traffico tra i backend nella GCP Console. Vai su Network services -> sezione Load balancing -> seleziona il tuo load balancer -> scheda Monitoring e seleziona il backend corrispondente. Dovresti vedere una dashboard simile alla fig. 5.

Fig. 5: GKE Console — Load Balancing (entrambi i cluster erano nella stessa regione, quindi il traffico è bilanciato in modo uniforme su tutti i backend)
È il momento giusto per sperimentare un po'. Vediamo cosa accade con cluster nella stessa regione e cosa cambia se sono in regioni diverse. Aumenta il carico e osserva il traffico riversarsi su un'altra regione (suggerimento: ricordi --max-rate-per-endpoint usato prima?). Prova a mettere offline uno dei cluster e guarda cosa succede. E se aggiungessi un terzo cluster?
(opzionale) `gke-autoneg-controller`
Nota l'annotazione anthos.cft.dev/autoneg sui Service K8s. Non è necessaria per la nostra configurazione, ma in alternativa puoi distribuire gke-autoneg-controller ¹³ nel cluster e usarlo per associare automaticamente i NEG creati da GKE ai backend service corrispondenti, risparmiando così un po' di lavoro manuale tedioso.
Ottimo lavoro!
Ed è tutto. Abbiamo illustrato lo scopo dei singoli componenti GCLB e mostrato come configurare il load balancing multi-cluster tra servizi distribuiti in 2 o più cluster GKE in regioni diverse. Per un utilizzo in produzione consiglio di automatizzare il setup con uno strumento di configuration management come Terraform.
Una configurazione di questo tipo aumenta la disponibilità del servizio — perché più cluster GKE indipendenti servono il traffico — e riduce anche la latenza. Nel caso di HTTPS, il time to first byte è più breve perché la negoziazione TLS iniziale avviene sul server GFE vicino all'utente. E con più cluster, la richiesta viene servita da quello più vicino all'utente.
Fammi sapere se il contenuto ti è stato utile e se hai altre domande, qui o su @stepanstipl. 🚀🚀🚀 Serve fast and prosper!
- [1] Oltre 90 location in tutto il mondo — Load Balancing — Locations e vengono inoltrate via proxy alla regione più vicina con capacità disponibile.
- [2] Mettendo per ora da parte Anthos. Anthos è una piattaforma di application management che permette di eseguire cluster K8s on-prem e su altri cloud, e che estende anche le funzionalità dei cluster GKE, incluso il multi-cluster ingress controller .)
- [3] I GFE sono sistemi distribuiti scalabili e definiti via software, dislocati negli Edge POP.
- [4] La porta può essere 80 o 8080 se il target è un proxy HTTP, oppure 443 nel caso di proxy HTTPS.
- [5] Per l'External HTTP(S) Load Balancing questi intervalli sono
35.191.0.0/16e130.211.0.0/22. - [6] Panoramica dei Network Endpoint Group
- [7] Container-native load balancing richiede un cluster in modalità VPC-native e consente ai load balancer di puntare direttamente ai singoli Pod (anziché ai nodi del cluster).
- [8] Usare cluster in regioni diverse è più interessante.
- [9] Tutti i file citati nei comandi di questo post fanno riferimento alla root del repository.
- [10] Il record DNS deve essere già attivo affinché il provisioning del certificato SSL gestito da Google vada a buon fine. In caso contrario, il certificato potrebbe risultare definitivamente fallito (perché la Certificate Authority non riuscirà a firmarlo) e dovrà essere ricreato.
- [11] Si presume che tu abbia usato cluster regionali distribuiti su 3 zone ciascuno; in caso contrario, regola di conseguenza.
- [12] Se hai cluster in regioni diverse, GCLB tenderà a servire il traffico da quello più vicino al client: non aspettarti quindi un bilanciamento uniforme tra le regioni.
- [13] Non entro qui nei dettagli su come distribuirlo e usarlo: segui il readme . In pratica, basta aggiungere al service un'annotazione con il nome del NEG, ad es.
anthos.cft.dev/autoneg: '{"name":"autoneg_test", "max_rate_per_endpoint":1000}'.