Configura il bilanciamento del carico di livello 2 in bundle

Il bilanciamento del carico integrato ti consente di eseguire i bilanciatori del carico per il tuo cluster Google Distributed Cloud sui nodi del cluster stessi. Keepalived e HAProxy gestiscono l'indirizzo IP virtuale (VIP) del control plane, mentre MetalLB in modalità di livello 2 fornisce il bilanciamento del carico del piano dati per i servizi di tipo LoadBalancer.

I bilanciatori del carico possono essere eseguiti sui nodi del control plane o su un pool di nodi del bilanciatore del carico dedicato. Puoi anche eseguire i bilanciatori del carico del control plane e del data plane su nodi separati.

Per esempi di topologie di bilanciamento del carico supportate, consulta Panoramica dei bilanciatori del carico.

Requisiti

  • Tutti i nodi del bilanciatore del carico devono trovarsi nella stessa subnet di livello 2.
  • Tutti i VIP devono trovarsi nella subnet dei nodi del bilanciatore del carico ed essere instradabili tramite il gateway della subnet.
  • Il gateway della subnet del bilanciatore del carico deve ascoltare i messaggi ARP non richiesti e inoltrare i pacchetti ARP ai nodi del bilanciatore del carico.

Campi di configurazione

Modifica la sezione cluster.spec.loadBalancer del file di configurazione del cluster per configurare il bilanciamento del carico in bundle. Per informazioni sui file di configurazione del cluster ed esempi di configurazioni valide, consulta una delle seguenti pagine:

loadBalancer.mode

Questo valore deve essere bundled per attivare il bilanciamento del carico in bundle.

loadBalancer.ports.controlPlaneLBPort

Questo valore specifica la porta di destinazione da utilizzare per il traffico inviato al control plane Kubernetes (server API Kubernetes).

loadBalancer.vips.controlPlaneVIP

Questo valore specifica l'indirizzo IP di destinazione da utilizzare per il traffico inviato al control plane Kubernetes (server API Kubernetes). Questo indirizzo IP deve trovarsi nella stessa subnet di livello 2 dei nodi del cluster. Non elencare questo indirizzo nella sezione address pools del file di configurazione.

loadBalancer.vips.ingressVIP

Questo valore specifica l'indirizzo IP da utilizzare per i servizi dietro il bilanciatore del carico per il traffico in entrata. Questo campo non è consentito nei file di configurazione del cluster di amministrazione. Questo indirizzo deve essere elencato nella sezione address pools della configurazione.

loadBalancer.addressPools

Questa sezione della configurazione contiene uno o più pool di indirizzi. Ogni pool di indirizzi specifica un elenco di intervalli di indirizzi IP. Quando crei un servizio di tipo LoadBalancer, gli indirizzi IP esterni per il servizio vengono scelti da questi intervalli.

I pool di indirizzi sono specificati nel seguente formato:

- name: POOL_NAME
  avoidBuggyIPs: BOOLEAN
  manualAssign: BOOLEAN
  addresses:
  - IP_RANGE
  - IP_RANGE2
  • name: il nome del pool di indirizzi, pool-name, per i tuoi scopi organizzativi. Questo campo è immutabile.
  • avoidBuggyIPs: (facoltativo) true o false. Se true, il pool omette gli indirizzi IP che terminano con .0 e .255. Alcuni componenti hardware di rete eliminano il traffico verso questi indirizzi speciali. Puoi omettere questo campo, il cui valore predefinito è false. Questo campo è modificabile.
  • manualAssign: (facoltativo) true o false. Se true, gli indirizzi in questo pool non vengono assegnati automaticamente ai servizi Kubernetes. Se true, un indirizzo IP in questo pool viene utilizzato solo se viene specificato esplicitamente da un servizio. Puoi omettere questo campo, il cui valore predefinito è false. Questo campo è modificabile.
  • addresses Un elenco di uno o più intervalli di indirizzi IP non sovrapposti. ip-range può essere specificato nella notazione CIDR (ad esempio 198.51.100.0/24) o nella notazione di intervallo (ad esempio 198.51.100.0-198.51.100.10, senza spazi intorno al trattino). Questo campo è immutabile.

