Configurer la gestion du trafic pour les équilibreurs de charge HTTP(S) internes

Ce guide contient des exemples de configuration de la gestion du trafic pour l'équilibrage de charge HTTP(S) interne. Ce document présente des exemples d'utilisation de la gestion du trafic pour certains cas d'utilisation spécifiques. De nombreux autres cas d'utilisation sont possibles.

Avant de commencer

Configurer la gestion du trafic

Vous pouvez utiliser Cloud Console, gcloud ou l'API Cloud Load Balancing pour configurer la gestion du trafic. Dans l'environnement de configuration que vous avez choisi, vous configurez la gestion du trafic à l'aide de configurations YAML. Un mappage d'URL et un service de backend possèdent chacun leur propre fichier YAML. Selon les fonctionnalités souhaitées, vous devez rédiger un fichier YAML de mappage d'URL, de service de backend, ou les deux.

Pour obtenir de l'aide concernant l'écriture de ces fichiers YAML, vous pouvez utiliser les ressources suivantes :

Accéder aux exemples YAML dans Cloud Console

Pour accéder aux exemples YAML dans Cloud Console, procédez comme suit :

  1. Accédez à la page Équilibrage de charge dans Google Cloud Console.
    Accéder à la page "Équilibrage de charge"
  2. Dans la section Équilibrage de charge HTTP(S), cliquez sur Démarrer la configuration.
  3. Sélectionnez Seulement entre les VM. Ce paramètre signifie que l'équilibreur de charge est interne.
  4. Cliquez sur Continuer.
  5. Sous Règles de routage, sélectionnez Règle avancée d'hôte, de chemin d'accès et de routage.
  6. Cliquez sur Ajouter des hôtes et un outil de mise en correspondance des chemins d'accès.
  7. Cliquez sur le lien Conseils de codage.

La page Exemples YAML d'outils de mise en correspondance des chemins d'accès s'affiche.

Exemples YAML de mappage d'URL

Autorisation unique dans un mappage d'URL

Service unique

Envoyez l'intégralité du trafic vers un service unique. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
name: [url-map-name]
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100

Répartir le trafic

Répartissez le trafic entre plusieurs services. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
name: [url-map-name]
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
  - matchRules:
    - prefixMatch: /prefix
    priority: 2
    routeAction:
      weightedBackendServices:
      - backendService: regions/[region]/backendServices/[backend-service1]
        weight: 95
      - backendService: regions/[region]/backendServices/[backend-service2]
        weight: 5

Redirection d'URL

Renvoie un code de réponse 3xx configurable. Elle définit également l'en-tête de réponse "Location" à l'aide de l'URI approprié, en remplaçant l'hôte et le chemin d'accès comme spécifié dans l'action de redirection. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      urlRedirect:
        hostRedirect: [REDIRECT_HOST]
        pathRedirect: [REDIRECT_PATH]
        redirectResponseCode: FOUND
        stripQuery: True

Autorisations multiples dans un mappage d'URL

Mise en miroir du trafic

En plus de transmettre la requête au service de backend sélectionné, vous allez envoyer une requête identique au service de backend en miroir, selon une configuration de type "fire and forget". L'équilibreur de charge n'attend pas de réponse du backend auquel il envoie la requête en miroir. La mise en miroir est utile pour tester une nouvelle version d'un service de backend. Elle permet également de déboguer les erreurs de production sur une version de débogage du service de backend, plutôt que sur la version de production. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        requestMirrorPolicy:
          backendService: regions/[region]/backendServices/[backend-service2]

Réécriture de l'URL

Réécrivez la partie du nom d'hôte de l'URL, la partie du chemin de l'URL, ou les deux, avant d'envoyer une requête au service de backend sélectionné. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        urlRewrite:
          hostRewrite: [REWRITE_HOST]
          pathPrefixRewrite: [REWRITE_PATH]

Nouvelle tentative de requête

