Konfigurieren Sie gebündeltes Load-Balancing mit MetalLB

Auf dieser Seite wird beschrieben, wie Sie das gebündelte Load-Balancing mit MetalLB für Google Distributed Cloud konfigurieren. MetalLB-Load-Balancer werden entweder auf einem dedizierten Pool von Worker-Knoten oder auf denselben Knoten wie die Steuerungsebene ausgeführt.

Unter Load-Balancer-Übersicht finden Sie Beispiele für Load-Balancing-Topologien, die in Google Distributed Cloud verfügbar sind.

Voraussetzungen

  • Alle Load-Balancer-Knoten müssen sich im selben Layer-2-Subnetz befinden.
  • Alle VIPs müssen sich im Subnetz des Load-Balancer-Knotens befinden und über das Gateway des Subnetzes routingfähig sein.
  • Das Gateway des Load-Balancer-Subnetzes muss ressourcensparende ARP-Nachrichten überwachen und ARP-Pakete an die Load-Balancer-Knoten weiterleiten.

Felder für die Konfiguration

Bearbeiten Sie den Abschnitt cluster.spec.loadBalancer der Cluster-Konfigurationsdatei, um das gebündelte Load-Balancing zu konfigurieren. Informationen zu Clusterkonfigurationsdateien und Beispiele für gültige Konfigurationen finden Sie in den folgenden Hilfeartikeln:

loadBalancer.mode

Dieser Wert muss bundled sein, um das gebündelte Load-Balancing zu aktivieren.

loadBalancer.ports.controlPlaneLBPort

Dieser Wert gibt den Zielport an, der für Traffic verwendet werden soll, der an die Kubernetes-Steuerungsebene gesendet wird (die Kubernetes API-Server).

loadBalancer.vips.controlPlaneVIP

Dieser Wert gibt die Ziel-IP-Adresse an, die für den Traffic an die Kubernetes-Steuerungsebene (die Kubernetes API-Server) verwendet werden soll. Diese IP-Adresse muss sich im selben Layer-2-Subnetz wie die Knoten im Cluster befinden. Listen Sie diese Adresse nicht im Abschnitt address pools der Konfigurationsdatei auf.

loadBalancer.vips.ingressVIP

Dieser Wert gibt die IP-Adresse an, die für Dienste hinter dem Load-Balancer für eingehenden Traffic verwendet werden soll. Dieses Feld ist in Konfigurationsdateien für Administratorcluster nicht zulässig. Diese Adresse muss im Abschnitt Adresspools der Konfiguration aufgeführt sein.

loadBalancer.addressPools

Dieser Abschnitt der Konfiguration enthält einen oder mehrere Adresspools. Jeder Adressbereich gibt eine Liste von IP-Adressbereichen an. Wenn Sie einen Dienst vom Typ LoadBalancer erstellen, werden die externen IP-Adressen für den Dienst aus diesen Bereichen ausgewählt.

Adresspools werden im folgenden Format angegeben:

- name: POOL_NAME
  avoidBuggyIPs: BOOLEAN
  manualAssign: BOOLEAN
  addresses:
  - IP_RANGE
  - IP_RANGE2
  • name: Der Name des Adresspools (pool-name) für Ihre eigenen Organisationszwecke. Dieses Feld ist unveränderlich.
  • avoidBuggyIPs: (Optional) true oder false. Bei true gibt der Pool IP-Adressen aus, die auf .0 und .255 enden. Einige Netzwerkhardware führt Traffic zu diesen speziellen Adressen auf. Sie können dieses Feld weglassen. Der Standardwert ist false. Dieses Feld ist veränderlich.
  • manualAssign: (Optional) true oder false. Bei true werden Adressen in diesem Pool nicht automatisch Kubernetes-Diensten zugewiesen. Bei true wird eine IP-Adresse in diesem Pool nur verwendet, wenn sie explizit von einem Dienst angegeben wird. Sie können dieses Feld weglassen. Der Standardwert ist false. Dieses Feld ist veränderlich.
  • addresses Eine Liste mit einem oder mehreren nicht überlappenden IP-Adressbereichen. ip-range kann entweder in CIDR-Notation (z. B. 198.51.100.0/24) oder in Bereichsnotation angegeben werden (z. B. 198.51.100.0-198.51.100.10, ohne Leerzeichen um den Bindestrich). Dieses Feld ist unveränderlich.