Gli intervalli di indirizzi IP nell'elenco addresses non devono sovrapporsi e devono trovarsi nella stessa subnet dei nodi che eseguono i bilanciatori del carico.

loadBalancer.nodePoolSpec

Questa sezione della configurazione specifica un elenco di nodi su cui eseguire i bilanciatori del carico. Per impostazione predefinita, i nodi del bilanciatore del carico possono eseguire workload normali; non esiste un taint speciale su questi nodi. Sebbene i nodi nel pool di nodi del bilanciatore del carico possano eseguire workload, sono separati dai nodi nei node pool dei worker. Non puoi includere un determinato nodo del cluster in più di un pool di nodi. Gli indirizzi IP dei nodi sovrapposti tra i pool di nodi bloccano la creazione del cluster e altre operazioni del cluster.

Se vuoi impedire l'esecuzione dei workload su un nodo nel pool di nodi del bilanciatore del carico, aggiungi la seguente incompatibilità al nodo:

node-role.kubernetes.io/load-balancer:NoSchedule

Google Distributed Cloud aggiunge tolleranze per questa incompatibilità ai pod necessari per il bilanciamento del carico.

L'esempio seguente mostra un pool di nodi di bilanciamento del carico con due nodi. Il primo nodo ha un indirizzo IP standard nodePoolSpec.nodes.address ("1.2.3.4") e un indirizzo IP Kubernetes nodePoolSpec.nodes.k8sIP (10.0.0.32). Quando specifichi l'indirizzo k8sIP facoltativo per un nodo, questo viene dedicato alla gestione del traffico di dati per il nodo, ad esempio richieste e risposte per l'API Kubernetes, il kubelet e i workload. In questo caso, l'indirizzo IP standard nodePoolSpec.nodes.address viene utilizzato per le connessioni SSH al nodo per le operazioni amministrative del cluster. Se non specifichi un indirizzo k8sIP, l'indirizzo IP del nodo standard gestisce tutto il traffico per il nodo.

nodePoolSpec:
  nodes:
  - address: 1.2.3.4
    k8sIP: 10.0.0.32
  - address: 10.0.0.33

Per impostazione predefinita, tutti i nodi nel pool di nodi del bilanciatore del carico devono trovarsi nella stessa subnet di livello 2 dei VIP del bilanciatore del carico configurati nella sezione loadBalancer.addressPools del file di configurazione. Tuttavia, se specifichi un indirizzo IP Kubernetes k8sIP per un nodo, solo questo indirizzo deve trovarsi nella stessa subnet di livello 2 degli altri VIP del bilanciatore del carico.

Se nodePoolSpec non è impostato, i bilanciatori del carico integrati vengono eseguiti sui nodi del control plane. Se possibile, ti consigliamo di eseguire i bilanciatori del carico su pool di nodi separati.

Bilanciamento del carico del control plane

Il bilanciatore del carico del control plane gestisce l'indirizzo IP virtuale (VIP) del control plane. Google Distributed Cloud esegue Keepalived e HAProxy come pod statici di Kubernetes sui nodi del bilanciatore del carico per annunciare il VIP del control plane. Keepalived utilizza il Virtual Router Redundancy Protocol (VRRP) sui nodi del bilanciatore del carico per l'alta affidabilità.

Bilanciamento del carico del piano dati

Il bilanciatore del carico del piano dati è per tutti i servizi Kubernetes di tipo LoadBalancer. Google Distributed Cloud utilizza MetalLB in esecuzione in modalità Layer 2 per il bilanciamento del carico del piano dati. Il bilanciamento del carico del piano dati può essere configurato solo tramite Google Distributed Cloud. Non modificare direttamente ConfigMap di MetalLB. Puoi utilizzare tutte le funzionalità di MetalLB, inclusa la condivisione degli indirizzi IP tra i servizi. Per informazioni sulle funzionalità, consulta la documentazione di MetalLB.

MetalLB esegue un pod speaker su ogni nodo utilizzando un daemonset, utilizzando memberlist per l'alta affidabilità. Esiste un nodo del bilanciatore del carico dedicato MetalLB per ogni servizio Kubernetes, anziché uno per l'intero cluster. In questo modo, il traffico viene distribuito tra i nodi del bilanciatore del carico se sono presenti più servizi.

