Crie um balanceador de carga externo de protocolo misto

Este documento mostra como expor uma aplicação em execução num cluster do Google Kubernetes Engine (GKE) à Internet através de um serviço LoadBalancer externo de protocolo misto para tráfego TCP e UDP.

Para saber mais sobre os balanceadores de carga de rede de encaminhamento externo, consulte o artigo Balanceador de carga de rede de encaminhamento externo baseado em serviço de back-end.

Vista geral

Pode expor aplicações que usam protocolos TCP e UDP através de dois serviços LoadBalancer do GKE separados com um endereço IP partilhado coordenado manualmente. No entanto, esta abordagem é ineficiente porque requer a gestão de vários serviços para uma única aplicação e pode originar problemas, como erros de configuração ou quotas de endereços IP esgotadas.

Os serviços LoadBalancer de protocolo misto permitem-lhe usar um único serviço para gerir o tráfego para TCP e UDP. A utilização de um único serviço simplifica a sua configuração, permitindo-lhe usar um único endereço IPv4 e um conjunto consolidado de regras de encaminhamento para ambos os protocolos. Esta funcionalidade é suportada para o Network Load Balancer de transferência externa.

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize-a. Se instalou anteriormente a CLI gcloud, execute o comando gcloud components update para obter a versão mais recente. As versões anteriores da CLI gcloud podem não suportar a execução dos comandos neste documento.
  • Certifique-se de que tem um cluster do Autopilot ou Standard existente. Para criar um novo cluster, consulte o artigo Crie um cluster do Autopilot.

Requisitos

Para criar um serviço LoadBalancer externo que use protocolos mistos, o cluster tem de cumprir os seguintes requisitos:

  • O equilíbrio de carga de protocolo misto só está disponível em clusters recém-criados na versão 1.34.1-gke.2190000 ou posterior.
  • Tem de ter o suplemento HttpLoadBalancing ativado no cluster.
  • Para novos serviços LoadBalancer externos, para implementar o balanceador de carga, defina o campo spec.loadBalancerClass como networking.gke.io/l4-regional-external no manifesto do serviço. Para os serviços existentes, o seu manifesto já tem a anotação cloud.google.com/l4-rbs: "enabled" e pode deixá-la como está.

Limitações

  • Os equilibradores de carga de protocolo misto suportam apenas endereços IPv4.
  • Não pode usar protocolos mistos num manifesto de serviço com os seguintes finalizadores:

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

    Se o manifesto tiver estes finalizadores, tem de eliminar e recriar o serviço de acordo com os requisitos anteriores.

Preços

Google Cloud cobra-lhe por regra de encaminhamento, por todos os endereços IP externos e pelos dados enviados. A tabela seguinte descreve o número de regras de encaminhamento e endereços IP externos usados para configurações especificadas. Para mais informações, consulte os preços da rede VPC.

Tipo Camada de transporte Camada de Internet Número de regras de encaminhamento Número de endereços IP externos
Externo Único (TCP ou UDP) IPv4 1 1
IPv6 1 1
IPv4 e IPv6(DualStack) 2 2
Misto (TCP e UDP) IPv4 2 1

Implemente uma carga de trabalho

Esta secção mostra como implementar uma carga de trabalho de exemplo que deteta portas TCP e UDP. Tenha em atenção que a configuração de implementação é a mesma, quer esteja a usar um serviço LoadBalancer de protocolo misto ou dois serviços LoadBalancer de protocolo único separados.

  1. O manifesto seguinte destina-se a uma aplicação de exemplo que escuta na porta 8080 para tráfego TCP e UDP. Guarde o seguinte manifesto 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. Aplique o manifesto ao cluster:

    kubectl apply -f mixed-app-deployment.yaml
    

Crie um balanceador de carga de protocolo misto

Crie um serviço do tipo LoadBalancer que exponha a implementação ao tráfego TCP e UDP.

  1. Guarde o seguinte manifesto 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
    

    O serviço anterior tem duas portas, uma para TCP e outra para UDP, ambas na porta 8080.

  2. Aplique o manifesto ao cluster:

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