Die IP-Adressbereiche in der addresses-Liste dürfen sich nicht überschneiden und müssen sich im selben Subnetz wie die Knoten befinden, auf denen Load-Balancer ausgeführt werden.

loadBalancer.nodePoolSpec

In diesem Abschnitt der Konfiguration wird eine Liste von Knoten angegeben, auf denen Load-Balancer ausgeführt werden sollen. Load-Balancer-Knoten können standardmäßig reguläre Arbeitslasten ausführen. Es gibt keine spezielle Markierung auf diesen Knoten. Obwohl Knoten im Load-Balancer-Knotenpool Arbeitslasten ausführen können, sind sie von den Knoten in den Worker-Knotenpools getrennt. Ein bestimmter Clusterknoten kann nicht in mehr als einem Knotenpool enthalten sein. Überlappende Knoten-IP-Adressen zwischen Knotenpools verhindern die Clustererstellung und andere Cluster-Vorgänge.

Wenn Sie verhindern möchten, dass Arbeitslasten auf einem Knoten im Load Balancer-Knotenpool ausgeführt werden, fügen Sie dem Knoten die folgende Markierung hinzu:

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

Google Distributed Cloud fügt den Pods, die für das Load Balancing erforderlich sind, Toleranzen für diese Markierung hinzu.

Das folgende Beispiel zeigt einen Load-Balancing-Knotenpool mit zwei Knoten. Der erste Knoten hat eine Standard-IP-Adresse nodePoolSpec.nodes.address ('1.2.3.4') und eine Kubernetes-IP-Adresse nodePoolSpec.nodes.k8sIP (10.0.0.32). Wenn Sie die optionale k8sIP Adresse für einen Knoten angeben, ist diese für die Verarbeitung von Daten-Traffic für den Knoten vorgesehen, z. B. Anfragen und Antworten für die Kubernetes API, das Kubelet und Arbeitslasten. In diesem Fall wird die Standard-IP-Adresse nodePoolSpec.nodes.address für SSH-Verbindungen zum Knoten für administrative Cluster-Vorgänge verwendet. Wenn Sie keine k8sIP-Adresse angeben, verarbeitet die Standardknoten-IP-Adresse den gesamten Traffic für den Knoten.

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

Alle Knoten im Knotenpool des Load-Balancers müssen sich standardmäßig im selben Layer-2-Subnetz befinden wie die Load-Balancer-VIPs, die im Abschnitt loadBalancer.addressPools der Konfigurationsdatei konfiguriert wurden. Wenn Sie jedoch eine Kubernetes-IP-Adresse k8sIP für einen Knoten angeben, muss sich nur diese Adresse im selben Layer-2-Subnetz befinden wie die anderen Load-Balancer-VIPs.

Wenn nodePoolSpec nicht festgelegt ist, werden die gebündelten Load-Balancer auf den Knoten der Steuerungsebene ausgeführt. Wir empfehlen Ihnen, Load-Balancer nach Möglichkeit auf separaten Knotenpools auszuführen.

Load-Balancing auf Steuerungsebene

Der Load-Balancer stellt die virtuelle IP-Adresse (VIP) der Steuerungsebene bereit. Google Distributed Cloud führt Keepalived und HAProxy als statische Kubernetes-Pods auf den Load-Balancer-Knoten aus, um den VIP der Steuerungsebene anzukündigen. Keepalived verwendet das Virtual Router Redundancy Protocol (VRRP) auf den Load-Balancer-Knoten zur Hochverfügbarkeit.

Load-Balancing der Datenebene

Der Datenebenen-Load-Balancer gilt für alle Kubernetes-Dienste vom Typ LoadBalancer. Google Distributed Cloud verwendet MetalLB , das im Layer-2-Modus ausgeführt wird, um das Load-Balancing auf Datenebene zu ermöglichen. Das Load-Balancing für die Datenebene kann nur über Google Distributed Cloud konfiguriert werden. Ändern Sie die MetalLB-ConfigMap nicht direkt. Sie können alle Metal-Features verwenden, einschließlich der IP-Adressfreigabe für mehrere Dienste. Weitere Informationen zu dieser Funktion finden Sie in der Dokumentation zum Thema "HLK".

