Multi-Cluster-Gateway für kapazitätsbasiertes Load-Balancing bereitstellen

In diesem Dokument wird beschrieben, wie Sie eine Beispielanwendung in zwei GKE-Clustern in verschiedenen Regionen bereitstellen und wie Multi-Cluster-Gateway Traffic intelligent weiterleitet, wenn er die Kapazitätslimits des Dienstes überschreitet.

Kapazitätsbasiertes Load-Balancing ist ein Feature von Multi-Cluster-Gateways, mit dem Sie hochzuverlässige und robuste Anwendungen erstellen können. Wenn Sie die Kapazität Ihrer Dienste festlegen, können Sie sie vor Überlastung schützen und für eine gleichbleibende Nutzererfahrung sorgen. Wenn ein Dienst in einem Cluster seine Kapazität erreicht, leitet der Load-Balancer den Traffic automatisch zu einem anderen Cluster mit freier Kapazität um. Weitere Informationen zur Traffic-Verwaltung finden Sie unter GKE-Traffic-Verwaltung.

In dieser Anleitung verwenden Sie eine store-Beispielanwendung, um ein reales Szenario zu simulieren, in dem ein Online-Shopping-Dienst von separaten Teams betrieben und über eine Flotte freigegebener GKE-Cluster bereitgestellt wird.

Hinweise

Multi-Cluster-Gateways erfordern eine gewisse Umgebungsvorbereitung, bevor sie bereitgestellt werden können. Bevor Sie fortfahren, führen Sie die Schritte unter Umgebung für Multi-Cluster-Gateways vorbereiten aus:

  1. GKE-Cluster bereitstellen.

  2. Registrieren Sie Ihre Cluster für eine Flotte, falls noch nicht geschehen.

  3. Aktivieren Sie den Multi-Cluster-Service und die Multi-Cluster-Gateway-Controller.

Prüfen Sie dann vor der Verwendung in der Umgebung die Einschränkungen und bekannten Probleme des GKE Gateway-Controllers.

Kapazitätsbasiertes Load-Balancing bereitstellen

Die Übung in diesem Abschnitt veranschaulicht die Konzepte für globales Load-Balancing und Service-Kapazität. Dazu wird eine Anwendung in zwei GKE-Clustern in verschiedenen Regionen bereitgestellt. Der generierte Traffic wird mit verschiedenen Werten für die Anfragen pro Sekunde (RPS) gesendet, um zu zeigen, wie das Traffic-Load-Balancing auf Cluster und Regionen erfolgt.

Das folgende Diagramm zeigt die Topologie, die Sie bereitstellen, und veranschaulicht, wie der Traffic zwischen Clustern und Regionen überläuft, wenn er die Service-Kapazität überschreitet:

Traffic, der von einem Cluster zu einem anderen überläuft

Umgebung vorbereiten

  1. Folgen Sie der Anleitung unter Umgebung für Multi-Cluster-Gateways vorbereiten, um Ihre Umgebung vorzubereiten.

  2. Prüfen Sie, ob die GatewayClass-Ressourcen im Konfigurationscluster installiert sind:

    kubectl get gatewayclasses --context=gke-west-1
    

    Die Ausgabe sieht in etwa so aus:

    NAME                                  CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed        networking.gke.io/gateway   True       16h
    gke-l7-global-external-managed-mc     networking.gke.io/gateway   True       14h
    gke-l7-gxlb                           networking.gke.io/gateway   True       16h
    gke-l7-gxlb-mc                        networking.gke.io/gateway   True       14h
    gke-l7-regional-external-managed      networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed-mc   networking.gke.io/gateway   True       14h
    gke-l7-rilb                           networking.gke.io/gateway   True       16h
    gke-l7-rilb-mc                        networking.gke.io/gateway   True       14h
    

Anwendung bereitstellen

Stellen Sie den Beispielwebanwendungsserver in beiden Clustern bereit:

kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml

Die Ausgabe sieht in etwa so aus:

namespace/store created
deployment.apps/store created