I bilanciatori del carico del piano dati possono essere eseguiti sui nodi del control plane o su un sottoinsieme di nodi worker. Il raggruppamento dei bilanciatori del carico del data plane sui nodi del control plane aumenta l'utilizzo dei nodi del control plane. Inoltre, il raggruppamento sui nodi del control plane aumenta anche il rischio di sovraccarico del control plane e il profilo di rischio delle informazioni riservate sul control plane, come le chiavi SSH.

Separazione del bilanciatore del carico

Prima della versione 1.32, quando configuri il bilanciamento del carico di livello 2 con MetalLB, i bilanciatori del carico del control plane e i bilanciatori del carico del data plane vengono eseguiti sugli stessi nodi. A seconda della configurazione, i bilanciatori del carico vengono eseguiti tutti sui nodi del control plane o tutti nel pool di nodi del bilanciatore del carico.

Il seguente diagramma mostra la configurazione predefinita del bilanciatore del carico integrato con i bilanciatori del carico del control plane e del data plane in esecuzione sui nodi del control plane o entrambi in esecuzione nel pool di nodi del bilanciatore del carico:

Configurazione del bilanciatore del carico predefinito

Con i cluster della versione 1.32, puoi configurare i bilanciatori del carico del control plane in modo che vengano eseguiti sui nodi del control plane e i bilanciatori del carico del piano dati in modo che vengano eseguiti nel pool di nodi del bilanciatore del carico. Puoi specificare questa separazione dei bilanciatori del carico quando crei un nuovo cluster versione 1.32 oppure puoi aggiornare un cluster versione 1.32 per eseguire la migrazione dei bilanciatori del carico del piano dati dai nodi del control plane al pool di nodi del bilanciatore del carico.

La configurazione del cluster per i bilanciatori del carico separati dovrebbe essere simile al seguente esempio:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: hybrid-ha-lb
  namespace: cluster-hybrid-ha-lb
spec:
  type: hybrid
  profile: default
  anthosBareMetalVersion: 1.36
  gkeConnect:
    projectID: project-fleet
  controlPlane:
    loadBalancer:
      mode: bundled
    nodePoolSpec:
      nodes:
      - address: 10.200.0.2
      - address: 10.200.0.3
      - address: 10.200.0.4
  clusterNetwork:
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...
  loadBalancer:
    mode: bundled
    ...
    nodePoolSpec:
      nodes:
      - address: 10.200.0.5
      - address: 10.200.0.6
      - address: 10.200.0.7
  clusterOperations:
  ...

Bilanciatori del carico separati durante la creazione di un cluster

Se stai creando un nuovo cluster versione 1.32 o successiva, puoi configurare i bilanciatori del carico in modo che eseguano i bilanciatori del carico del control plane sui nodi del control plane e i bilanciatori del carico del data plane sul pool di nodi del bilanciatore del carico.

Il seguente diagramma mostra i bilanciatori del carico del control plane e del data plane separati su nodi diversi:

Bilanciatori del carico del control plane e del piano dati separati

Per separare i bilanciatori del carico durante la creazione di un cluster, segui questi passaggi:

  1. Nel file di configurazione del cluster, specifica un pool di nodi del bilanciatore del carico con loadBalancer.nodePoolSpec come descritto nella sezione loadBalancer.nodePoolSpec di questo documento.

  2. Aggiungi controlPlane.loadBalancer.mode al file di configurazione del cluster e imposta il valore mode su bundled.

  3. Completa la configurazione del cluster ed esegui bmctl create cluster per creare il cluster.

Esegui la migrazione dei bilanciatori del carico del data plane dal control plane

Se hai un cluster esistente versione 1.32 o successiva in cui non sono impostati né controlPlane.loadBalancer.mode né loadBalancer.nodePoolSpec, sia il bilanciatore del carico del control plane sia il bilanciatore del carico del data plane vengono eseguiti nel pool di nodi del control plane. Puoi aggiornare il cluster per eseguire la migrazione del bilanciatore del carico del piano dati a un pool di nodi del bilanciatore del carico.