MetalLB führt auf einem Knoten über ein DaemonSet eine Lautsprechergruppe mit memberlist für eine hohe Verfügbarkeit aus. Für jeden Kubernetes-Dienst gibt es einen eigenen MetalLB Load-Balancer-Knoten, nicht einen für den gesamten Cluster. So wird der Traffic auf die Load-Balancer-Knoten verteilt, wenn mehrere Dienste vorhanden sind.

Die Load-Balancer der Datenebene können entweder auf Knoten der Steuerungsebene oder auf einer Teilmenge von Worker-Knoten ausgeführt werden. Durch das Zwischenspeichern der Datenebenen-Load-Balancer auf den Steuerungseben-Knoten wird die Nutzung der Steuerungsebene-Knoten erhöht. Durch das Bündeln der Knoten auf der Steuerungsebene wird auch das Risiko einer Überlastung der Steuerungsebene und das Risikoprofil vertraulicher Informationen auf der Steuerungsebene, z. B. SSH-Schlüssel, erhöht.

Load-Balancer-Trennung

Vor Version 1.32 werden bei der Konfiguration des Layer-2-Load-Balancings mit MetalLB die Load-Balancer der Steuerungsebene und die Load-Balancer der Datenebene auf denselben Knoten ausgeführt. Je nach Konfiguration werden die Load-Balancer entweder alle auf den Knoten der Steuerungsebene oder alle im Load-Balancer-Knotenpool ausgeführt.

Das folgende Diagramm zeigt die Standardkonfiguration für gebündelte Load-Balancer, bei der sowohl die Load-Balancer der Steuerungsebene als auch die Load-Balancer der Datenebene auf den Knoten der Steuerungsebene oder beide im Load-Balancer-Knotenpool ausgeführt werden:

Standardkonfiguration des Load Balancers

Bei Clustern der Version 1.32 können Sie die Load-Balancer der Steuerungsebene so konfigurieren, dass sie auf den Knoten der Steuerungsebene ausgeführt werden, und die Load-Balancer der Datenebene so, dass sie im Load-Balancer-Knotenpool ausgeführt werden. Sie können diese Trennung der Load-Balancer angeben, wenn Sie einen neuen Cluster der Version 1.32 erstellen, oder Sie können einen Cluster der Version 1.32 aktualisieren, um die Load-Balancer der Datenebene von den Knoten der Steuerungsebene zum Load-Balancer-Knotenpool zu migrieren.

Die Clusterkonfiguration für getrennte Load-Balancer sollte in etwa so aussehen wie im folgenden Beispiel:

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.35
  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:
  ...

Load-Balancer beim Erstellen eines Clusters trennen

Wenn Sie einen neuen Cluster der Version 1.32 oder höher erstellen, können Sie die Load-Balancer so konfigurieren, dass die Load-Balancer der Steuerungsebene auf den Knoten der Steuerungsebene und die Load-Balancer der Datenebene auf dem Load-Balancer-Knotenpool ausgeführt werden.

Das folgende Diagramm zeigt die Load-Balancer der Steuerungsebene und der Datenebene, die auf verschiedenen Knoten getrennt sind:

Separate Load Balancer für Steuerungsebene und Datenebene

So trennen Sie die Load-Balancer beim Erstellen eines Clusters:

  1. Geben Sie in der Clusterkonfigurationsdatei einen Load-Balancer-Knotenpool mit loadBalancer.nodePoolSpec an, wie im loadBalancer.nodePoolSpec Abschnitt dieses Dokuments beschrieben.

  2. Fügen Sie controlPlane.loadBalancer.mode der Clusterkonfigurationsdatei hinzu und setzen Sie den Wert für mode auf bundled.

  3. Konfigurieren Sie den Cluster fertig und führen Sie bmctl create cluster aus, um den Cluster zu erstellen.

Load-Balancer der Datenebene von der Steuerungsebene migrieren

Wenn Sie einen vorhandenen Cluster der Version 1.32 oder höher haben, in dem weder controlPlane.loadBalancer.mode noch loadBalancer.nodePoolSpec festgelegt ist, werden sowohl der Load-Balancer der Steuerungsebene als auch der Load-Balancer der Datenebene im Knotenpool der Steuerungsebene ausgeführt. Sie können den Cluster aktualisieren, um den Load-Balancer der Datenebene zu einem Load-Balancer-Knotenpool zu migrieren.

Das folgende Diagramm zeigt die Load-Balancer der Steuerungsebene und der Datenebene, die getrennt sind, nachdem der Load-Balancer der Datenebene von den Knoten der Steuerungsebene migriert wurde:

