Usa el balanceo de cargas de Maglev en GKE Dataplane V2

En este documento, se muestra cómo configurar y verificar el balanceo de cargas de Maglev para los servicios en GKE Dataplane V2.

Maglev es un algoritmo de hash coherente que proporciona balanceo de cargas de alta capacidad de procesamiento y baja latencia. Maglev minimiza las pérdidas de paquetes y las interrupciones de conexión cuando los Pods de backend se escalan, actualizan o reprograman, ya que ayuda a garantizar que el mismo flujo se asigne de forma coherente al mismo backend.

Para obtener más información, consulta el documento de investigación Maglev consistent hashing algorithm (Algoritmo de hash coherente de Maglev).

Recomendamos esta función para cargas de trabajo con conexiones de larga duración o aplicaciones con estado en las que los cambios en el backend no deberían interrumpir los flujos existentes.

Para obtener información sobre la sobrecarga de recursos y las consideraciones de escalabilidad, consulta Conceptos de GKE Dataplane V2.

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 la 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 indican en este documento.

Requisitos previos y límites

  • Versión de GKE: 1.36.0-gke.2882000 y posteriores
  • GKE Dataplane V2: habilitado
  • Modos de clúster: Autopilot y Standard

Crea un clúster de GKE con GKE Dataplane V2

Para usar Maglev, debes tener un clúster de GKE con GKE Dataplane V2 habilitado.

Autopilot

Los clústeres de Autopilot tienen GKE Dataplane V2 habilitado de forma predeterminada. Para crear un clúster de Autopilot y recuperar su configuración, ejecuta el siguiente comando:

gcloud container clusters create-auto CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --release-channel=rapid
gcloud container clusters get-credentials CLUSTER_NAME \
    --region=COMPUTE_REGION

Estándar

Para habilitar GKE Dataplane V2 en un clúster de Standard, usa la marca --enable-dataplane-v2. Para crear un clúster de Standard y recuperar su configuración, ejecuta el siguiente comando:

gcloud container clusters create CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --enable-dataplane-v2 \
    --cluster-version=1.36.0-gke.2882000
gcloud container clusters get-credentials CLUSTER_NAME \
    --zone=COMPUTE_ZONE

Implementa una aplicación de backend

Antes de configurar tus servicios de balanceo de cargas, implementa una aplicación de backend para controlar el tráfico. Este Deployment ejecuta cinco réplicas de la aplicación de ejemplo hello-app.

  1. Guarda el siguiente manifiesto como echo-backend.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-backend
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: echo-backend
      template:
        metadata:
          labels:
            app: echo-backend
        spec:
          containers:
          - name: hello
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
            ports:
            - containerPort: 8080
    
  2. Aplica el manifiesto

    kubectl apply -f echo-backend.yaml
    

Configura servicios de balanceo de cargas

Puedes configurar los servicios para que usen el algoritmo de balanceo de cargas de Maglev o el algoritmo de balanceo de cargas aleatorio predeterminado. Ambos Services se orientan al Deployment echo-backend que se creó en el paso anterior.

Configura un servicio de Maglev

Para habilitar el balanceo de cargas de Maglev, agrega la anotación gke.networking.io/lb-algorithm: "maglev" a los metadatos del Service durante la creación.

  1. Guarda el siguiente manifiesto como maglev-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: maglev-service
      annotations:
        gke.networking.io/lb-algorithm: "maglev"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. Aplica el manifiesto

    kubectl apply -f maglev-service.yaml
    

Configura un Service aleatorio

De forma predeterminada, los servicios usan un algoritmo de balanceo de cargas aleatorio. No es necesario especificar una anotación para usar el algoritmo predeterminado, pero en el siguiente ejemplo se configura de forma explícita para la comparación.

  1. Guarda el siguiente manifiesto como random-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: random-service
      annotations:
        gke.networking.io/lb-algorithm: "random"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. Aplica el manifiesto

    kubectl apply -f random-service.yaml
    

Verifica la coherencia del tráfico

Puedes verificar las diferencias en la coherencia del enrutamiento entre Maglev y el balanceo de cargas aleatorio implementando Pods de clientes de prueba que envían tráfico desde un puerto de origen fijo.

Verifica la coherencia del tráfico de Maglev

Maglev enruta las solicitudes del mismo puerto de origen de forma coherente al mismo Pod de backend.

  1. Guarda el siguiente manifiesto como client-maglev.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-maglev
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://maglev-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    

    La marca --local-port fuerza el puerto de origen, y el encabezado Connection: close ayuda a garantizar que el cliente pueda reutilizar el puerto de origen de inmediato para solicitudes posteriores.

  2. Aplica el manifiesto

    kubectl apply -f client-maglev.yaml
    
  3. Mientras se ejecuta el Pod, verifica los registros:

    kubectl logs client-maglev
    

    Resultado esperado:

    El resultado muestra el mismo nombre de host impreso de forma repetida, lo que indica que todo el tráfico del cliente se enruta de forma coherente al mismo Pod de backend:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-abcde
    

Verifica la distribución del tráfico predeterminada (aleatoria)

El Service predeterminado distribuye el tráfico desde el mismo puerto de origen a diferentes Pods de backend.

  1. Guarda el siguiente manifiesto como client-random.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-random
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://random-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    
  2. Aplica el manifiesto

    kubectl apply -f client-random.yaml
    
  3. Mientras se ejecuta el Pod, verifica los registros:

    kubectl logs client-random
    

    Resultado esperado:

    En el resultado, se muestran varios nombres de host diferentes, lo que indica que el tráfico se distribuye entre diferentes Pods:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-fghij
    Hostname: echo-backend-5c78f66dbf-klmno
    ...
    

Limpieza

Para limpiar los recursos que se usaron en este instructivo, ejecuta los siguientes comandos:

  1. Borra los Pods, los Services y el Deployment del cliente:

    kubectl delete service maglev-service random-service
    kubectl delete deployment echo-backend
    kubectl delete pod client-maglev client-random
    
  2. Borra los clústeres de GKE:

Autopilot

gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION

Estándar

gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE