Configura el balanceo de cargas basado en verificaciones de estado

En este documento, se muestra cómo implementar la alta disponibilidad para direcciones IP persistentes en Google Kubernetes Engine (GKE) con el balanceo de cargas basado en verificaciones de estado. Si bien las configuraciones de IP persistente estándar asignan una sola dirección IP persistente a un solo Pod, el balanceo de cargas basado en verificaciones de estado te permite distribuir el tráfico de una o más direcciones IP persistentes en un grupo de Pods en buen estado.

Para reclamar direcciones IP persistentes específicas y determinar qué Pods reciben tráfico, crea un recurso personalizado de GKEIPRoute. Al integrar el recurso GKEIPRoute con las verificaciones de estado regionales, GKE supervisa tus cargas de trabajo en la capa de redes y enruta el tráfico solo a los Pods que están listos para recibirlo. También puedes designar Pods de copia de seguridad opcionales con el objeto GKEIPRoute. GKE solo enruta el tráfico a estos Pods en espera si todos los Pods activos principales fallan en su verificación de estado.

Requisitos y limitaciones

  • Para usar el balanceo de cargas basado en verificaciones de estado, tu clúster debe ejecutar la versión 1.32.3-gke.1440000 de GKE o una posterior. GKE admite la selección de Pods de copia de seguridad solo en la versión 1.35.0-gke.1403000 o posterior.
  • Tu clúster debe tener habilitados GKE Dataplane V2 y la API de Gateway.
  • Un solo objeto GKEIPRoute admite solo un Pod coincidente por nodo. Si varios Pods en un nodo coinciden con el selector de Pods de GKEIPRoute, GKE elige el Pod creado más recientemente en ese nodo.
  • No puedes modificar una clase Gateway después de crear el objeto GKEIPRoute.
  • El balanceo de cargas basado en verificaciones de estado solo admite el tráfico que se inicia desde fuera de la carga de trabajo. No se admite el tráfico iniciado desde la carga de trabajo hacia la dirección IP persistente.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se describen en este documento.

Implementa el balanceo de cargas basado en verificaciones de estado

En esta sección, se resume el flujo de trabajo para implementar el balanceo de cargas basado en verificaciones de estado:

  1. Crea una verificación de estado regional: Define los parámetros que GKE usa para supervisar el estado de tus Pods. Este objeto le indica a la capa de redes qué extremos están en buen estado y son aptos para recibir tráfico de la dirección IP persistente.
  2. Crea un clúster: Configura un clúster de GKE con GKE Dataplane V2 y la API de Gateway habilitados. Estos componentes proporcionan la infraestructura subyacente necesaria para administrar el enrutamiento de IP persistente y el balanceo de cargas basado en verificaciones de estado.
  3. Reservar una dirección IP: Selecciona y reserva una dirección IP interna o externa estática en la misma región que tu clúster. Esta dirección sirve como punto de entrada persistente que GKE distribuirá en tu grupo de Pods activos o de copia de seguridad.
  4. Crea una puerta de enlace: Configura un objeto de puerta de enlace para administrar tus direcciones IP persistentes reservadas. El objeto GKEIPRoute reclama y usa direcciones IP específicas de la puerta de enlace para tus cargas de trabajo.
  5. Crea un objeto GKEIPRoute: Define las reglas de enrutamiento que asignan tu dirección IP persistente a un grupo de Pods con selectores de etiquetas. Dentro de este objeto, haces referencia a tu verificación de estado regional y, de manera opcional, designas Pods de copia de seguridad para situaciones de conmutación por error.
  6. Ver extremos coincidentes: Verifica que GKE haya identificado correctamente tus Pods activos y de copia de seguridad inspeccionando los EndpointSlices generados automáticamente. Este paso confirma que tus etiquetas coinciden con los Pods esperados y que la capa de redes está lista para enrutar el tráfico.

Paso 1: Crea una verificación de estado regional y reglas de firewall

