Crea un balanceador de cargas externo de protocolo mixto

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

Para obtener más información sobre los balanceadores de cargas de red de transferencia externos, consulta Balanceador de cargas de red de transferencia externo basado en servicios de backend.

Descripción general

Puedes exponer aplicaciones que usan protocolos TCP y UDP con dos Services LoadBalancer de GKE separados con una dirección IP compartida y coordinada de forma manual. Sin embargo, este enfoque es ineficiente porque requiere administrar varios Services para una sola aplicación y puede generar problemas, como errores de configuración o cuotas de direcciones IP agotadas.

Los Services LoadBalancer de protocolo mixto te permiten usar un solo Service para administrar el tráfico de TCP y UDP. El uso de un solo Service 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 es compatible con el balanceador de cargas de red de transferencia externo.

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 de este documento.

Requisitos

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

  • El balanceo de cargas de protocolo mixto está disponible en la versión 1.34.1-gke.2190000 o posterior.
  • Debes tener habilitado el complemento HttpLoadBalancing en tu clúster.
  • Para los Services LoadBalancer externos nuevos, para implementar el balanceador de cargas, establece el campo spec.loadBalancerClass en networking.gke.io/l4-regional-external en el manifiesto del Service. En el caso de los Services existentes, tu manifiesto ya tiene la anotación cloud.google.com/l4-rbs: "enabled", y puedes dejar la anotación tal como está.

Limitaciones

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

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

    Si tu manifiesto tiene estos finalizadores, debes borrar y volver a crear el Service según los requisitos anteriores.

Precios

Google Cloud te factura por regla de reenvío, por cualquier dirección IP externa y por los datos enviados. En la siguiente tabla, se describe la cantidad de reglas de reenvío y direcciones IP externas que se usan para las configuraciones especificadas. Para obtener más información, consulta Precios de la red de VPC.

Tipo Capa de transporte Capa de Internet Cantidad de reglas de reenvío Cantidad de direcciones IP externas
Externo Único (TCP o UDP) IPv4 1 1
IPv6 1 1
IPv4 e IPv6(pila doble) 2 2
Mixto (TCP y UDP) IPv4 2 1

Implementa una carga de trabajo

En esta sección, se muestra cómo implementar una carga de trabajo de muestra que escucha en los puertos TCP y UDP. Ten en cuenta que la configuración de Deployment es la misma, ya sea que uses un Service LoadBalancer de protocolo mixto o dos Services LoadBalancer de protocolo único separados.

  1. El siguiente manifiesto es para una aplicación de muestra que escucha en el puerto 8080 para el tráfico de TCP y UDP. Guarda el siguiente 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 al clúster:

    kubectl apply -f mixed-app-deployment.yaml
    

Crea un balanceador de cargas de protocolo mixto

Crea un Service de tipo LoadBalancer que exponga la implementación al tráfico de TCP y UDP.

  1. Guarda el siguiente 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 Service anterior tiene dos puertos, uno para TCP y otro para UDP, ambos en el puerto 8080.

  2. Aplica el manifiesto al clúster:

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

Verifica el balanceador de cargas de protocolo mixto

Después de crear el Service, verifica que GKE haya creado el balanceador de cargas correctamente.

  1. Inspecciona el servicio:

    kubectl describe service mixed-protocol-lb
    

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

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

Actualiza el balanceador de cargas de protocolo mixto

Puedes actualizar los puertos en un balanceador de cargas de protocolo mixto editando el manifiesto del Service. Para editar el Service, ejecuta el siguiente comando:

kubectl edit service SERVICE_NAME

Reemplaza SERVICE_NAME por el nombre de tu Service.

Actualiza los puertos

Para actualizar los puertos en un balanceador de cargas de protocolo mixto, modifica la sección ports del manifiesto del Service. Puedes agregar, quitar o modificar puertos.

En el siguiente ejemplo, se agrega 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

Actualiza un balanceador de cargas de protocolo único a protocolo mixto

Para cambiar un balanceador de cargas de protocolo único a un balanceador de cargas de protocolo mixto, edita el Service para incluir puertos para los protocolos TCP y UDP.

En el siguiente ejemplo, se agrega un puerto UDP para DNS a un balanceador de cargas existente solo de 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

Actualiza un balanceador de cargas de protocolo mixto a protocolo único

Para cambiar un balanceador de cargas de protocolo mixto a un balanceador de cargas de protocolo único, quita todos los puertos de uno de los protocolos.

En el siguiente ejemplo, se quita el puerto UDP para DNS, lo que convierte el balanceador de cargas en solo 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

Borra el LoadBalancer de protocolo mixto

Para borrar el Service LoadBalancer externo mixed-protocol-lb, ejecuta el siguiente comando:

kubectl delete service mixed-protocol-lb

GKE quita automáticamente todos los recursos del balanceador de cargas creados para el Service.

Soluciona problemas

En esta sección, se describe cómo resolver problemas comunes con los Services LoadBalancer de protocolo mixto.

Verifica si hay eventos de error

El primer paso para solucionar problemas es verificar los eventos asociados con tu Service.

  1. Obtén los detalles de tu Service:

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

Error: No se admite el protocolo mixto para LoadBalancer

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

Puedes ignorar este mensaje de forma segura porque el nuevo controlador, que admite protocolos mixtos, aprovisiona correctamente el balanceador de cargas.

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

Síntoma:

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

Causa:

Este es un problema conocido en Kubernetes. Cuando actualizas un Service con varios protocolos en el mismo puerto, el cálculo de parches del cliente puede combinar de forma incorrecta la lista de puertos, lo que provoca que se quite una de las definiciones de puerto. Este problema afecta a los clientes que usan parches 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
    

    Reemplaza YOUR_SERVICE_MANIFEST por el nombre de tu manifiesto de Service.

  • Para go-client: No uses parches de combinación. En su lugar, usa una llamada de actualización para reemplazar el Service. Esto requiere una solicitud HTTP PUT con la especificación completa del objeto Service.

¿Qué sigue?