Il seguente diagramma mostra i bilanciatori del carico del control plane e del data plane separati dopo la migrazione del bilanciatore del carico del data plane dai nodi del control plane:

Bilanciatore del carico del piano dati di cui è stata eseguita la migrazione al pool di nodi del bilanciatore del carico

Per eseguire la migrazione del bilanciatore del carico del piano dati a un pool di nodi del bilanciatore del carico quando aggiorni un cluster, segui questi passaggi:

  1. Nel file di configurazione del cluster, specifica un pool di nodi del bilanciatore del carico con loadBalancer.nodePoolSpec come descritto nella sezione loadBalancer.nodePoolSpec di questo documento.

  2. Aggiungi controlPlane.loadBalancer.mode al file di configurazione del cluster e imposta il valore mode su bundled.

  3. Aggiorna il cluster eseguendo il seguente comando:

    bmctl update cluster -c CLUSTER_NAME --kubeconfig=ADMIN_KUBECONFIG
    

    Sostituisci quanto segue:

    • CLUSTER_NAME: il nome del cluster che stai aggiornando.

    • ADMIN_KUBECONFIG: il percorso del file kubeconfig del cluster di amministrazione.

Conservazione dell'indirizzo IP di origine del client

Il servizio LoadBalancer creato con la soluzione di bilanciamento del carico di livello 2 in bundle utilizza l'impostazione predefinita Cluster per la policy del traffico esterno. Questa impostazione, spec.externalTrafficPolicy: Cluster, instrada il traffico esterno agli endpoint a livello di cluster, ma oscura anche l'indirizzo IP di origine del client.

Google Distributed Cloud supporta due metodi per conservare l'indirizzo IP di origine del client:

  • Imposta la modalità di forwarding per il bilanciamento del carico su Direct Server Return (DSR). Per saperne di più sulla modalità di forwarding DSR, incluse le istruzioni per attivarla, consulta Configura la modalità di forwarding del bilanciamento del carico.

  • Imposta la policy del traffico esterno su locale per il servizio LoadBalancer e configura i servizi e l'Ingress correlati di conseguenza. Le sezioni seguenti descrivono come configurare il cluster per utilizzare questo metodo.

Servizi LoadBalancer

Quando utilizzi externalTrafficPolicy: Local nei tuoi servizi LoadBalancer, imposta i pod dell'applicazione in modo che vengano eseguiti esattamente sui nodi del bilanciatore del carico. Per apportare questa modifica, aggiungi il seguente nodeSelector ai pod dell'applicazione:

apiVersion: v1
kind: Pod
...
spec:
  nodeSelector:
      baremetal.cluster.gke.io/lbnode: "true"
...

Servizi NodePort

Kubernetes esegue la Network Address Translation dell'origine (SNAT) per i servizi NodePort. Per conservare gli indirizzi IP di origine del client, imposta service.spec.externalTrafficPolicy su Local. Kubernetes non eseguirà più SNAT, ma devi assicurarti che i pod siano in esecuzione esattamente sull'IP del nodo che hai scelto.

In entrata

Se le tue applicazioni sono servizi HTTP, puoi ottenere la visibilità dell'IP client configurando i componenti Ingress:

  1. Apri il servizio istio-ingress per modificarlo:

    kubectl edit service -n gke-system istio-ingress
    
  2. Aggiungi externalTrafficPolicy: Local a spec, salva ed esci dall'editor.

    apiVersion: v1
    kind: Service
    ...
    spec:
    ...
      externalTrafficPolicy: Local
    
  3. Apri il deployment istio-ingress per la modifica:

    kubectl edit deployment -n gke-system istio-ingress
    
  4. Aggiungi il seguente nodeSelector al deployment, salva ed esci dall'editor.

    apiVersion: apps/v1
    kind: Deployment
    ...
    spec:
      ...
      template:
        ...
        spec:
          ...
          nodeSelector:
              baremetal.cluster.gke.io/lbnode: "true"
    ...
    

Ora, tutti i servizi dietro Ingress vedono un'intestazione X-Forwarded-For con l'IP client, come nell'esempio seguente:

X-Forwarded-For: 21.0.104.4