Para crear una verificación de estado regional, sigue los pasos que se indican en Crea verificaciones de estado. El nombre que proporciones aquí se usará en la configuración de GKEIPRoute. Por ejemplo:

gcloud compute health-checks create http reg-lb-hc \
    --region=us-central1 \
    --check-interval=5s \
    --timeout=5s \
    --healthy-threshold=2 \
    --unhealthy-threshold=2

Para permitir que los sondeos de verificación de estado de Google Cloud lleguen a tus nodos, también debes crear reglas de firewall.

Paso 2: Crea un clúster de GKE

Crea un clúster con la API de Gateway y GKE Dataplane V2 habilitados. Por ejemplo:

gcloud container clusters create cluster-1 \
    --enable-dataplane-v2 \
    --gateway-api=standard \
    --region=us-central1

Si configuras el objeto GKEIPRoute en una red de VPC diferente de la red de VPC predeterminada del clúster, debes crear un clúster de GKE con capacidades de varias redes. Para obtener más información, consulta Configura la compatibilidad con varias redes para Pods.

Paso 3: Reserva direcciones IP

Reserva las direcciones IP que deseas usar para tus cargas de trabajo. Puedes elegir entre reservar direcciones IP proporcionadas por Google o usar tus propias (BYOIP).

Paso 3a: Reserva las direcciones IP proporcionadas por Google

Para reservar direcciones IP externas, ejecuta el siguiente comando:

gcloud compute addresses create ADDRESS_NAME \
   --region=REGION

Reemplaza lo siguiente:

  • ADDRESS_NAME: Es el nombre que deseas asociar a esta dirección.
  • REGION: Es la región en la que deseas reservar esta dirección. Esta región debe ser la misma que el recurso al que deseas conectar la dirección IP.

    Nota: Debes especificar una región cuando reservas una dirección IP, ya que las reglas de reenvío, que controlan el enrutamiento de tráfico para direcciones IP persistentes, son regionales. Tu dirección IP y el clúster de GKE deben estar en la misma región para que el enrutamiento funcione de forma correcta.

Para reservar direcciones IP internas, ejecuta el siguiente comando:

gcloud compute addresses create ADDRESS_NAME \
    --region REGION
    --subnet SUBNETWORK \
    --addresses IP_ADDRESS

Reemplaza lo siguiente:

  • ADDRESS_NAME: Son los nombres de una o más direcciones que deseas reservar. En el caso de varias direcciones, especifica todas las direcciones como una lista, separadas por espacios. Por ejemplo, example-address-1 example-address-2 example-address-3.
  • REGION: Es la región para esta solicitud.
  • SUBNETWORK: Es la subred para esta dirección IPv4 interna.
  • IP_ADDRESS: una dirección IP interna sin usar del rango de direcciones IP principal de la subred seleccionada

Para garantizar que el tráfico se enrute correctamente dentro de tu red privada, las direcciones IP internas deben pertenecer a la subred predeterminada del clúster o a una subred de red adicional.

Para obtener más información sobre las direcciones IP internas y externas, o para ver cómo reservar direcciones con la consola de Google Cloud , consulta Reserva una dirección IP externa estática y Reserva una dirección IP interna estática.

Paso 3b: Traslada tus propias direcciones IP (BYOIP)

Puedes proporcionar tus propias direcciones IP (BYOIP), en lugar de depender de las direcciones IP proporcionadas por Google. BYOIP es útil si necesitas direcciones IP específicas para tus aplicaciones o si trasladas sistemas existentes a Google Cloud. Si quieres usar BYOIP, Google valida que eres el propietario del rango de direcciones IP y, después de importar las direcciones IP a Google Cloud, puedes asignarlas como las direcciones IP para los Pods de GKE. Para obtener más información, consulta Usa tus propias direcciones IP.

Paso 4: Crea objetos Gateway

Crea una puerta de enlace con una de las siguientes clases de Gateway, que solo admiten el tipo de red L3:

  • gke-passthrough-lb-external-managed o
  • gke-passthrough-lb-internal-managed.

En el siguiente ejemplo, se define una puerta de enlace que administra un grupo de direcciones IP externas:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: lb-gateway
spec:
  gatewayClassName: gke-passthrough-lb-external-managed

  listeners:
    - name: default
      port: 443
      protocol: none
      allowedRoutes:
        namespaces:
          from: All

  addresses:
    - value: "34.123.10.1/32"
      type: "gke.networking.io/cidr"
    - value: "34.123.10.2/32"
      type: "gke.networking.io/cidr"

En el ejemplo anterior, ten en cuenta los siguientes campos:

  • addresses: Enumera todos los rangos de direcciones IP para los que la puerta de enlace específica administra permisos.
  • listeners: Identifica los espacios de nombres desde los que los objetos GKEIPRoute pueden hacer referencia a esta puerta de enlace.

Para obtener detalles sobre el uso de Listener, consulta Crea objetos de Gateway.

Paso 5: Crea un objeto GKEIPRoute con la configuración del balanceo de cargas y la verificación de estado

Crea un objeto GKEIPRoute en el que definas tus selectores de Pods principal y de copia de seguridad, y asocia la verificación de estado que creaste en el paso 1.

kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
  namespace: default
  name: my-ip-route
spec:
  parentRefs:
  - name: lb-gateway
  addresses:
  - value: "34.123.10.1/32"
    type: "gke.networking.io/cidr"
  - value: "34.123.10.2/32"
    type: "gke.networking.io/cidr"
  network: default
  podSelector:
    matchLabels:
      component: activePodSelector

  loadBalancing:
    healthCheckName: "reg-lb-hc"
    backupPodSelector:
      namespaceSelector:
        matchLabels:
          environment: test
          dc: us-central
      podSelector:
        matchLabels:
          component: backupPodSelector
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: proxy-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: proxy
  template:
    metadata:
      # annotations:  <- Include these lines if the pods are multi-nic pods
      #   networking.gke.io/default-interface: 'eth0'
      #   networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
      labels:
        component: proxy
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

Ten en cuenta lo siguiente:

  • podSelector: Identifica los Pods activos principales que reciben tráfico de las direcciones IP persistentes definidas. Este campo usa etiquetas para hacer coincidir los Pods dentro del mismo espacio de nombres que el recurso GKEIPRoute. GKE distribuye el tráfico entre todos los Pods en buen estado que coinciden con este selector. Si varios Pods coincidentes residen en el mismo nodo, GKE selecciona solo el Pod creado más recientemente para recibir tráfico. Las etiquetas definidas aquí no deben superponerse con las del campo backupPodSelector. Este campo es mutable.
  • backupPodSelector: Define los Pods en espera que reciben tráfico solo si todos los Pods principales que coinciden con el objeto podSelector fallan en sus verificaciones de estado. Este selector incluye lo siguiente:
    • namespaceSelector: Determina en qué espacios de nombres busca GKE para encontrar estos Pods de copia de seguridad. Puedes limitar la búsqueda a espacios de nombres específicos con selectores de etiquetas. Si este campo se omite o está vacío, GKE buscará Pods de copia de seguridad en todos los espacios de nombres del clúster.
    • podSelector: Coincide con los Pods de copia de seguridad según sus etiquetas. Estas etiquetas deben ser distintas de las que se usan en el objeto podSelector principal.

Para obtener más detalles sobre los otros campos de este manifiesto, consulta Crea el objeto GKEIPRoute.

Paso 6: Usa las direcciones IP asignadas dentro del Pod

Asignar una dirección IP a un Pod de GKE con un objeto GKEIPRoute no hace que la aplicación pueda usar de forma automática las direcciones IP. Las direcciones IP se manejan a nivel de enrutamiento de red, pero la configuración predeterminada del Pod no las tendrá en cuenta. Debes configurar la especificación del Pod para que reconozca y use la dirección dentro del Pod. Para lograrlo, tu Pod requiere permisos de privilegios.

