Configura la administración de tráfico para balanceadores de cargas de HTTP(S) internos

Esta guía contiene ejemplos a fin de configurar la administración del tráfico para el balanceo de cargas de HTTP(S) interno. En este documento, se muestran ejemplos de cómo usar la administración del tráfico en algunos casos prácticos específicos. Muchos otros casos prácticos son posibles.

Antes de comenzar

Configura la administración del tráfico

Puedes usar Cloud Console, gcloud o la API de Cloud Load Balancing para configurar la administración del tráfico. En el entorno de configuración elegido, configura la administración del tráfico mediante configuraciones YAML. Un mapa de URL y un servicio de backend tienen cada uno su archivo YAML. Según la funcionalidad que desees, debes escribir un YAML de mapa de URL, un YAML de servicio de backend o ambos.

Para obtener ayuda con la escritura de estos archivos YAML, puedes usar los siguientes recursos:

Accede a los ejemplos de YAML en Cloud Console

Para acceder a los ejemplos de YAML en Cloud Console, realiza lo siguiente:

  1. Ve a la página Balanceo de cargas en Google Cloud Console.
    Ir a la página Balanceo de cargas
  2. En Balanceo de cargas de HTTP(S), haz clic en Iniciar configuración.
  3. Selecciona Solo entre mis VM. Esta configuración indica que el balanceador de cargas es interno.
  4. Haga clic en Continue.
  5. En la configuración Reglas de enrutamiento, selecciona Host avanzado, ruta de acceso y regla de enrutamiento.
  6. Haz clic en Agregar hosts y comparadores de rutas de acceso.
  7. Haz clic en el vínculo Código de orientación.

Aparecerá la página Ejemplos de comparador de rutas de acceso YAML.

Ejemplos de YAML de mapa de URL

Uno permitido en un mapa de URL

Servicio único

Envía todo el tráfico a un solo servicio. Asegúrate de reemplazar las variables marcadas por []:

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

Divide el tráfico

Divide el tráfico entre varios servicios. Asegúrate de reemplazar las variables marcadas por []:

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

Redireccionamiento de la URL

Muestra un código de respuesta 3xx configurable. También establece el encabezado de respuesta de Ubicación con el URI apropiado, lo que reemplaza el host y la ruta de acceso como se especifica en la acción de redireccionamiento. Asegúrate de reemplazar las variables marcadas por []:

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

Múltiples permitidos en un mapa de URL

Tráfico de duplicación

Además de reenviar la solicitud al servicio de backend seleccionado, envía una solicitud idéntica al servicio de backend duplicado y configurado en una base de “enviar y olvidar”. El balanceador de cargas no espera una respuesta del backend al que envía la solicitud duplicada. La duplicación es útil para probar una versión nueva de un servicio de backend. También puedes usarla para depurar errores de producción en una versión de depuración de tu servicio de backend, en lugar de hacerlo en la versión de producción. Asegúrate de reemplazar las variables marcadas por []:

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]

Reescribe la URL

Vuelve a escribir la parte del nombre de host de la URL, la parte de la ruta de la URL o ambas, antes de enviar una solicitud al servicio de backend seleccionado. Asegúrate de reemplazar las variables marcadas por []:

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]

Solicitud de reintentos

Configura las condiciones en las que el balanceador de cargas reintenta enviar solicitudes con errores, cuánto espera el balanceador de cargas hasta volver a intentarlo y la cantidad máxima de reintentos permitidos. Asegúrate de reemplazar las variables marcadas por []:

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

Tiempo de espera

Especifica el tiempo de espera para la ruta seleccionada. El tiempo de espera se calcula desde el momento en que la solicitud se procesa por completo hasta que la respuesta hace lo mismo. El tiempo de espera incluye todos los reintentos. Asegúrate de reemplazar las variables marcadas por []:

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

Fallas

