Criar um balanceador de carga externo de protocolo misto

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

Para saber mais sobre balanceadores de carga de rede de passagem externa, consulte Balanceador de carga de rede de passagem externa baseado em serviço de back-end.

Visão geral

É possível expor aplicativos que usam protocolos TCP e UDP usando dois serviços LoadBalancer do GKE separados com um endereço IP compartilhado coordenado manualmente. No entanto, essa abordagem é ineficiente porque exige o gerenciamento de vários serviços para um único aplicativo e pode causar problemas como erros de configuração ou cotas de endereço IP esgotadas.

Os serviços LoadBalancer de protocolo misto permitem usar um único serviço para gerenciar o tráfego de TCP e UDP. Usar um único serviço simplifica sua configuração, permitindo que você use um único endereço IPv4 e um conjunto consolidado de regras de encaminhamento para os dois protocolos. Esse recurso é compatível com o balanceador de carga de rede de passagem externa.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e inicialize a gcloud CLI. Se você instalou a gcloud CLI anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da gcloud CLI não sejam compatíveis com a execução dos comandos neste documento.

Requisitos

Para criar um serviço LoadBalancer externo que use protocolos mistos, seu cluster precisa atender aos seguintes requisitos:

  • O balanceamento de carga de protocolo misto está disponível apenas em clusters recém-criados na versão 1.34.1-gke.2190000 ou mais recente.
  • Você precisa ter o complemento HttpLoadBalancing ativado no cluster.
  • Para novos serviços LoadBalancer externos, defina o campo spec.loadBalancerClass como networking.gke.io/l4-regional-external no manifesto do serviço para implementar o balanceador de carga. Para serviços atuais, o manifesto já tem a anotação cloud.google.com/l4-rbs: "enabled", e você pode deixá-la como está.

Limitações

  • Os balanceadores de carga de protocolo misto são compatíveis apenas com endereços IPv4.
  • Não é possível usar protocolos mistos em um manifesto de serviço com os seguintes finalizadores:

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

    Se o manifesto tiver esses finalizadores, exclua e recrie o serviço de acordo com os requisitos anteriores.

Preços

Google Cloud cobra por regra de encaminhamento, por endereços IP externo e por dados enviados. A tabela a seguir descreve o número de regras de encaminhamento e endereços IP externo usados para configurações específicas. Para mais informações, consulte Preços de 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

Implantar uma carga de trabalho

Nesta seção, mostramos como implantar uma carga de trabalho de amostra que escuta nas portas TCP e UDP. A configuração de implantação é a mesma, seja usando um serviço LoadBalancer de protocolo misto ou dois serviços LoadBalancer de protocolo único separados.

  1. O manifesto a seguir é para um aplicativo de exemplo que detecta atividade na porta 8080 para tráfego TCP e UDP. Salve 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
    

Criar um balanceador de carga de protocolo misto

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

  1. Salve 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
    

Verificar o balanceador de carga de protocolo misto

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

  1. Inspecionar o serviço:

    kubectl describe service mixed-protocol-lb
    

    A saída mostra o endereço IP externo do balanceador de carga e as regras de encaminhamento para TCP e UDP. Verifique os seguintes detalhes na saída:

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

Atualizar o balanceador de carga de protocolo misto

É possível atualizar as portas em um balanceador 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.

Atualizar portas

Para atualizar as portas em um balanceador de carga de protocolo misto, modifique a seção ports do manifesto do serviço. É possível adicionar, remover ou modificar portas.

O exemplo a seguir 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

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

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

O exemplo a seguir adiciona uma porta UDP para DNS a um balanceador de carga somente 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

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

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

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

Excluir o LoadBalancer de protocolo misto

Para excluir o serviço LoadBalancer externo mixed-protocol-lb, execute o comando a seguir:

kubectl delete service mixed-protocol-lb

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

Solução de problemas

Nesta seção, descrevemos como resolver problemas comuns com serviços LoadBalancer de protocolo misto.

Verificar se há eventos de erro

A primeira etapa da solução de problemas é verificar os eventos associados ao seu serviço.

  1. Confira os detalhes do seu serviço:

    kubectl describe service mixed-protocol-lb
    
  2. Analise a seção Events no final da saída para conferir se há mensagens de erro.

Erro: o protocolo misto não é compatível com LoadBalancer

Se você criou o serviço com a anotação cloud.google.com/l4-rbs: "enabled", talvez veja 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.

Você pode ignorar essa mensagem porque o novo controlador, que oferece suporte a protocolos mistos, provisiona corretamente o balanceador de carga.

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

Sintoma:

Quando você atualiza um serviço que usa a mesma porta para TCP e UDP (por exemplo, a porta 8080), uma das definições de porta fica faltando no serviço atualizado.

Causa:

Esse é um problema conhecido no Kubernetes. Quando você atualiza um serviço com vários protocolos na mesma porta, o cálculo de patch do lado do cliente pode mesclar incorretamente a lista de portas, o que faz com que uma das definições de porta seja removida. Esse problema afeta clientes que usam patchs do lado do cliente, como kubectl apply e o cliente Go com patchs de mesclagem.

Solução:

A solução alternativa para esse problema depende do seu cliente.

  • Para 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 go-client: não use patches de mesclagem. Em vez disso, use uma chamada de atualização para substituir o serviço. Isso exige uma solicitação HTTP PUT com toda a especificação do objeto Service.

A seguir