Puedes configurar la especificación de tu Pod con una de las siguientes opciones:

  • Modificar net.ipv4.ip_nonlocal_bind sysctl

    Puedes modificar la configuración del sistema para permitir que tu aplicación use direcciones IP no asignadas directamente a su interfaz configurando net.ipv4.ip_nonlocal_bind sysctl en tu Pod securityContext. Esta opción es útil si tu aplicación puede vincularse a una dirección IP que no está en una interfaz.

    Agrega lo siguiente a la especificación YAML de tu Deployment o StatefulSet en spec.template.spec:

    securityContext:
      sysctls:
      - name: net.ipv4.ip_nonlocal_bind
        value: "1"
    
  • Agrega la dirección IP asignada a la interfaz del Pod

    Puedes agregar de forma manual la dirección IP que reclama el objeto GKEIPRoute a una de las interfaces del Pod con un contenedor de inicialización. Esto hace que la dirección IP sea visible para el Pod como si se hubiera asignado directamente. Esto requiere la capacidad NET_ADMIN.

    Agrega lo siguiente a la especificación YAML de tu Deployment o StatefulSet en spec.template.spec:

    initContainers:
    - name: configure-ips
      image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
      command: ['sh', '-c', 'ip address add ASSIGNED_IP/32 dev eth0']
      securityContext:
        capabilities:
          add:
          - NET_ADMIN
    

    Reemplaza ASSIGNED_IP por una de las direcciones IP asignadas al objeto GKEIPRoute.

  • Sockets sin procesar: Para obtener aún más control, la aplicación puede interactuar directamente con la pila de red (avanzado).

  • Pila de direcciones IP del espacio de usuario: En casos especializados, se puede ejecutar una aplicación distinta dentro del Pod para administrar la dirección IP (muy avanzada).

Paso 7: Habilita el ARP para las direcciones IP asignadas (solo para la red predeterminada)

Para generar solicitudes y respuestas válidas del Protocolo de resolución de direcciones (ARP) y establecer una conexión nueva con un Pod a través de la dirección IP asignada por el objeto GKEIPRoute en la red predeterminada, debes configurar la variable arp_announce.

Para configurar la variable arp_announce, ejecuta el siguiente comando en tu Pod:

echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce

donde la variable arp_announce controla cómo se manejan los anuncios de ARP. Si se configura en "2", se garantiza que se realicen anuncios ARP para la dirección IP persistente, lo que permite que otros dispositivos de la red conozcan la nueva asociación.

Paso 8: Visualiza los Endpoints coincidentes

Para administrar la distribución del tráfico, GKE crea objetos EndpointSlice para cada objeto GKEIPRoute. Estas segmentaciones actúan como un registro de todos los Pods designados como destinos de enrutamiento para esa ruta específica.

GKE genera objetos EndpointSlice separados para los extremos activos y de copia de seguridad. El sistema ajusta automáticamente la cantidad de EndpointSlices según tu carga de trabajo. Si bien un solo EndpointSlice admite hasta 1,000 endpoints, GKE crea segmentos adicionales si la cantidad de Pods coincidentes supera este límite.

Para ver todos los objetos EndpointSlice de un objeto GKEIPRoute específico, ejecuta el siguiente comando:

kubectl get endpointslices --all-namespaces -l \
  networking.gke.io/gkeiproute-name=GKEIPROUTE_NAME,\
  networking.gke.io/gkeiproute-namespace=GKEIPROUTE_NAMESPACE

Reemplaza lo siguiente:

  • GKEIPROUTE_NAME: Es el nombre del manifiesto de GKEIPRoute.
  • GKEIPROUTE_NAMESPACE: Es el espacio de nombres del manifiesto de GKEIPRoute.

