Crea un balanceador de cargas externo de protocolo mixto

En este documento, se muestra cómo exponer a Internet una aplicación que se ejecuta en un clúster de Google Kubernetes Engine (GKE) con un Service LoadBalancer externo de protocolo mixto para el tráfico 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 externa basado en servicios de backend.

Descripción general

Puedes exponer aplicaciones que usan protocolos TCP y UDP con dos servicios 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 servicios para una sola aplicación y puede generar 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 administrar el tráfico de TCP y UDP. Usar un solo objeto Service simplifica tu 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 que se describen en este documento.

Requisitos

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

  • El balanceo de cargas de protocolo mixto solo está disponible en los clústeres creados recientemente en la versión 1.34.1-gke.2190000 o posterior.
  • Debes tener habilitado el complemento HttpLoadBalancing en tu clúster.
  • Para implementar el balanceador de cargas en los nuevos objetos Service LoadBalancer externos, configura el campo spec.loadBalancerClass en networking.gke.io/l4-regional-external en el manifiesto del Service. En el caso de los servicios existentes, tu manifiesto ya tiene la anotación cloud.google.com/l4-rbs: "enabled", por lo que puedes dejarla 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 servicio 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 las redes 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 (tanto TCP como 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 puertos TCP y UDP. Ten en cuenta que la configuración de Deployment es la misma, ya sea que uses un servicio LoadBalancer de protocolo mixto o dos servicios LoadBalancer de un solo protocolo separados.

  1. El siguiente manifiesto es para una aplicación de ejemplo que escucha en el puerto 8080 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 servicio, 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 se propaga.
    • 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 servicio. Para editar el Service, ejecuta el siguiente comando:

kubectl edit service SERVICE_NAME

Reemplaza SERVICE_NAME por el nombre de tu servicio.

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 un solo protocolo a uno de protocolo mixto

Para cambiar un balanceador de cargas de un solo protocolo a uno de protocolo mixto, edita el servicio 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 para 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 un solo protocolo

Para cambiar un balanceador de cargas de protocolo mixto a un balanceador de cargas de un solo protocolo, 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 objeto Service LoadBalancer externo de 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 servicios de LoadBalancer de protocolo mixto.

Verifica si hay eventos de error

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

  1. Obtén los detalles de tu servicio:

    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 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 cargas de protocolo mixto: mixed-protocol is not supported for LoadBalancer.

Puedes ignorar este mensaje sin problemas, ya que 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 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:

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 incorrectamente la lista de puertos, lo que provoca que se quite una de las definiciones de puertos. 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 servicio.

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

¿Qué sigue?