Uso del balanceo de carga de conexiones con descarga acelerada en Istio

Acelere el balanceo de conexiones usando la configuración de balanceo de conexiones DLB en gateways de Istio.

Aug 8, 2023 | Por Loong Dai - Intel

¿Qué es el balanceo de carga de conexiones?

El balanceo de carga es una solución de red central utilizada para distribuir el tráfico entre múltiples servidores en una granja de servidores. Los balanceadores de carga mejoran la disponibilidad y capacidad de respuesta de las aplicaciones y previenen la sobrecarga del servidor. Cada balanceador de carga se sitúa entre los dispositivos cliente y los servidores backend, recibiendo y luego distribuyendo las solicitudes entrantes a cualquier servidor disponible capaz de cumplirlas.

Para un servidor web común, generalmente tiene múltiples trabajadores (procesadores o hilos). Si muchos clientes se conectan a un solo trabajador, este trabajador se vuelve ocupado y genera latencia de cola larga mientras otros trabajadores funcionan en estado libre, afectando el rendimiento del servidor web. El balanceo de carga de conexiones es la solución para esta situación, que también se conoce como balanceo de conexiones.

¿Qué hace Istio para el balanceo de carga de conexiones?

Istio utiliza Envoy como data plane.

Envoy proporciona una implementación de balanceo de carga de conexiones llamada Exact connection balancer. Como su nombre lo indica, se mantiene un bloqueo durante el balanceo para que los recuentos de conexiones estén casi exactamente equilibrados entre los trabajadores. Es “casi” exacto en el sentido de que una conexión podría cerrarse en paralelo, haciendo que los recuentos sean incorrectos, pero esto debería rectificarse en la siguiente aceptación. Este balanceador sacrifica el rendimiento de aceptación por precisión y debe usarse cuando hay un pequeño número de conexiones que rara vez cambian, por ejemplo, salida gRPC de service mesh.

Obviamente, no es adecuado para un gateway de entrada ya que un gateway de entrada acepta miles de conexiones en un corto período de tiempo, y el costo de recursos del bloqueo provoca una gran caída en el rendimiento.

Ahora, Envoy ha integrado Intel® Dynamic Load Balancing (Intel®DLB) para acelerar el balanceo de carga de conexiones en casos de alto número de conexiones como gateway de entrada.

Cómo Intel® Dynamic Load Balancing acelera el balanceo de carga de conexiones en Envoy

Intel DLB es un sistema gestionado por hardware de colas y árbitros que conecta productores y consumidores. Es un dispositivo PCI previsto para residir en el uncore del CPU del servidor y puede interactuar con software que se ejecuta en los núcleos, y potencialmente con otros dispositivos.

Intel DLB implementa las siguientes características de balanceo de carga:

Hay tres tipos de colas de balanceo de carga:

Se espera que un gateway de entrada procese tantos datos como sea posible lo más rápido posible, por lo que el balanceo de carga de conexiones Intel DLB utiliza una cola desordenada.

Cómo usar el balanceo de carga de conexiones Intel DLB en Istio

Con la versión 1.17, Istio oficialmente soporta el balanceo de carga de conexiones Intel DLB.

Los siguientes pasos muestran cómo usar el balanceo de carga de conexiones Intel DLB en un Ingress Gateway de Istio en una máquina SPR (Sapphire Rapids), asumiendo que el clúster de Kubernetes está en ejecución.

Paso 1: Preparar el entorno DLB

Instale el controlador Intel DLB siguiendo las instrucciones en el sitio oficial del controlador Intel DLB.

Instale el plugin de dispositivo Intel DLB con el siguiente comando:

$ kubectl apply -k https://github.com/intel/intel-device-plugins-for-kubernetes/deployments/dlb_plugin?ref=v0.26.0

Para más detalles sobre el plugin de dispositivo Intel DLB, consulte la página principal del plugin de dispositivo Intel DLB.

Puede verificar el recurso del dispositivo Intel DLB:

$ kubectl describe nodes | grep dlb.intel.com/pf
  dlb.intel.com/pf:   2
  dlb.intel.com/pf:   2
...

Paso 2: Descargar Istio

En este blog usamos 1.17.2. Descargemos la instalación:

$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 TARGET_ARCH=x86_64 sh -
$ cd istio-1.17.2
$ export PATH=$PWD/bin:$PATH

Puede verificar que la versión es 1.17.2:

$ istioctl version
no running Istio pods in "istio-system"
1.17.2

Paso 3: Instalar Istio

Cree una configuración de instalación para Istio, tenga en cuenta que asignamos 4 CPUs y 1 dispositivo DLB al gateway de entrada y establecemos la concurrencia en 4, que es igual al número de CPU.

