Erweitertes Load Balancing in GKE-Clustern

Auf dieser Seite erfahren Sie, wie Sie mit der Kubernetes API ein erweitertes Load Balancing in GKE-Clustern für Nutzer von verwaltetem Cloud Service Mesh (TD) konfigurieren. Eine entsprechende Anleitung zum Konfigurieren des erweiterten Load Balancings mit derGoogle Cloud API finden Sie unter Erweitertes Load Balancing einrichten.

Mit dem erweiterten Load Balancing können Sie Folgendes tun:

  • Behalten Sie den Traffic in einer Servicezone, bis die lokale Kapazität ausgeschöpft ist.
  • Senden Sie Traffic an den Dienst an einem „primären“ Standort mit Failover zu einem sekundären Standort, wenn genügend Endpunkte am primären Standort nicht mehr betriebsbereit sind.
  • Festlegen, wann das Failover erfolgt (basierend auf dem Prozentsatz der fehlerfreien Hosts).

Beschränkungen

  • Für die Verwendung des erweiterten Load Balancings in Google Cloud gelten allgemeine Einschränkungen.
  • Diese Funktion ist nur für Nutzer von verwaltetem Cloud Service Mesh verfügbar, die Traffic Director als Steuerungsebene verwenden. Außerdem ist die Datenebenenversion 1.19.10-asm.22 oder höher erforderlich.
  • Nicht alle Felder in GCPTrafficDistributionPolicy und GCPBackendPolicy werden für managedCloud Service Mesh (TD) unterstützt. Die unterstützten Felder sind:
    • GCPTrafficDistributionPolicy
      • ServiceLbAlgorithm
      • AutoCapacityDrain
      • FailoverConfig
    • GCPBackendPolicy
      • MaxRatePerEndpoint
      • BackendPreference
  • Das erweiterte Load Balancing kann nur auf Kubernetes-Dienste angewendet werden, die von Arbeitslasten unterstützt werden, die auf Google Cloudausgeführt werden. Externe Dienste oder Arbeitslasten (z. B. ServiceEntry) werden nicht unterstützt.
  • Die Load Balancing-Richtlinien können nur auf einzelne Kubernetes-Dienste angewendet werden. Load Balancing-Richtlinien auf Namespace-/Mesh-Ebene werden nicht unterstützt.
  • Es wird nur die QPS-Kapazität unterstützt.
  • Nur GKE-Versionen >= 1.31.1 werden unterstützt.
  • Erweiterte Load Balancing-Richtlinien für Service Meshs dürfen nur auf Dienste angewendet werden, die nur Mesh-Traffic verarbeiten. Sie darf nicht auf Dienste angewendet werden, die als GKE Gateway-Back-Ends dienen. Das Traffic-Verhalten ist nicht definiert, wenn ein erweiterter Load Balancing-Traffic auf einen Kubernetes-Dienst ausgerichtet ist, der sowohl Mesh-Traffic als auch Traffic von einem GKE-Gateway verarbeitet.

Erweitertes Load Balancing konfigurieren

Mit den folgenden benutzerdefinierten Ressourcen können Sie erweitertes Load Balancing in GKE konfigurieren. Die detaillierte Ressourcendefinition finden Sie im Repository „gke-gateway-api“.

GCPTrafficDistributionPolicy

Mit GCPTrafficDistributionPolicy wird die Load Balancing-Richtlinie auf Dienstebene für Kubernetes-Dienste konfiguriert. Sie haben folgende Möglichkeiten:

Wenn mehrere GCPTrafficDistributionPolicies auf denselben Dienst ausgerichtet sind, wird die älteste Richtlinie erzwungen.

GCPBackendPolicy

Mit GCPBackendPolicy werden Eigenschaften von Dienst-Back-Ends konfiguriert, die sich auf das Load Balancing-Verhalten auswirken. Dazu gehören:

Wenn mehrere GCPBackendPolicies auf denselben Dienst in einem Cluster ausgerichtet sind, wird die älteste Richtlinie erzwungen.

Richtlinienstatus

Sowohl GCPTrafficDistributionPolicy als auch GCPBackendPolicy haben ein Statusfeld, das den Anhangsstatus der Richtlinie angibt.