Service, Gateway und HTTPRoute bereitstellen

  1. Wenden Sie das folgende Service-Manifest auf die Cluster gke-west-1 und gke-east-1 an:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    
    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    

    Der Service wird mit max-rate-per-endpoint auf 10 Anfragen pro Sekunde annotiert. Mit zwei Replikaten pro Cluster hat jeder Service eine Kapazität von 20 RPS pro Cluster.

    Weitere Informationen zur Auswahl einer Service-Kapazitätsstufe für Ihren Service finden Sie unter Kapazität Ihres Service bestimmen.

  2. Wenden Sie das folgende Gateway-Manifest auf den Konfigurationscluster gke-west-1 in diesem Beispiel an:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
      namespace: traffic-test
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    Das Manifest beschreibt ein externes, globales Multi-Cluster-Gateway, das einen externen Application Load Balancer mit einer öffentlich zugänglichen IP-Adresse bereitstellt.

  3. Wenden Sie das folgende HTTPRoute-Manifest auf den Konfigurationscluster gke-west-1 in diesem Beispiel an:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
      namespace: traffic-test
      labels:
        gateway: store
    spec:
      parentRefs:
      - kind: Gateway
        namespace: traffic-test
        name: store
      rules:
      - backendRefs:
        - name: store
          group: net.gke.io
          kind: ServiceImport
          port: 8080
    EOF
    

    Das Manifest beschreibt eine HTTPRoute, die das Gateway mit einer Routingregel konfiguriert, die den gesamten Traffic an den Speicher-ServiceImport weiterleitet. Der store-ServiceImport gruppiert die store-Service-Pods in beiden Clustern und ermöglicht ihnen, vom Load Balancer als ein einzelner Service adressiert zu werden.

    Sie können die Ereignisse des Gateways nach einigen Minuten prüfen, um festzustellen, ob die Bereitstellung abgeschlossen ist:

    kubectl describe gateway store -n traffic-test --context gke-west-1
    

    Die Ausgabe sieht in etwa so aus:

    ...
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.102.159.147
      Conditions:
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                  From                   Message
      ----    ------  ----                 ----                   -------
      Normal  ADD     12m                  mc-gateway-controller  traffic-test/store
      Normal  SYNC    6m43s                mc-gateway-controller  traffic-test/store
      Normal  UPDATE  5m40s (x4 over 12m)  mc-gateway-controller  traffic-test/store
      Normal  SYNC    118s (x6 over 10m)   mc-gateway-controller  SYNC on traffic-test/store was a success
    

    Diese Ausgabe zeigt, dass das Gateway erfolgreich bereitgestellt wurde. Nach der Bereitstellung des Gateways kann es einige Minuten dauern, bis der Traffic weitergeleitet wird. Notieren Sie sich die IP-Adresse in dieser Ausgabe, da sie in einem folgenden Schritt verwendet wird.

Traffic bestätigen

Testen Sie, ob der Traffic an die Anwendung weitergeleitet wird. Testen Sie dazu die Gateway-IP-Adresse mit einem curl-Befehl:

curl GATEWAY_IP_ADDRESS

Die Ausgabe sieht in etwa so aus:

{
  "cluster_name": "gke-west-1",
  "host_header": "34.117.182.69",
  "pod_name": "store-54785664b5-mxstv",
  "pod_name_emoji": "👳🏿",
  "project_id": "project",
  "timestamp": "2021-11-01T14:06:38",
  "zone": "us-west1-a"
}

Diese Ausgabe zeigt die Pod-Metadaten. Diese geben die Region an, in der die Anfrage verarbeitet wurde.

Traffic mithilfe von Lasttests prüfen

Wenn Sie prüfen möchten, ob der Load-Balancer funktioniert, können Sie in Ihrem gke-west-1-Cluster einen Traffic-Generator bereitstellen. Der Traffic-Generator generiert Traffic auf verschiedenen Laststufen, um die Kapazitäts- und Überlauffunktionen des Load-Balancers zu demonstrieren. Die folgenden Schritte demonstrieren drei Laststufen:

  • 10 RPS, was unter der Kapazität des Speicher-Service in gke-west-1 liegt.
  • 30 RPS, was die Kapazität für den gke-west-1-Speicher-Service überschreitet und einen Traffic-Überlauf zu gke-east-1 verursacht.
  • 60 RPS, was die Kapazität für die Services in beiden Clustern übersteigt.

Dashboard konfigurieren

  1. Rufen Sie den Namen der zugrunde liegenden URL-Zuordnung für Ihr Gateway ab:

    kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
    

    Die Ausgabe sieht etwa so aus:

    /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
    
  2. Wechseln Sie in der Google Cloud Console zur Seite Metrics Explorer.

    Zu Metrics Explorer

  3. Klicken Sie unter Messwert auswählen auf CODE: MQL.

  4. Geben Sie die folgende Abfrage ein, um die Traffic-Messwerte für den Speicher-Service in den beiden Clustern zu beobachten:

    fetch https_lb_rule
    | metric 'loadbalancing.googleapis.com/https/backend_request_count'
    | filter (resource.url_map_name == 'GATEWAY_URL_MAP')
    | align rate(1m)
    | every 1m
    | group_by [resource.backend_scope],
        [value_backend_request_count_aggregate:
            aggregate(value.backend_request_count)]
    

    Ersetzen Sie GATEWAY_URL_MAP durch den URL-Zuordnungsnamen aus dem vorherigen Schritt.

  5. Klicken Sie auf Abfrage ausführen. Warten Sie nach der Bereitstellung des Lastgenerators im nächsten Abschnitt mindestens fünf Minuten, bis die Messwerte im Diagramm angezeigt werden.