El siguiente resultado muestra un ejemplo de un EndpointSlice:

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
 name: {gkeiproute_name-truncated}-{gkeiproute_namespace-truncated}-backup-{unique_hash}
 namespace: {gkeiproute_namespace}
 labels:
  endpointslice.kubernetes.io/managed-by: gkeiproute-controller
  networking.gke.io/gkeiproute-name: {gkeiproute_name}
  networking.gke.io/gkeiproute-namespace: {gkeiproute_namespace}
  networking.gke.io/pip-es-role: backup
 ownerReferences:
  - kind: GKEIPRoute
    name: {gkeiproute_name}
    apiVersion: networking.gke.io/v1
    uid: {uid}
    controller: true
addressType: IPv4
endpoints:
 - addresses:
     - "{pod_ip_address}"
   targetRef:
     Name: {pod_name}
   nodeName: {node_name}

Para ver los objetos EndpointSlice específicamente para los extremos activos o de copia de seguridad, filtra los resultados con la etiqueta pip-eps-role. Por ejemplo:

kubectl get endpointslices --all-namespaces -l \
   networking.gke.io/pip-eps-role=ROLE \
  networking.gke.io/gkeiproute-name=GKEIPROUTE_NAME,

Reemplaza lo siguiente:

  • ROLE: Es el tipo de extremo que deseas ver, ya sea active o backup.
  • GKEIPROUTE_NAME: Es el nombre de tu objeto GKEIPRoute específico.

Soluciona problemas del balanceo de cargas basado en verificaciones de estado

En esta sección, se muestra cómo resolver problemas relacionados con el balanceo de cargas basado en verificaciones de estado.

Algunos Pods activos no están en buen estado, pero los Pods de copia de seguridad no reciben tráfico

Síntoma

El estado de GKEIPRoute muestra Ready, lo que indica que se completó la configuración de la dirección IP para los Pods coincidentes. Las verificaciones de estado o cualquier otro diagnóstico muestran que algunos Pods activos no están en buen estado. Sin embargo, los Pods de copia de seguridad no reciben tráfico.

Causa

Los Pods de copia de seguridad no reciben tráfico hasta que todos los Pods activos están en mal estado. Hasta entonces, todo el tráfico se distribuye entre los Pods activos y en buen estado restantes.

Solución

Si es necesario, actualiza las etiquetas de los campos podSelector para que ya no coincidan con ningún Pod activo. GKE enruta automáticamente el tráfico al grupo de backends.

Se configuró GKEIPRoute, pero no todos los Pods reciben tráfico

Síntoma

El estado de GKEIPRoute muestra Ready, lo que indica que se completó la configuración de la dirección IP para los Pods coincidentes, pero algunos de ellos no reciben tráfico.

Causa

Es posible que los Pods que no reciben tráfico no estén en buen estado o no respondan correctamente a las verificaciones de estado. Ten en cuenta que, si todos los Pods coincidentes no están en buen estado, GKE distribuirá el tráfico entre todos los Pods, independientemente de su estado.

Solución

  • Verifica que el Pod esté en buen estado: Usa Google Cloud CLI o la consola deGoogle Cloud para verificar que el Pod responda correctamente a las verificaciones de estado.
  • Investiga más si es necesario: Si el Pod está en mal estado, verifica que hayas configurado correctamente los firewalls para las verificaciones de estado y que tu Pod responda.

Errores de configuración del balanceador de cargas no válidos

En esta sección, se te ayudará a solucionar problemas relacionados con errores de estado de GKEIPRoute.

Backup pod and active pod are on the same node

Síntoma

El estado de GKEIPRoute informa el siguiente error:

invalid LB configuration: Backup pod %s and active pod %s are on the same node %s. Active and backup pods must reside on different nodes.

Causa

Un Pod activo y un Pod de copia de seguridad que coinciden con el mismo objeto GKEIPRoute se programan en el mismo nodo. En otras palabras, hay Pods que coinciden con los objetos podSelector activos y de copia de seguridad en el mismo nodo.

Solución