Wenn Sie beispielsweise kubectl describe gcpbackendpolicies example-policy -n example ausführen, erhalten Sie eine Ausgabe wie diese:

...
Status:
  Ancestors:
    Ancestor Ref:
      Group:
      Kind:       Service
      Name:       example-svc
      Namespace:  example
    Conditions:
      Last Transition Time:  2024-10-13T01:15:03Z
      Message:
      Observed Generation:   1
      Reason:                Attached
      Status:                True
      Type:                  Attached
    Controller Name:         gsmconfig.gke.io/controller

Vorbereitende Einrichtung

Bevor Sie diese Anleitung ausführen können, müssen Sie Cloud Service Mesh in einem GKE-Cluster bereitstellen.

  1. Prüfen Sie, ob die CRDs installiert sind:

    kubectl get crd
    

    Die Ausgabe sieht etwa so aus:

    ...
    gcptrafficdistributionpolicies.networking.gke.io   2024-07-18T21:50:12Z
    gcpbackendpolicies.networking.gke.io               2024-07-18T21:50:12Z
    ...
    
  2. Installieren Sie die GCPBackendPolicy-CRD, falls noch nicht geschehen:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
    
  3. Installieren Sie die GCPTrafficDistributionPolicy-CRD, falls noch nicht geschehen:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficdistributionpolicies.yaml
    

Die Beispielrichtlinien in diesem Leitfaden sind zu Demonstrationszwecken auf den Dienst „foo“ im Namespace „foo“ ausgerichtet. Sie können den folgenden Befehl ausführen, um den Testdienst und den Namespace zu erstellen. Alternativ können Sie auch Ihren eigenen Dienst und Namespace verwenden:

kubectl apply -f - <<EOF
kind: Namespace
apiVersion: v1
metadata:
  name: foo
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
  namespace: foo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-backend
  template:
    metadata:
      labels:
        app: test-backend
    spec:
      containers:
      - name: whereami
        image: gcr.io/google-samples/whereami:v1.2.23
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: foo
  namespace: foo
spec:
  selector:
    app: test-backend
  ports:
  - port: 8080
    targetPort: 8080
EOF

Load-Balancing-Algorithmus konfigurieren

Standardmäßig wird der Traffic zu einem Dienst gleichmäßig auf jedes einzelne fehlerfreie Dienst-Back-End in einem Cloud Service Mesh-Service Mesh verteilt. Sie können die folgende GCPTrafficDistributionPolicy erstellen, damit der Traffic bis zur Backendkapazität auf die nächstgelegene Zone verteilt wird:

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
    serviceLbAlgorithm: WATERFALL_BY_ZONE
EOF

Standardmäßig werden Dienst-Backends so behandelt, als hätten sie eine unbegrenzte Kapazität. Wenn sich in der lokalen/nächstgelegenen Zone genügend fehlerfreie Hosts befinden, wird Traffic für eine bestimmte Client-Lokalität nie außerhalb der lokalen/nächstgelegenen Zone verteilt. Sie können die Kapazität Ihres Dienst-Backends optional mit GCPBackendPolicy konfigurieren, damit eine einzelne Zone nicht überlastet wird.

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: backend-policy
  namespace: foo
spec:
  targetRef:
    kind: Service
    group: ""
    name: foo-backend
  default:
    maxRatePerEndpoint: 5
EOF

Failover-Verhalten anpassen

Standardmäßig wird kein Failover ausgelöst, solange ein ausreichender Prozentsatz der Hosts in den primären Back-Ends fehlerfrei ist. Weitere Informationen zu primären Backends und anderer Terminologie finden Sie in der Übersicht über das erweiterte Load Balancing. Mit GCPTrafficDistributionPolicy können Sie den Prozentsatz der fehlerfreien Hosts konfigurieren, bis der Traffic von primären Back-Ends zu Failover-Back-Ends umgeleitet wird. Bei einem höheren Grenzwert wird das Failover früher ausgelöst. Wenn Sie beispielsweise möchten, dass ein Failover ausgelöst wird, sobald der Prozentsatz der fehlerfreien Hosts in den primären Back-Ends unter 90% fällt, können Sie die folgende GCPTrafficDistributionPolicy konfigurieren:

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
   failoverConfig:
     failoverHealthThreshold: 90