$ cat > config.yaml << EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: default
  components:
    ingressGateways:
    - enabled: true
      name: istio-ingressgateway
      k8s:
        overlays:
          - kind: Deployment
            name: istio-ingressgateway
        podAnnotations:
          proxy.istio.io/config: |
            concurrency: 4
        resources:
          requests:
            cpu: 4000m
            memory: 4096Mi
            dlb.intel.com/pf: '1'
          limits:
            cpu: 4000m
            memory: 4096Mi
            dlb.intel.com/pf: '1'
        hpaSpec:
          maxReplicas: 1
          minReplicas: 1
  values:
    telemetry:
      enabled: false
EOF

Use istioctl para instalar:

$ istioctl install -f config.yaml --set values.gateways.istio-ingressgateway.runAsRoot=true -y
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete                                                                                                                                                                                                                                                                       Making this installation the default for injection and validation.

Thank you for installing Istio 1.17.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/hMHGiwZHPU7UQRWe9

Paso 4: Configurar el servicio backend

Dado que queremos usar el balanceo de carga de conexiones DLB en el gateway de entrada de Istio, primero necesitamos crear un servicio backend.

Usaremos una muestra proporcionada por Istio para probar, httpbin.

$ kubectl apply -f samples/httpbin/httpbin.yaml
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  # The selector matches the ingress gateway pod labels.
  # If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
EOF
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "httpbin.example.com"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /delay
    route:
    - destination:
        port:
          number: 8000
        host: httpbin
EOF

Ahora ha creado una configuración de servicio virtual para el servicio httpbin que contiene dos reglas de ruta que permiten el tráfico para las rutas /status y /delay.

La lista de gateways especifica que solo se permiten solicitudes a través de su httpbin-gateway. Todas las demás solicitudes externas serán rechazadas con una respuesta 404.

Paso 5: Habilitar el balanceo de carga de conexiones DLB

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: dlb
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: LISTENER
    match:
      context: GATEWAY
    patch:
      operation: MERGE
      value:
        connection_balance_config:
            extend_balance:
              name: envoy.network.connection_balance.dlb
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.network.connection_balance.dlb.v3alpha.Dlb
EOF

Se espera que si verifica el registro del pod del gateway de entrada istio-ingressgateway-xxxx verá entradas de registro similares a:

$ export POD="$(kubectl get pods -n istio-system | grep gateway | awk '{print $1}')"
$ kubectl logs -n istio-system ${POD} | grep dlb
2023-05-05T06:16:36.921299Z     warning envoy config external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:46        dlb device 0 is not found, use dlb device 3 instead     thread=35

Envoy detectará y elegirá automáticamente el dispositivo DLB.

Paso 6: Probar

$ export HOST="<YOUR-HOST-IP>"
$ export PORT="$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')"
$ curl -s -I -HHost:httpbin.example.com "http://${HOST}:${PORT}/status/200"
HTTP/1.1 200 OK
server: istio-envoy
...

Tenga en cuenta que utiliza el flag -H para establecer el encabezado HTTP Host en httpbin.example.com ya que ahora no tiene vinculación DNS para ese host y simplemente está enviando su solicitud a la IP de entrada.

También puede agregar la vinculación DNS en /etc/hosts y eliminar el flag -H:

$ echo "$HOST httpbin.example.com" >> /etc/hosts
$ curl -s -I "http://httpbin.example.com:${PORT}/status/200"
HTTP/1.1 200 OK
server: istio-envoy
...

Acceda a cualquier otra URL que no haya sido expuesta explícitamente. Debería ver un error HTTP 404:

$ curl -s -I -HHost:httpbin.example.com "http://${HOST}:${PORT}/headers"
HTTP/1.1 404 Not Found
...

Puede activar el nivel de registro de depuración para ver más registros relacionados con DLB:

$ istioctl pc log ${POD}.istio-system --level debug
istio-ingressgateway-665fdfbf95-2j8px.istio-system:
active loggers:
  admin: debug
  alternate_protocols_cache: debug
  aws: debug
  assert: debug
  backtrace: debug
...

Ejecute curl para enviar una solicitud y verá algo como lo siguiente:

$ kubectl logs -n istio-system ${POD} | grep dlb
2023-05-05T06:16:36.921299Z     warning envoy config external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:46        dlb device 0 is not found, use dlb device 3 instead     thread=35
2023-05-05T06:37:45.974241Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:269   worker_3 dlb send fd 45 thread=47
2023-05-05T06:37:45.974427Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:286   worker_0 get dlb event 1        thread=46
2023-05-05T06:37:45.974453Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:303   worker_0 dlb recv 45    thread=46
2023-05-05T06:37:45.975215Z     debug   envoy connection external/envoy/contrib/network/connection_balance/dlb/source/connection_balancer_impl.cc:283   worker_0 dlb receive none, skip thread=46

Para más detalles sobre Istio Ingress Gateway, consulte la Documentación oficial de Istio Ingress Gateway.

Share this post