Déployer une passerelle multicluster pour l'équilibrage de charge basé sur la capacité

Ce document vous guide dans le déploiement d'un exemple d'application sur deux clusters GKE dans différentes régions. Il vous montre également comment la passerelle multicluster achemine intelligemment le trafic lorsqu'il dépasse les limites de capacité de service.

L'équilibrage de charge basé sur la capacité est une fonctionnalité des passerelles multiclusters qui vous aide à créer des applications très fiables et résilientes. En définissant la capacité de vos services, vous pouvez les protéger contre la surcharge et garantir une expérience cohérente à vos utilisateurs. Lorsqu'un service d'un cluster atteint sa capacité, l'équilibreur de charge redirige automatiquement le trafic vers un autre cluster disposant d'une capacité disponible. Pour en savoir plus sur la gestion du trafic, consultez Gestion du trafic GKE.

Dans ce tutoriel, vous utiliserez un exemple d'application store pour simuler un scénario réel dans lequel un service d'achats en ligne est détenu et géré par des équipes distinctes, et est déployé sur un parc de clusters GKE partagés.

Avant de commencer

Les passerelles multiclusters nécessitent une préparation environnementale avant de pouvoir être déployées. Avant de continuer, suivez les étapes décrites dans la section Préparer votre environnement pour les passerelles multiclusters :

  1. Déployez des clusters GKE

  2. Enregistrez vos clusters dans un parc (si ce n'est pas déjà fait).

  3. Activez les contrôleurs de service et de passerelle multiclusters.

Enfin, consultez les limites et les problèmes connus du contrôleur GKE Gateway avant de l'utiliser dans votre environnement.

Déployer un équilibrage de charge basé sur la capacité

L'exercice de cette section illustre les concepts mondiaux d'équilibrage de charge et de capacité de service, en déployant une application sur deux clusters GKE dans différentes régions. Le trafic généré est envoyé à différents niveaux de requête par seconde (RPS) pour montrer comment le trafic est équilibré entre les clusters et les régions.

Le schéma suivant illustre la topologie que vous allez déployer et la manière dont le trafic déborde entre les clusters et les régions lorsque le trafic a dépassé la capacité de service :

Débordement du trafic d'un cluster à un autre

Préparer votre environnement

  1. Pour préparer votre environnement, suivez les instructions de la section Préparer votre environnement pour les passerelles multiclusters.

  2. Vérifiez que les ressources GatewayClass sont installées sur le cluster de configuration :

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

    Le résultat ressemble à ce qui suit :

    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
    

Déployer une application

Déployez l'exemple de serveur d'applications Web sur les deux clusters :

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

Le résultat ressemble à ce qui suit :

namespace/store created
deployment.apps/store created

Déployer un service, une passerelle et une route HTTP

  1. Appliquez le fichier manifeste Service suivant aux clusters gke-west-1 et gke-east-1 :

    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
    

    Le service est annoté avec max-rate-per-endpoint défini sur 10 requêtes par seconde. Avec deux instances dupliquées par cluster, chaque service dispose d'une capacité de 20 RPS par cluster.

    Pour plus d'informations sur le choix d'un niveau de capacité de service pour votre service, consultez la section Déterminer la capacité de votre service.

  2. Appliquez le fichier manifeste Gateway suivant au cluster de configuration, gke-west-1 dans cet exemple :

    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
    

    Le fichier manifeste décrit une passerelle multicluster globale externe, qui déploie un équilibreur de charge d'application externe avec une adresse IP accessible publiquement.

  3. Appliquez le fichier manifeste HTTPRoute suivant au cluster de configuration, gke-west-1 dans cet exemple :

    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
    

    Le fichier manifeste décrit une HTTPRoute qui configure la passerelle avec une règle de routage qui dirige tout le trafic vers la ressource ServiceImport du magasin. La ressource ServiceImport store regroupe les pods de service store sur les deux clusters et permet à l'équilibreur de charge de les traiter comme un service unique.

    Vous pouvez vérifier les événements de la passerelle après quelques minutes pour voir si le déploiement est terminé :

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

    Le résultat ressemble à ce qui suit :

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

    Ce résultat indique que la passerelle a été déployée avec succès. Le déploiement du trafic peut prendre quelques minutes après le déploiement de la passerelle. Notez l'adresse IP dans ce résultat, car elle est utilisée dans une étape suivante.

Confirmer le trafic

Vérifiez que le trafic est transmis à l'application en testant l'adresse IP de la passerelle à l'aide d'une commande curl :

curl GATEWAY_IP_ADDRESS

Le résultat ressemble à ce qui suit :

{
  "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"
}

Ce résultat affiche les métadonnées du pod, qui indiquent la région depuis laquelle la requête a été diffusée.

Vérifier le trafic à l'aide de tests de charge

Pour vérifier que l'équilibreur de charge fonctionne, vous pouvez déployer un générateur de trafic dans votre cluster gke-west-1. Le générateur de trafic génère du trafic à différents niveaux de charge pour illustrer la capacité et le débordement de l'équilibreur de charge. Les trois niveaux de charge suivants sont présentés :

  • 10 RPS, ce qui est inférieur à la capacité du service de magasin dans gke-west-1
  • 30 RPS, ce qui est une surcapacité pour le service de magasin gke-west-1 et entraîne un débordement du trafic vers gke-east-1.
  • 60 RPS, ce qui correspond à la surcapacité des services dans les deux clusters.

Configurer le tableau de bord

  1. Récupérez le nom du mappage d'URL sous-jacent de votre passerelle :

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

    Le résultat ressemble à ce qui suit :

    /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
    
  2. Dans la console Google Cloud , accédez à la page Explorateur de métriques.

    Accéder à l'explorateur de métriques

  3. Sous Sélectionner une métrique, cliquez sur CODE: MQL.

  4. Saisissez la requête suivante pour observer les métriques de trafic du service de magasin sur vos deux clusters :

    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)]
    

    Remplacez GATEWAY_URL_MAP par le nom de mappage d'URL de l'étape précédente.

  5. Cliquez sur Exécuter la requête. Attendez au moins cinq minutes après le déploiement du générateur de charge dans la section suivante pour que les métriques s'affichent dans le graphique.