Load-Balancer der Datenebene wurde zum Load-Balancer-Knotenpool migriert

So migrieren Sie den Load-Balancer der Datenebene zu einem Load-Balancer-Knotenpool, wenn Sie einen Cluster aktualisieren:

  1. Geben Sie in der Clusterkonfigurationsdatei einen Load-Balancer-Knotenpool mit loadBalancer.nodePoolSpec an, wie im loadBalancer.nodePoolSpec Abschnitt dieses Dokuments beschrieben.

  2. Fügen Sie controlPlane.loadBalancer.mode der Clusterkonfigurationsdatei hinzu und setzen Sie den Wert für mode auf bundled.

  3. Aktualisieren Sie den Cluster mit dem folgenden Befehl:

    bmctl update cluster -c CLUSTER_NAME --kubeconfig=ADMIN_KUBECONFIG
    

    Ersetzen Sie Folgendes:

    • CLUSTER_NAME: der Name des Clusters, den Sie aktualisieren

    • ADMIN_KUBECONFIG: der Pfad der kubeconfig-Datei des Administratorclusters

Quell-IP-Adresse des Clients beibehalten

Der Dienst LoadBalancer, der mit der gebündelten Ebene-2-Load-Balancing-Lösung erstellt wurde, verwendet die Standardeinstellung Cluster für die externe Trafficrichtlinie. Diese Einstellung (spec.externalTrafficPolicy: Cluster) leitet externen Traffic an clusterweite Endpunkte weiter, verschleiert jedoch auch die IP-Adresse des Clientquellcodes.

Google Distributed Cloud unterstützt zwei Methoden zum Beibehalten der Quell-IP-Adresse des Clients :

  • Setzen Sie den Weiterleitungsmodus für das Load-Balancing auf Direct Server Return (DSR). Weitere Informationen zum DSR-Weiterleitungsmodus und eine Anleitung zum Aktivieren finden Sie unter Weiterleitungsmodus für das Load-Balancing konfigurieren.

  • Setzen Sie die externe Trafficrichtlinie für den Dienst LoadBalancer auf „Lokal“ und konfigurieren Sie die zugehörigen Dienste und den eingehenden Traffic entsprechend. In den folgenden Abschnitten wird beschrieben, wie Sie Ihren Cluster für die Verwendung dieser Methode konfigurieren.

LoadBalancer-Dienste

Wenn Sie externalTrafficPolicy: Local in Ihren LoadBalancer-Diensten verwenden, legen Sie fest, dass Ihre Anwendungs-Pods genau auf den Load-Balancer-Knoten ausgeführt werden. Fügen Sie den Anwendungs-Pods das folgende nodeSelector hinzu, um diese Änderung vorzunehmen:

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

NodePort-Dienste

Kubernetes führt eine Quellnetzwerkadressübersetzung (SNAT) für NodePort-Dienste aus. Wenn Sie die Quell-IP-Adressen der Clients beibehalten möchten, setzen Sie service.spec.externalTrafficPolicy auf Local. Kubernetes führt keine SNAT mehr aus. Sie müssen jedoch darauf achten, dass Pods genau auf der ausgewählten Knoten-IP ausgeführt werden.

Eingehender Traffic

Wenn Ihre Anwendungen HTTP-Dienste sind, können Sie die Sichtbarkeit der Client-IP-Adresse erreichen, indem Sie Ingress-Komponenten konfigurieren:

  1. Öffnen Sie den istio-ingress-Dienst zum Bearbeiten:

    kubectl edit service -n gke-system istio-ingress
    
  2. Fügen Sie externalTrafficPolicy: Local zum spec hinzu, speichern Sie den Editor und beenden Sie ihn.

    apiVersion: v1
    kind: Service
    ...
    spec:
    ...
      externalTrafficPolicy: Local
    
  3. Öffnen Sie das Deployment istio-ingress zum Bearbeiten:

    kubectl edit deployment -n gke-system istio-ingress
    
  4. Fügen Sie dem Deployment den folgenden nodeSelector hinzu, speichern Sie den Editor und beenden Sie ihn.

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

Jetzt sehen alle Ihre Dienste hinter Ingress einen X-Forwarded-For-Header mit der Client-IP, wie im folgenden Beispiel:

X-Forwarded-For: 21.0.104.4