Asegúrate de que los Pods activos y de copia de seguridad estén en nodos diferentes. Actualiza la configuración de GKEIPRoute y ajusta tus etiquetas podSelector o backupPodSelector para que no haya dos Pods en el mismo nodo que coincidan con el mismo objeto GKEIPRoute.

Pod cannot be selected as both an active and a backup pod

Síntoma

El estado de GKEIPRoute informa el siguiente error:

invalid LB configuration: pod %s cannot be selected as both an active and a backup pod. Active and backup pod sets must be mutually exclusive

Causa

Uno o más Pods coinciden con los selectores de etiquetas para el campo podSelector (activo) y el campo backupPodSelector (en espera). GKE requiere que estos dos grupos se excluyan mutuamente. Un solo Pod no puede servir como su propia copia de seguridad.

Solución

Asegúrate de que tus Pods activos y de copia de seguridad sean únicos. Modifica el campo podSelector o el campo backupPodSelector en tu manifiesto de GKEIPRoute para usar claves y valores de etiquetas más específicos o distintos.

Estado de NoPodsFound

Síntoma

El manifiesto de GKEIPRoute muestra un estado de NoPodsFound, lo que indica que no hay Pods dentro de los espacios de nombres que tengan etiquetas coincidentes.

Causas posibles

  • Etiquetas incorrectas: Es posible que el Pod con el que deseas usar la dirección IP configurada tenga las etiquetas incorrectas o ninguna.
  • No existen Pods: Si reactionMode == Exists, verifica si el Pod se asigna a un nodo mediante la verificación del campo pod.Spec.nodeName. Es posible que no haya ningún Pod en ejecución en el espacio de nombres de GKEIPRoute que coincida con el selector.
  • Los Pods no están listos: Si reactionMode == ReadyCondition, verifica si el estado del Pod es READY. Si existe un Pod coincidente, pero no está en un estado READY, el Pod no puede entregar tráfico y no se selecciona.

Solución

  • Verifica las etiquetas: Confirma que las etiquetas del campo podSelector de tu objeto GKEIPRoute coincidan con las etiquetas que aplicaste al Pod deseado.
  • Verifica la existencia del Pod: Asegúrate de que exista un Pod con las etiquetas correctas en los espacios de nombres del objeto GKEIPRoute que especifican los objetos Listener de tu puerta de enlace. Si reactionMode == Exists, verifica si el Pod está asignado a un nodo mediante la revisión del campo pod.Spec.nodeName.
  • Confirma la preparación del Pod: Si reactionMode == ReadyCondition, verifica si el estado del Pod es READY. Asegúrate de que el Pod esté en el estado Ready con el siguiente comando:

    kubectl get pods -n NAMESPACE
    

    Los Pods en otros estados (por ejemplo, Pending o Error) no están seleccionados.

Estado Mutated cuando se encontró un Pod coincidente y la programación de direcciones IP de GKEIPRoute está en curso

Síntoma

El estado de GKEIPRoute muestra Mutated, lo que indica que la configuración de la dirección IP para un Pod coincidente está en curso.

Posible causa:

Puedes esperar el estado Mutated durante la configuración mientras el sistema configura la ruta de datos de GKE y los recursos de Google Cloud para la dirección IP configurada.

Solución

  1. Espera y vuelve a intentar: En la mayoría de los casos, el proceso de configuración se completa de forma automática en un período corto. Verifica el estado después de esperar. Cambiará a Ready cuando se complete de forma correcta.
  2. Investiga más a fondo (si es necesario): Si el estado Mutated persiste por un período prolongado, esto podría indicar un error de configuración. Examina las otras condiciones de estado en tu objeto GKEIPRoute:

    • Aceptado: Indica si tu configuración de GKEIPRoute es válida.
    • GCPReady: Indica si los recursos de Google Cloud están configurados como se espera.

Busca mensajes de error dentro de estas condiciones para ayudar a solucionar el problema.

¿Qué sigue?