Test avec 10 RPS

  1. Déployez un pod sur votre cluster gke-west-1 :

    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'
    

    Remplacez GATEWAY_IP_ADDRESS par l'adresse IP de la passerelle de l'étape précédente.

    Le résultat ressemble à ce qui suit, indiquant que le générateur de trafic envoie du trafic :

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

    Le générateur de charge envoie en continu 10 RPS à la passerelle. Même si le trafic provient d'une région Google Cloud , il est considéré comme du trafic client provenant de la côte ouest des États-Unis par l'équilibreur de charge. Pour simuler une diversité de client réaliste, le générateur de charge envoie chaque requête HTTP en tant que nouvelle connexion TCP, ce qui signifie que le trafic est réparti plus uniformément entre les pods de backend.

    Le générateur prend jusqu'à 5 minutes pour générer du trafic pour le tableau de bord.

  2. Afficher le tableau de bord de l'explorateur de métriques Deux lignes apparaissent, indiquant la quantité de charge de trafic équilibrée pour chacun des clusters :

    Graphique montrant la charge de trafic équilibrée pour les clusters

    Vous devriez constater que us-west1-a reçoit environ 10 RPS de trafic, tandis que us-east1-b ne reçoit aucun trafic. Comme le générateur de trafic s'exécute dans la région us-west1, tout le trafic est envoyé au service dans le cluster gke-west-1.

  3. Arrêtez le générateur de charge à l'aide du raccourci Ctrl+C, puis supprimez le pod :

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

Test avec 30 RPS

  1. Déployez à nouveau le générateur de charge, mais configuré pour envoyer 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'
    

    Le générateur prend jusqu'à 5 minutes pour générer du trafic pour le tableau de bord.

  2. Affichez votre tableau de bord Cloud Ops.

    Graphique illustrant le débordement du trafic vers gke-east-1

    Vous devriez constater qu'environ 20 RPS sont envoyées à us-west1-a et 10 RPS à us-east1-b. Cela indique que le service de gke-west-1 est pleinement utilisé et qu'il fait déborder 10 RPS du trafic vers le service dans gke-east-1.

  3. Arrêtez le générateur de charge à l'aide du raccourci Ctrl+C, puis supprimez le pod :

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

Test avec 60 RPS

  1. Déployez le générateur de charge configuré pour envoyer 60 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 60'
    
  2. Attendez cinq minutes, puis affichez votre tableau de bord Cloud Ops. Vous devriez maintenant voir que les deux clusters reçoivent environ 30 RPS. Étant donné que tous les services sont surexploités à l'échelle mondiale, le trafic n'est pas en débordement et les services absorbent tout le trafic possible.

    Graphique illustrant les services surexploités

  3. Arrêtez le générateur de charge à l'aide du raccourci Ctrl+C, puis supprimez le pod :

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

Effectuer un nettoyage

Après avoir terminé les exercices de ce document, procédez comme suit pour supprimer les ressources afin d'éviter que des frais inutiles ne vous soient facturés sur votre compte :

  1. Supprimer les clusters

  2. Annulez l'enregistrement de vos clusters dans le parc s'ils n'ont pas besoin d'être enregistrés à d'autres fins.

  3. Désactivez la fonctionnalité multiclusterservicediscovery :

    gcloud container fleet multi-cluster-services disable
    
  4. Désactiver un objet Ingess multicluster

    gcloud container fleet ingress disable
    
  5. Désactivez les API :

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

Dépannage

Aucun élément opérationnel en amont

Symptôme :

Le problème suivant peut se produire lorsque vous créez une passerelle, mais que vous ne pouvez pas accéder aux services de backend (code de réponse 503) :

no healthy upstream

Explication :

Ce message d'erreur indique que le vérificateur d'état ne parvient pas à trouver des services de backend opérationnels. Il est possible que vos services de backend soient opérationnels, mais que vous deviez personnaliser les vérifications d'état.

Solution :

Pour résoudre ce problème, personnalisez votre vérification d'état en fonction des exigences de votre application (par exemple, /health), à l'aide d'une ressource HealthCheckPolicy.

Étapes suivantes