Crear un balanceador de carga externo de protocolo mixto

En este documento se explica cómo exponer a Internet una aplicación que se ejecuta en un clúster de Google Kubernetes Engine (GKE) mediante un servicio LoadBalancer externo de protocolo mixto para el tráfico TCP y UDP.

Para obtener más información sobre los balanceadores de carga de red de paso a través externos, consulta el artículo Balanceador de carga de red de paso a través externo basado en el servicio de backend.

Información general

Puedes exponer aplicaciones que usen los protocolos TCP y UDP mediante dos servicios LoadBalancer de GKE independientes con una dirección IP compartida y coordinada manualmente. Sin embargo, este enfoque es ineficiente porque requiere gestionar varios servicios para una sola aplicación y puede provocar problemas, como errores de configuración o cuotas de direcciones IP agotadas.

Los servicios LoadBalancer de protocolo mixto te permiten usar un solo servicio para gestionar el tráfico de TCP y UDP. Usar un solo servicio simplifica la configuración, ya que te permite usar una sola dirección IPv4 y un conjunto consolidado de reglas de reenvío para ambos protocolos. Esta función se admite en el balanceador de carga de red de paso a través externo.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la CLI de gcloud, obtén la versión más reciente ejecutando el comando gcloud components update. Es posible que las versiones anteriores de la interfaz de línea de comandos de gcloud no admitan la ejecución de los comandos de este documento.

Requisitos

Para crear un servicio LoadBalancer externo que use protocolos mixtos, tu clúster debe cumplir los siguientes requisitos:

  • El balanceo de carga de protocolo mixto solo está disponible en los clústeres creados recientemente con la versión 1.34.1-gke.2190000 o posterior.
  • Debes tener habilitado el complemento HttpLoadBalancing en tu clúster.
  • En el caso de los nuevos servicios LoadBalancer externos, para implementar el balanceador de carga, defina el campo spec.loadBalancerClass como networking.gke.io/l4-regional-external en el manifiesto del servicio. En el caso de los servicios que ya tengas, tu archivo de manifiesto ya tendrá la anotación cloud.google.com/l4-rbs: "enabled", por lo que puedes dejarla como está.

Limitaciones

  • Los balanceadores de carga de protocolo mixto solo admiten direcciones IPv4.
  • No puedes usar protocolos mixtos en un manifiesto de servicio con los siguientes finalizadores:

    • gke.networking.io/l4-ilb-v1
    • gke.networking.io/l4-netlb-v1

    Si tu manifiesto tiene estos finalizadores, debes eliminar y volver a crear el servicio de acuerdo con los requisitos anteriores.

Precios

Google Cloud te cobra por cada regla de reenvío, por las direcciones IP externas y por los datos enviados. En la siguiente tabla se describe el número de reglas de reenvío y direcciones IP externas que se usan en las configuraciones especificadas. Para obtener más información, consulta los precios de las redes VPC.

Tipo Capa de transporte Capa de Internet Número de reglas de reenvío Número de direcciones IP externas
Externo Único (TCP o UDP) IPv4 1 1
IPv6 1 1
IPv4 e IPv6(DualStack) 2 2
Mixto (TCP y UDP) IPv4 2 1

Desplegar una carga de trabajo

En esta sección se muestra cómo desplegar una carga de trabajo de ejemplo que escucha en los puertos TCP y UDP. Ten en cuenta que la configuración de Deployment es la misma tanto si usas un servicio LoadBalancer de protocolo mixto como si usas dos servicios LoadBalancer de un solo protocolo.

  1. El siguiente manifiesto es de una aplicación de ejemplo que escucha en el puerto 8080 el tráfico TCP y UDP. Guarda el siguiente archivo de manifiesto como mixed-app-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mixed-app-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: mixed-app
      template:
        metadata:
          labels:
            app: mixed-app
        spec:
          containers:
          - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6
            name: agnhost
            args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"]
            ports:
              - name: tcp8080
                protocol: TCP
                containerPort: 8080
              - name: udp8080
                protocol: UDP
                containerPort: 8080
    
  2. Aplica el manifiesto a tu clúster:

    kubectl apply -f mixed-app-deployment.yaml
    

Crear un balanceador de carga de protocolo mixto

Crea un servicio de tipo LoadBalancer que exponga el despliegue al tráfico TCP y UDP.

  1. Guarda el siguiente archivo de manifiesto como mixed-protocol-lb.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: mixed-protocol-lb
    spec:
      loadBalancerClass: "networking.gke.io/l4-regional-external"
      type: LoadBalancer
      selector:
        app: mixed-app
      ports:
      - name: tcp-port
        protocol: TCP
        port: 8080
      - name: udp-port
        protocol: UDP
        port: 8080
    

    El servicio anterior tiene dos puertos, uno para TCP y otro para UDP, ambos en el puerto 8080.

  2. Aplica el manifiesto a tu clúster:

    kubectl apply --server-side -f mixed-protocol-lb.yaml
    