Mit 10 RPS testen

  1. Stellen Sie einen Pod in Ihrem gke-west-1-Cluster bereit:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 10'
    

    Ersetzen Sie GATEWAY_IP_ADDRESS durch die Gateway-IP-Adresse aus dem vorherigen Schritt.

    Die Ausgabe sieht etwa so aus, was darauf hinweist, dass der Traffic-Generator Traffic sendet:

    If you don't see a command prompt, try pressing enter.
    

    Der Lastgenerator sendet kontinuierlich 10 RPS an das Gateway. Obwohl der Traffic aus einer Google Cloud -Region stammt, behandelt der Load-Balancer ihn als Client-Traffic von der US-Westküste. Zur Simulation einer realistischen Client-Diversität sendet der Lastgenerator jede HTTP-Anfrage als neue TCP-Verbindung. Dies bedeutet, dass der Traffic gleichmäßiger auf die Backend-Pods verteilt wird.

    Es dauert bis zu fünf Minuten, bis der Generator Traffic für das Dashboard generiert.

  2. Sehen Sie sich das Metrics Explorer-Dashboard an. Es werden zwei Zeilen angezeigt, die angeben, wie viel Traffic per Load-Balancing auf jeden Cluster verteilt wird:

    Grafik mit Traffic-Load-Balancing zu Clustern

    Sie sollten sehen, dass us-west1-a etwa 10 RPS an Traffic empfängt, während us-east1-b keinen Traffic empfängt. Da der Traffic-Generator in us-west1 ausgeführt wird, wird der gesamte Traffic an den Service im gke-west-1-Cluster gesendet.

  3. Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Mit 30 RPS testen

  1. Stellen Sie den Lastgenerator noch einmal bereit, aber konfigurieren Sie ihn zum Senden von 30 RPS:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 30'
    

    Es dauert bis zu fünf Minuten, bis der Generator Traffic für das Dashboard generiert.

  2. Rufen Sie das Cloud Ops-Dashboard auf.

    Grafik, die den Traffic-Überlauf zu gke-east-1 zeigt

    Sie sollten sehen, dass etwa 20 RPS an us-west1-a und 10 RPS an us-east1-b gesendet werden. Dies gibt an, dass der Service in gke-west-1 vollständig genutzt wird und 10 RPS an Traffic zum Service in gke-east-1 überlaufen.

  3. Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Mit 60 RPS testen

  1. Stellen Sie den Lastgenerator bereit, der zum Senden von 60 RPS konfiguriert ist:

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 60'
    
  2. Warten Sie fünf Minuten und sehen Sie sich Ihr Cloud Ops-Dashboard an. Es sollte nun zeigen, dass beide Cluster etwa 30 RPS erhalten. Da alle Services global überlastet sind, gibt es keinen Traffic-Überlauf und Services verarbeiten so viel Traffic wie möglich.

    Grafik: Services mit Überlastung

  3. Beenden Sie den Lastgenerator mit Strg + C und löschen Sie dann den Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Bereinigen

Wenn Sie mit den Übungen in diesem Dokument fertig sind, entfernen Sie mit den folgenden Schritten die Ressourcen, damit Sie unerwünschte Kosten für Ihr Konto vermeiden:

  1. Löschen Sie die Cluster.

  2. Heben Sie die Registrierung der Cluster für die Flotte auf, wenn sie nicht für einen anderen Zweck registriert werden müssen.

  3. Deaktivieren Sie die Funktion multiclusterservicediscovery.

    gcloud container fleet multi-cluster-services disable
    
  4. Deaktivieren sie Multi-Cluster-Ingress:

    gcloud container fleet ingress disable
    
  5. Deaktivieren Sie die APIs:

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

Fehlerbehebung

Kein gesunder Upstream

Symptom:

Das folgende Problem kann auftreten, wenn Sie ein Gateway erstellen, aber nicht auf die Backend-Dienste zugreifen können (Antwortcode 503):

no healthy upstream

Grund:

Diese Fehlermeldung gibt an, dass der Prüfer für die Systemdiagnose keine fehlerfreien Backend-Dienste finden kann. Möglicherweise sind Ihre Back-End-Dienste in Ordnung, aber Sie müssen die Systemdiagnosen möglicherweise anpassen.

Workaround:

Um dieses Problem zu beheben, passen Sie Ihre Systemdiagnose anhand der Anforderungen Ihrer Anwendung (z. B. /health) mithilfe einer HealthCheckPolicy an.

Nächste Schritte