Presenta errores cuando se entregan solicitudes para simular fallas, incluida la latencia alta, la sobrecarga del servicio, las fallas del servicio y la partición de la red. Esta característica es útil a fin de probar la resistencia de un servicio ante fallas simuladas. Asegúrate de reemplazar las variables marcadas por []`:

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

Configura las políticas de uso compartido de recursos entre dominios (CORS) a fin de controlar la configuración del balanceo de cargas de HTTP(S) interno para aplicar las solicitudes CORS. Asegúrate de reemplazar las variables marcadas por []:

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

Encabezados

Agrega y quita encabezados de solicitud antes de enviar una solicitud al servicio de backend. Además, agrega y quita los encabezados de respuesta después de recibir una respuesta del servicio de backend. Asegúrate de reemplazar las variables marcadas por []:

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

Ejemplos de YAML del servicio de backend

Detección de valores atípicos

Especifica los criterios para la expulsión de las VM de backend o extremos en mal estado en los NEG, junto con criterios que definan cuándo un backend o extremo tiene un estado lo suficientemente bueno como para recibir tráfico otra vez. Asegúrate de reemplazar las variables marcadas por []:

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]

Interrupción del circuito

La interrupción del circuito te permite establecer umbrales de fallas para evitar que las solicitudes del cliente sobrecarguen tus backends. Una vez que las solicitudes alcanzan el límite que configuraste, el balanceador de cargas deja de permitir conexiones nuevas o de enviar solicitudes adicionales, lo que permite que los backends tengan tiempo de recuperarse. Por lo tanto, la interrupción de circuitos evita errores en cascada, ya que muestra un error al cliente en vez de sobrecargar un backend. Esto permite que se entregue parte del tráfico mientras se proporciona tiempo para administrar la situación de sobrecarga, como controlar un aumento repentino de tráfico mediante el aumento de la capacidad a través del ajuste de escala automático.

Establece límites máximos para las solicitudes por conexión y el volumen de conexiones a un servicio de backend. También limita la cantidad de solicitudes y reintentos pendientes. Asegúrate de reemplazar las variables marcadas por []:

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]

Configura la división de tráfico

En este ejemplo, se muestran los siguientes pasos:

  1. Crear plantillas distintas para servicios diferentes

  2. Crear grupos de instancias para esas plantillas

  3. Crea reglas de enrutamiento que configuren una división del tráfico del 95% / 5%.

  4. Envía los comandos curl que muestren que los porcentajes de división del tráfico coinciden de forma aproximada con la configuración.

En estas instrucciones, se supone lo siguiente:

  • La región es us-west1.
  • Se creó un proxy de destino y una regla de reenvío, junto con un mapa de URL llamado l7-ilb-map.
  • La regla de reenvío tiene la dirección 10.1.2.99.

    Consulta las instrucciones que figuran en Configura el balanceo de cargas de HTTP(S) interno para las VM de Compute Engine.

  • El mapa de URL envía todo el tráfico a un servicio de backend llamado red-service, que es el servicio de backend predeterminado.

  • Configura una ruta alternativa que envíe el 5% del tráfico a blue-service y el 95% del tráfico a green-service.

  • Se usa un comparador de rutas.

  • Se usa Cloud Shell o algún otro entorno con bash instalado.

Define los servicios

Con la siguiente función de bash, se crea un servicio de backend, que incluye la plantilla de instancias y el grupo de instancias administrado.

En estas instrucciones, se supone que se creó una verificación de estado de HTTP (l7-ilb-basic-check). Consulta las instrucciones en Configura el balanceo de cargas de HTTP(S) interno para las VM de 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")
}

Crea los servicios

Ahora llama a la función para crear tres servicios: red, green y blue. El servicio red actúa como el servicio predeterminado para las solicitudes a /. Los servicios green y blue se configuraron en /prefix para administrar el 95% y el 5% del tráfico, respectivamente.

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

Crea el mapa de URL

Console

  1. Ve a la página Balanceo de cargas en Google Cloud Console.
    Ir a la página Balanceo de cargas
  2. Haz clic en el vínculo l7-ilb-map.
  3. Haz clic en Editar .

Configura las reglas de enrutamiento nuevas

  1. En Reglas de enrutamiento, selecciona Host avanzado, ruta de acceso y regla de enrutamiento.
  2. En Nuevos hosts y comparadores de rutas de acceso, crea la acción predeterminada. Para esto, establece el Servicio en red-service.
  3. Haz clic en Listo.
  4. Haz clic en Agregar hosts y comparadores de rutas de acceso.
  5. En el campo Hosts, ingresa 10.1.2.99. Esta es la dirección IP de la regla de reenvío de tu balanceador de cargas.
  6. Pega el siguiente contenido de YAML en el cuadro Comparador de rutas de acceso y asegúrate de reemplazar [PROJECT_ID] por tu ID del proyecto:

    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. Haz clic en Listo.

  8. Haz clic en Actualizar.

gcloud

  1. Exporta el mapa de URL existente con el comando gcloud compute url-maps export:

    gcloud compute url-maps export l7-ilb-map \
      --destination=l7-ilb-map-config.yaml \
      --region=us-west1
    
  2. Actualiza el archivo de mapa de URL l7-ilb-map-config.yaml. Para esto, agrega lo siguiente al final del archivo y asegúrate de reemplazar [PROJECT_ID] por el ID de tu proyecto:

    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. Actualiza el mapa de URL con el comando gcloud compute url-maps import:

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

Prueba la configuración

Para probar la configuración, primero asegúrate de que las solicitudes a 10.1.2.99/ (la dirección IP que se configuró antes en el balanceador de cargas) se manejen mediante la configuración red predeterminada.

Luego, asegúrate de que las solicitudes que se enviaron a 10.1.2.99/prefix estén divididas según lo esperado.

Crea una VM cliente

Consulta Crea una instancia de VM en la zona para probar la conectividad.

Envía solicitudes a 10.1.2.99

Establece una conexión SSH con el cliente.

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

Ejecuta el siguiente comando:

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
Verifica los resultados
***
***Results of load balancing to 10.1.2.99:
***
502 red-instance-group-9jvq
498 red-instance-group-sww8

Envía solicitudes a 10.1.2.99/prefix

Envía solicitudes a 10.1.2.99/prefix y anota la división del tráfico.

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
Verifica los resultados
***
***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 configuración Canary envía con éxito el 95% de las solicitudes /prefix al servicio green y el 5% al servicio blue.

El control de tráfico te permite configurar la afinidad de sesión en función de una cookie proporcionada. Si deseas configurar la afinidad de sesión basada en HTTP_COOKIE para un servicio de backend llamado red-service, sigue estas instrucciones.

Para configurar la afinidad de sesión con HTTP_COOKIE, sigue estos pasos:

  1. Usa el comando gcloud compute backend_services export para obtener la configuración del servicio de backend.

    gcloud compute backend-services export red-service \
        --destination=red-service-config.yaml \
        --region=us-west1
    
  2. Actualiza el archivo red-service-config.yaml de la siguiente manera:

    sessionAffinity: 'HTTP_COOKIE'
    localityLbPolicy: 'RING_HASH'
    consistentHash:
     httpCookie:
      name: 'http_cookie'
      path: '/cookie_path'
      ttl:
        seconds: 100
        nanos: 30
     minimumRingSize: 10000
    
  3. En el archivo red-service-config.yaml, borra la línea que contiene lo siguiente:

    sessionAffinity: NONE
    
  4. Actualiza el archivo de configuración del servicio de backend mediante la ejecución del siguiente comando:

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

Soluciona problemas

Usa esta información para solucionar problemas cuando el tráfico no se enrute de acuerdo con las reglas de enrutamiento ni las políticas de tráfico que configuraste.

Para obtener información sobre el registro y la supervisión, consulta Registro y supervisión de HTTP(S) interno.

Síntomas:

  • Mayor tráfico a los servicios en reglas que se encuentran por encima de la regla en cuestión
  • Aumento inesperado en las respuestas HTTP 4xx y 5xx para una regla de enrutamiento determinada

Solución: verifica el orden de tus reglas de enrutamiento. Las reglas de enrutamiento se interpretan en el orden en que se especifican.

Las reglas de enrutamiento dentro de una asignación de URL se interpretan en el orden en que se especifican. Esto difiere de la forma en la que se interpretan las reglas de ruta de acceso, que es por la coincidencia de prefijo más largo. Para una regla de ruta de acceso, el balanceo de cargas de HTTP(S) interno solo seleccionará una única regla de ruta de acceso; sin embargo, cuando usas reglas de enrutamiento, podría aplicarse más de una.

Cuando definas reglas de enrutamiento, asegúrate de que las reglas ubicadas en la parte superior de la lista no desvíen de forma involuntaria el tráfico que, de lo contrario, se enrutaría mediante una regla de enrutamiento posterior. Es probable que el servicio que recibe tráfico mal dirigido rechace las solicitudes y que el servicio en tus reglas de enrutamiento reciba poco o nada de tráfico.