Verificar el balanceador de carga de protocolo mixto

Una vez que hayas creado el servicio, comprueba que GKE haya creado el balanceador de carga correctamente.

  1. Inspecciona el servicio:

    kubectl describe service mixed-protocol-lb
    

    El resultado muestra la dirección IP externa del balanceador de carga y las reglas de reenvío de TCP y UDP. Verifica los siguientes detalles en el resultado:

    • El campo status.loadBalancer.ingress.ip se rellena.
    • Verifica que estén presentes las siguientes anotaciones en tu balanceador de carga externo:
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • La sección Events no contiene mensajes de error.

Actualizar el balanceador de carga de protocolo mixto

Para actualizar los puertos de un balanceador de carga de protocolo mixto, edita el manifiesto de Service. Para editar el servicio, ejecuta el siguiente comando:

kubectl edit service SERVICE_NAME

Sustituye SERVICE_NAME por el nombre de tu servicio.

Actualizar puertos

Para actualizar los puertos de un balanceador de carga de protocolo mixto, modifica la sección ports del manifiesto de servicio. Puedes añadir, quitar o modificar puertos.

En el siguiente ejemplo se añade un puerto UDP para la transmisión y un puerto TCP para los metadatos del servidor de juegos:

apiVersion: v1
kind: Service
metadata:
  name: mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: tcp-port
    protocol: TCP
    port: 8080
  - name: streaming
    protocol: UDP
    port: 10100
  - name: gameserver-metadata
    protocol: TCP
    port: 10400
  - name: https
    protocol: TCP
    port: 443

Actualizar un balanceador de carga de un solo protocolo a un protocolo mixto

Para cambiar un balanceador de carga de un solo protocolo a un balanceador de carga de protocolo mixto, edita el servicio para incluir puertos de los protocolos TCP y UDP.

En el siguiente ejemplo se añade un puerto UDP para DNS a un balanceador de carga que solo usa TCP:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-single-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443
  - name: dns
    protocol: UDP
    port: 53

Actualizar un balanceador de carga de protocolo mixto a un solo protocolo

Para cambiar un balanceador de carga de protocolo mixto a un balanceador de carga de un solo protocolo, elimina todos los puertos de uno de los protocolos.

En el siguiente ejemplo, se elimina el puerto UDP de DNS, lo que convierte el balanceador de carga en un balanceador solo para TCP:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443

Eliminar el LoadBalancer de protocolo mixto

Para eliminar el servicio mixed-protocol-lb LoadBalancer externo, ejecuta el siguiente comando:

kubectl delete service mixed-protocol-lb

GKE elimina automáticamente todos los recursos de balanceador de carga creados para el servicio.

Solución de problemas

En esta sección se describe cómo resolver problemas habituales con los servicios LoadBalancer de protocolo mixto.

Comprobar si hay eventos de error

El primer paso para solucionar problemas es comprobar los eventos asociados a tu servicio.

  1. Obtén los detalles de tu servicio:

    kubectl describe service mixed-protocol-lb
    
  2. Consulte la sección Events al final del resultado para ver si hay mensajes de error.

Error: Mixed Protocol is not supported for LoadBalancer (No se admite el protocolo mixto en LoadBalancer)

Si has creado el servicio con la anotación cloud.google.com/l4-rbs: "enabled", es posible que veas un evento de advertencia del controlador de servicio original después de crear el balanceador de carga de protocolo mixto: mixed-protocol is not supported for LoadBalancer.

Puedes ignorar este mensaje, ya que el nuevo controlador, que admite protocolos mixtos, aprovisiona correctamente el balanceador de carga.

Falta la definición de puerto después de una actualización

Síntoma:

Cuando actualizas un servicio que usa el mismo puerto para TCP y UDP (por ejemplo, el puerto 8080), falta una de las definiciones de puerto en el servicio actualizado.

Causa:

Se trata de un problema conocido de Kubernetes. Cuando actualiza un servicio con varios protocolos en el mismo puerto, el cálculo de parches del lado del cliente puede combinar incorrectamente la lista de puertos, lo que provoca que se elimine una de las definiciones de puerto. Este problema afecta a los clientes que usan parches del lado del cliente, como kubectl apply y el cliente de Go con parches de combinación.

Solución:

La solución alternativa para este problema depende de tu cliente.

  • Para kubectl: usa la marca --server-side con kubectl apply:

    kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yaml
    

    Sustituye YOUR_SERVICE_MANIFEST por el nombre de tu manifiesto de servicio.

  • Para go-client: no uses parches de combinación. En su lugar, usa una llamada de actualización para sustituir el servicio. Para ello, se necesita una solicitud HTTP PUT con la especificación completa del objeto Service.

Siguientes pasos