Configurez les conditions dans lesquelles l'équilibreur de charge doit effectuer une nouvelle tentative pour les requêtes ayant échoué, le délai d'attente avant de procéder à une nouvelle tentative et le nombre maximal de tentatives autorisées. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        retryPolicy:
          retryConditions: 502, 504
          numRetries: 3
          perTryTimeout:
            seconds: 1
            nanos: 50

Délai avant expiration

Indiquez le délai avant expiration pour la route sélectionnée. Le délai avant expiration est calculé à partir du moment où la requête est entièrement traitée et jusqu'à ce que la réponse soit elle aussi entièrement traitée. Le délai avant expiration inclut l'ensemble des nouvelles tentatives. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        timeout:
          seconds: 30
          nanos: 100

Erreurs

Intégrez des erreurs lors du traitement des requêtes pour simuler des pannes, y compris une latence élevée, une surcharge de service, des défaillances de service et un partitionnement réseau. Cette fonctionnalité est utile pour tester la résilience d'un service aux pannes simulées. Veillez à remplacer les variables entre crochets ([ ]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        faultInjectionPolicy:
          delay:
            fixedDelay:
              seconds: 10
              nanos: 20
            percentage: 25
          abort:
            httpStatus: 503
            percentage: 50

CORS

Configurez les règles de partage des ressources entre origines multiples (CORS, Cross-origin resource sharing) afin de gérer les paramètres d'équilibrage de charge HTTP(S) interne pour l'application des requêtes CORS. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      routeAction:
        weightedBackendServices:
          - backendService: regions/[region]/backendServices/[backend-service1]
            weight: 100
        corsPolicy:
            allowOrigins: my-domain.com
            allowMethods: GET, POST
            allowHeaders: Authorization, Content-Type
            maxAge: 1200
            allowCredentials: True

En-têtes

Ajoutez et supprimez des en-têtes de requête avant d'envoyer les requêtes au service de backend. Ajoutez et supprimez également des en-têtes de réponse après avoir reçu une réponse du service de backend. Veillez à remplacer les variables entre crochets ([]) :

defaultService: regions/[region]/backendServices/[backend-service1]
kind: compute#urlMap
name: l7-ilb-map
region: region/[region]
hostRules:
- hosts:
  - '*'
  pathMatcher: matcher1
pathMatchers:
- defaultService: regions/[region]/backendServices/[backend-service1]
  name: matcher1
  routeRules:
    - matchRules:
        - prefixMatch: /
      priority: [priority]
      headerAction:
        requestHeadersToAdd:
          - headerName: header-1-name
            headerValue: header-1-value
            replace: True
        requestHeadersToRemove:
          - header-2-name
          - header-3-name
        responseHeadersToAdd:
          - headerName: header-4-name
            headerValue: header-4-value
            replace: True
        responseHeadersToRemove:
          - header-5-name
          - header-6-name

Exemples YAML de service de backend

Détection des anomalies

Spécifiez les critères d'exclusion des VM backend ou des points de terminaison défaillants dans les NEG, ainsi que des critères permettant de définir à quel moment un backend ou un point de terminaison est considéré comme suffisamment opérationnel pour recevoir à nouveau le trafic. Veillez à remplacer les variables entre crochets ([]) :

kind: compute#backendService
loadBalancingScheme: INTERNAL_MANAGED
localityLbPolicy: RANDOM
name: regions/[region]/backendServices/[backend-service1]
outlierDetection:
  baseEjectionTime:
    nanos: 0
    seconds: '30'
  consecutiveErrors: 5
  consecutiveGatewayFailure: 3
  enforcingConsecutiveErrors: 2
  enforcingConsecutiveGatewayFailure: 100
  enforcingSuccessRate: 100
  interval:
    nanos: 0
    seconds: '1'
  maxEjectionPercent: 50
  successRateMinimumHosts: 5
  successRateRequestVolume: 100
  successRateStdevFactor: 1900
region: region/[region]

Ruptures de circuit