Valide o equilibrador de carga de protocolo misto

Depois de criar o serviço, verifique se o GKE criou o balanceador de carga com êxito.

  1. Inspeção do serviço:

    kubectl describe service mixed-protocol-lb
    

    O resultado mostra o endereço IP externo do balanceador de carga e as regras de encaminhamento para TCP e UDP. Valide os seguintes detalhes no resultado:

    • O campo status.loadBalancer.ingress.ip está preenchido.
    • Verifique se as seguintes anotações para o balanceador de carga externo estão presentes:
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • A secção Events não contém mensagens de erro.

Atualize o balanceador de carga de protocolo misto

Pode atualizar as portas num equilibrador de carga de protocolo misto editando o manifesto do serviço. Para editar o serviço, execute o seguinte comando:

kubectl edit service SERVICE_NAME

Substitua SERVICE_NAME pelo nome do seu serviço.

Atualize as portas

Para atualizar as portas num equilibrador de carga de protocolo misto, modifique a secção ports do manifesto do serviço. Pode adicionar, remover ou modificar portas.

O exemplo seguinte adiciona uma porta UDP para streaming e uma porta TCP para metadados do servidor de jogos:

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

Atualize um balanceador de carga de protocolo único para protocolo misto

Para alterar um balanceador de carga de protocolo único para um balanceador de carga de protocolo misto, edite o serviço para incluir portas para os protocolos TCP e UDP.

O exemplo seguinte adiciona uma porta UDP para DNS a um balanceador de carga apenas TCP existente:

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

Atualize um balanceador de carga de protocolo misto para protocolo único

Para alterar um balanceador de carga de protocolo misto para um balanceador de carga de protocolo único, remova todas as portas de um dos protocolos.

O exemplo seguinte remove a porta UDP para DNS, o que converte o balanceador de carga apenas 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

Elimine o LoadBalancer de protocolo misto

Para eliminar o serviço LoadBalancer externo mixed-protocol-lb, execute o seguinte comando:

kubectl delete service mixed-protocol-lb

O GKE remove automaticamente todos os recursos do equilibrador de carga criados para o serviço.

Resolução de problemas

Esta secção descreve como resolver problemas comuns com serviços LoadBalancer de protocolo misto.

Verifique se existem eventos de erros

O primeiro passo na resolução de problemas é verificar os eventos associados ao seu serviço.

  1. Obtenha os detalhes do seu serviço:

    kubectl describe service mixed-protocol-lb
    
  2. Reveja a secção Events no final do resultado para ver se existem mensagens de erro.

Erro: o protocolo misto não é suportado para o LoadBalancer

Se criou o serviço com a anotação cloud.google.com/l4-rbs: "enabled", pode ver um evento de aviso do controlador de serviço original depois de criar o balanceador de carga de protocolo misto: mixed-protocol is not supported for LoadBalancer.

Pode ignorar esta mensagem com segurança, porque o novo controlador, que suporta protocolos mistos, aprovisiona corretamente o equilibrador de carga.

A definição de porta está em falta após uma atualização

Sintoma:

Quando atualiza um serviço que usa a mesma porta para TCP e UDP (por exemplo, a porta 8080), uma das definições de porta está em falta no serviço atualizado.

Causa:

Este é um problema conhecido no Kubernetes. Quando atualiza um serviço com vários protocolos na mesma porta, o cálculo da correção do lado do cliente pode unir incorretamente a lista de portas, o que faz com que uma das definições de portas seja removida. Este problema afeta os clientes que usam patches do lado do cliente, como kubectl apply e o cliente Go com patches de união.

Solução:

A solução para contornar este problema depende do seu cliente.

  • Para o kubectl: use a flag --server-side com kubectl apply:

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

    Substitua YOUR_SERVICE_MANIFEST pelo nome do manifesto do serviço.

  • Para o go-client: não use patches de união. Em alternativa, use uma chamada de atualização para substituir o serviço. Isto requer um pedido HTTP PUT com a especificação completa do objeto Service.

O que se segue?