EOF

Erweitertes Load Balancing in einem Multi-Cluster-Service Mesh konfigurieren

GCPTrafficDistributionPolicy und GCPBackendPolicy werden in einem Multi-Cluster-Service-Mesh auf unterschiedliche Bereiche angewendet.

Wenn eine GCPTrafficDistributionPolicy auf einen Multi-Cluster-Dienst ausgerichtet ist, definiert sie das Load Balancing-Verhalten auf Serviceebene für alle Cluster. Für einen bestimmten Multi-Cluster-Dienst muss nur eine GCPTrafficDistributionPolicy erstellt werden. Wenn Sie die Istio API zum Konfigurieren Ihres Service Mesh verwenden, können Sie „GCPTrafficDistributionPolicy“ in jedem Cluster der Flotte erstellen. Ob eine Richtlinie mit einer anderen in Konflikt steht, können Sie anhand des Richtlinienstatus prüfen.

Wenn eine GCPBackendPolicy auf einen Multi-Cluster-Dienst ausgerichtet ist, werden Einstellungen auf Back-End-Ebene (z. B. die Kapazität pro Pod) für die Back-End-Pods definiert, die vom Targeting-Dienst in seinem lokalen Cluster ausgewählt werden. Für denselben Multi-Cluster-Dienst können in verschiedenen Clustern unterschiedliche Einstellungen auf Back-End-Ebene definiert werden.

Im folgenden Beispiel wird in Cluster A eine GCPTrafficDistributionPolicy erstellt, um den Load Balancing-Algorithmus zu definieren, der für die gesamte Flotte verwendet werden soll. GCPBackendPolicies befinden sich in jedem Cluster. Mit beiden GCPBackendPolicy-Objekten wird eine Kapazität von 10 qps pro Pod für die Backend-Pods in ihrem lokalen Cluster konfiguriert. Die GCPBackendPolicy in Cluster A konfiguriert die Backend-Pods in Cluster A als bevorzugtes Backend.

Zusammengenommen konfigurieren diese Richtlinien das Load Balancing für In-Mesh-Traffic, der an den Dienst „foo“ gesendet wird:

  • Traffic von überall wird Back-Ends in Cluster A vorgezogen, bis Back-End-Pods in Cluster A 10 qps pro Pod verarbeiten müssen.
    • Dieses Verhalten wird hauptsächlich durch die GCPBackendPolicy definiert, die backendPreference in Cluster A auf PREFERRED festlegt.
  • Traffic, der die konfigurierte Kapazität der Back-Ends in Cluster A überschreitet, wird mit Algorithmus WATERFALL_BY_ZONE an Cluster B weitergeleitet. Eine ausführlichere Erklärung zu bevorzugten Backends finden Sie unter Erweitertes Load Balancing – Übersicht.
    • Dieses Verhalten wird hauptsächlich durch die GCPTrafficDistributionPolicy definiert, die den Algorithmus in Cluster A und die GCPBackendPolicy, die die Backendkapazität sowohl in Cluster A als auch in Cluster B definiert.

Erweitertes Load Balancing für Multi-Cluster-Service Mesh

In Istio werden reguläre Kubernetes-Dienste implizit zu „Multi-Cluster-Diensten“, wenn sich im Service Mesh mehrere Cluster befinden und der Dienst über Clustergrenzen hinweg erstellt wird. Die folgende GCPTrafficDistributionPolicy richtet sich zwar an den regulären Kubernetes-Dienst „foo“, gilt aber für den Multi-Cluster-Dienst „foo“, der aus entsprechenden Arbeitslasten in zwei Clustern besteht.

  1. Erstellen Sie die GCPTrafficDistributionPolicy für Cluster A:

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPTrafficDistributionPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-traffic-distribution-policy
    namespace: foo
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: foo-service
      default:
        serviceLbAlgorithm: WATERFALL_BY_ZONE
    
    EOF
    
  2. Erstellen Sie die GCPBackendPolicy für Cluster A:

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 100
        backendPreference: PREFERRED
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    
  3. Erstellen Sie die GCPBackendPolicy für Cluster B:

    kubectl apply --context cluster-b-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 10
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    

Weitere Informationen