La rupture de circuit vous permet de définir des seuils de défaillance pour empêcher les requêtes client de surcharger vos backends. Une fois que les requêtes atteignent la limite que vous avez définie, l'équilibreur de charge arrête d'autoriser de nouvelles connexions ou n'envoie plus de requêtes, ce qui laisse le temps à vos backends de revenir à l'état normal de fonctionnement. Avec la rupture du circuit, vous pouvez empêcher les défaillances en cascade. Lorsque la limite est atteinte, les requêtes s'interrompent et un message d'erreur est renvoyé aux clients. Vous évitez ainsi tout risque de surcharge des backends. Cela permet de diffuser du trafic tout en gérant la situation de surcharge. Ce fonctionnement est comparable à la gestion d'un pic de trafic via l'augmentation de la capacité (par le biais de l'autoscaling).

Définissez des limites supérieures pour le nombre de requêtes par connexion et le volume de connexions à un service de backend. Limitez également le nombre de requêtes et de tentatives en attente. Veillez à remplacer les variables entre crochets ([]) :

kind: compute#backendService
loadBalancingScheme: INTERNAL_MANAGED
localityLbPolicy: RANDOM
affinityCookieTtlSec: 0
backends:
- balancingMode: UTILIZATION
  capacityScaler: 1.0
  group: region/[region]/instanceGroups/[instance-group]
  maxUtilization: 0.8
circuitBreakers:
  maxConnections: 1000
  maxPendingRequests: 200
  maxRequests: 1000
  maxRequestsPerConnection: 100
  maxRetries: 3
connectionDraining:
  drainingTimeoutSec: 0
healthChecks:
- region/[region]/healthChecks/[health-check]

Configurer la répartition du trafic

Cet exemple illustre les étapes suivantes :

  1. Créer des modèles distincts pour les différents services.

  2. Créer des groupes d'instances pour ces modèles.

  3. Créer des règles de routage qui configurent une répartition du trafic de type 95 % / 5 %.

  4. Envoyer des commandes curl pour vérifier que les pourcentages de répartition du trafic correspondent approximativement à la configuration.

Ces instructions partent du principe que :

  • la région est us-west1 ;
  • un proxy cible et une règle de transfert ont été créés, de même qu'un mappage d'URL nommé l7-ilb-map ;
  • la règle de transfert contient l'adresse 10.1.2.99

    (reportez-vous aux instructions de la section Configurer l'équilibrage de charge HTTP(S) interne pour les VM Compute Engine) ;

  • le mappage d'URL envoie tout le trafic vers un service de backend, nommé red-service, qui est le service de backend par défaut ;

  • vous avez configuré un autre chemin d'accès qui envoie 5 % du trafic vers blue-service et 95 % du trafic vers green-service ;

  • un outil de mise en correspondance des chemins d'accès est utilisé ;

  • vous utilisez Cloud Shell ou un autre environnement avec bash installé.

Définir les services

La fonction bash suivante crée un service de backend, incluant le modèle d'instance et le groupe d'instances géré.

Ces instructions partent du principe qu'une vérification d'état HTTP l7-ilb-basic-check a été créée. Reportez-vous aux instructions de la section Configurer l'équilibrage de charge HTTP(S) interne pour les VM Compute Engine.

function make_service() {
  local name="$1"
  local region="$2"
  local zone="$3"
  local network="$4"
  local subnet="$5"
  local subdir="$6"

  www_dir="/var/www/html/$subdir"

  (set -x; \
  gcloud compute instance-templates create "${name}-template" \
    --region="$region" \
    --network="$network" \
    --subnet="$subnet" \
    --tags=allow-ssh,load-balanced-backend \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --metadata=startup-script="#! /bin/bash
  apt-get update
  apt-get install apache2 -y
  a2ensite default-ssl
  a2enmod ssl
  sudo mkdir -p $www_dir
  /bin/hostname | sudo tee ${www_dir}index.html
  systemctl restart apache2"; \
  gcloud compute instance-groups managed create \
    "${name}-instance-group" \
    --zone="$zone" \
    --size=2 \
    --template="${name}-template"; \
  gcloud compute backend-services create "${name}-service" \
    --load-balancing-scheme=INTERNAL_MANAGED \
    --protocol=HTTP \
    --health-checks=l7-ilb-basic-check \
    --health-checks-region="$region" \
    --region="$region"; \
  gcloud compute backend-services add-backend "${name}-service" \
    --balancing-mode='UTILIZATION' \
    --instance-group="${name}-instance-group" \
    --instance-group-zone="$zone" \
    --region="$region")
}

Créer les services

Appelez maintenant la fonction pour créer trois services : red, green et blue. Le service red sert de service par défaut pour les requêtes envoyées à /. Les services green et blue sont configurés sur /prefix pour traiter respectivement 95 % et 5 % du trafic.

make_service red us-west1 us-west1-a lb-network backend-subnet ""
make_service green us-west1 us-west1-a lb-network backend-subnet /prefix
make_service blue us-west1 us-west1-a lb-network backend-subnet /prefix

Créer le mappage d'URL

Console

  1. Accédez à la page "Équilibrage de charge" dans Google Cloud Console.
    Accéder à la page Équilibrage de charge
  2. Cliquez sur le lien l7-ilb-map.
  3. Cliquez sur Modifier ().

Configurer les nouvelles règles de routage

  1. Sous Règles de routage, sélectionnez Règle avancée d'hôte, de chemin d'accès et de routage.
  2. Sous Nouveaux hôtes et outil de mise en correspondance des chemins d'accès, créez l'action par défaut en définissant le Service sur red-service.
  3. Cliquez sur OK.
  4. Cliquez sur Ajouter des hôtes et un outil de mise en correspondance des chemins d'accès.
  5. Dans le champ Hôtes, saisissez 10.1.2.99. Il s'agit de l'adresse IP de la règle de transfert de votre équilibreur de charge.
  6. Collez le contenu YAML suivant dans la zone Outil de mise en correspondance des chemins d'accès, en veillant à remplacer [PROJECT_ID] par l'ID de votre projet :

    defaultService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/red-service
    name: matcher1
    routeRules:
    - priority: 2
      matchRules:
        - prefixMatch: /prefix
      routeAction:
        weightedBackendServices:
          - backendService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/green-service
            weight: 95
          - backendService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/blue-service
            weight: 5
    
  7. Cliquez sur OK.

  8. Cliquez sur Mettre à jour.

gcloud

  1. Exportez le mappage d'URL existant à l'aide de la commande gcloud compute url-maps export :

    gcloud compute url-maps export l7-ilb-map \
      --destination=l7-ilb-map-config.yaml \
      --region=us-west1
    
  2. Mettez à jour le fichier de mappage d'URL l7-ilb-map-config.yaml en l'ajoutant à la fin du fichier, en veillant à remplacer [PROJECT_ID] par l'ID de votre projet :

    hostRules:
    - hosts:
      - '*'
      pathMatcher: matcher1
    pathMatchers:
    - defaultService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/red-service
      name: matcher1
      routeRules:
      - priority: 2
        matchRules:
          - prefixMatch: /prefix
        routeAction:
          weightedBackendServices:
            - backendService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/green-service
              weight: 95
            - backendService: https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/regions/us-west1/backendServices/blue-service
              weight: 5
    
  3. Mettez à jour le mappage d'URL à l'aide de la commande gcloud compute url-maps import :

    gcloud compute url-maps import l7-ilb-map \
       --region=us-west1 \
       --source=l7-ilb-map-config.yaml
    

Tester la configuration

Pour tester la configuration, vérifiez d'abord que les requêtes envoyées à 10.1.2.99/ (l'adresse IP de l'équilibreur de charge, configurée précédemment) sont gérées par la configuration red par défaut.

Vérifiez ensuite que les requêtes envoyées à 10.1.2.99/prefix sont réparties comme prévu.

Créer une VM cliente

Reportez-vous à la section Créer une instance de VM dans la zone pour tester la connectivité.

Envoyer des requêtes à 10.1.2.99

Connectez-vous en SSH au client.

gcloud compute ssh l7-ilb-client-us-west1-a \
    --zone=us-west1-a

Exécutez la commande suivante :

for LB_IP in 10.1.2.99; do
    RESULTS=
    for i in {1..1000}; do RESULTS="$RESULTS:`curl ${LB_IP}`"; done >/dev/null 2>&1
    IFS=':'
    echo "***"
    echo "*** Results of load balancing to $LB_IP: "
    echo "***"
    for line in $RESULTS; do echo $line; done | grep -Ev "^$" | sort | uniq -c
    echo
done
Vérifier les résultats
***
***Results of load balancing to 10.1.2.99:
***
502 red-instance-group-9jvq
498 red-instance-group-sww8

Envoyer des requêtes à 10.1.2.99/prefix

Envoyez les requêtes à 10.1.2.99/prefix et notez la répartition du trafic.

for LB_IP in 10.1.2.99; do
    RESULTS=
    for i in {1..1000}; do RESULTS="$RESULTS:`curl ${LB_IP}/prefix/index.html`"; done >/dev/null 2>&1
    IFS=':'
    echo "***"
    echo "*** Results of load balancing to $LB_IP/prefix: "
    echo "***"
    for line in $RESULTS; do echo $line; done | grep -Ev "^$" | sort | uniq -c
    echo
done
Vérifier les résultats
***
***Results of load balancing to 10.1.2.99/prefix:
***
21 blue-instance-group-8n49
27 blue-instance-group-vlqc
476 green-instance-group-c0wv
476 green-instance-group-rmf4

La configuration Canary envoie effectivement 95 % des requêtes /prefix au service green et 5 % au service blue.

Le contrôle du trafic vous permet de configurer l'affinité de session en fonction d'un cookie fourni. Suivez ces instructions pour configurer une affinité de session HTTP_COOKIE pour un service de backend nommé red-service.

Pour configurer l'affinité de session à l'aide de HTTP_COOKIE, procédez comme suit :

  1. Exécutez la commande gcloud compute backend_services export pour obtenir la configuration du service de backend.

    gcloud compute backend-services export red-service \
        --destination=red-service-config.yaml \
        --region=us-west1
    
  2. Mettez à jour le fichier red-service-config.yaml comme suit :

    sessionAffinity: 'HTTP_COOKIE'
    localityLbPolicy: 'RING_HASH'
    consistentHash:
     httpCookie:
      name: 'http_cookie'
      path: '/cookie_path'
      ttl:
        seconds: 100
        nanos: 30
     minimumRingSize: 10000
    
  3. Dans le fichier red-service-config.yaml, supprimez la ligne suivante :

    sessionAffinity: NONE
    
  4. Mettez à jour le fichier de configuration du service de backend :

    gcloud compute backend-services import red-service \
        --source=red-service-config.yaml \
        --region=us-west1
    

Dépannage

Utilisez ces informations pour le dépannage lorsque le trafic n'est pas acheminé conformément aux règles de routage et de trafic que vous avez configurées.

Pour plus d'informations sur la journalisation et la surveillance, consultez la section Journaux et surveillance HTTP(S) internes.

Symptômes :

  • Augmentation du trafic vers les services dans les règles supérieures à la règle considérée.
  • Augmentation inattendue des réponses HTTP 4xx et 5xx pour une règle de routage donnée.

Solution : vérifiez l'ordre de tri de vos règles de routage. Les règles de routage sont interprétées dans l'ordre dans lequel elles sont spécifiées.

Les règles de routage dans un mappage d'URL sont interprétées dans l'ordre dans lequel elles sont spécifiées. Cela diffère de la façon dont les règles de chemin d'accès sont interprétées par la correspondance du préfixe le plus long. Pour une règle de chemin d'accès, l'équilibrage de charge HTTP(S) interne ne sélectionne qu'une seule règle de chemin d'accès. Cependant, lorsque vous utilisez des règles de routage, plusieurs règles de chemin d'accès peuvent s'appliquer.

Lorsque vous définissez des règles de routage, assurez-vous que les règles en début de liste n'acheminent pas par inadvertance du trafic qu'une règle de routage définie ultérieurement est sensée rediriger. Le service qui reçoit ce trafic qui ne lui est pas destiné rejettera à coup sûr les requêtes, et le service concerné par vos règles de routage recevra peu de trafic, voire aucun trafic.