Configurar balanceamento de carga em pacote com o MetalLB

Nesta página, descrevemos como configurar o balanceamento de carga em pacote com o MetalLB para Google Distributed Cloud. Os balanceadores de carga do MetalLB são executados em um pool dedicado de nós de trabalho ou nos mesmos nós do plano de controle.

Consulte a Visão geral dos balanceadores de carga para exemplos de topologias de balanceamento de carga disponíveis no Google Distributed Cloud.

Requisitos

  • Todos os nós do balanceador de carga precisam estar na mesma sub-rede da camada 2.
  • Todos os VIPs precisam estar na sub-rede de nós do balanceador de carga e ser roteado por meio do gateway da sub-rede.
  • O gateway da sub-rede do balanceador de carga precisa ouvir mensagens ARP gratuitas e encaminhar pacotes ARP para os nós do balanceador de carga.

Campos de configuração

Edite a seção cluster.spec.loadBalancer do arquivo de configuração do cluster para configurar o balanceamento de carga agrupado. Para informações sobre arquivos de configuração de cluster e exemplos de configurações válidas, consulte uma das seguintes páginas:

loadBalancer.mode

Este valor precisa ser bundled para ativar o balanceamento de carga em pacote.

loadBalancer.ports.controlPlaneLBPort

Esse valor especifica a porta de destino a ser usada no tráfego enviado ao plano de controle do Kubernetes (os servidores da API Kubernetes).

loadBalancer.vips.controlPlaneVIP

Esse valor especifica o endereço IP de destino a ser usado para o tráfego enviado ao plano de controle do Kubernetes (os servidores da API Kubernetes). Esse endereço IP precisa estar na mesma sub-rede da camada 2 que os nós no cluster. Não liste esse endereço na seção address pools do arquivo de configuração.

loadBalancer.vips.ingressVIP

Esse valor especifica o endereço IP a ser usado para serviços atrás do balanceador de carga para o tráfego de entrada. Este campo não é permitido em arquivos de configuração do cluster de administrador. Esse endereço precisa ser listado na seção de pools de endereços da configuração.

loadBalancer.addressPools

Esta seção da configuração contém um ou mais pools de endereços. Cada pool de endereços especifica uma lista de intervalos de endereços IP. Quando você cria um Serviço do tipo LoadBalancer, os endereços IP externos do Serviço são escolhidos nesses intervalos.

Os pools de endereços são especificados no formato a seguir:

- name: POOL_NAME
  avoidBuggyIPs: BOOLEAN
  manualAssign: BOOLEAN
  addresses:
  - IP_RANGE
  - IP_RANGE2
  • name: o nome do pool de endereços,pool-name , para seus fins organizacionais. Este campo não pode ser modificado.
  • avoidBuggyIPs: (opcional) true ou false. Se true, o pool omitirá endereços IP terminados em .0 e .255. Alguns hardwares de rede descartam tráfego para esses endereços especiais. É possível omitir esse campo. O valor padrão dele é false. Este campo pode ser modificado.
  • manualAssign: (opcional) true ou false. Se true, os endereços neste pool não serão atribuídos automaticamente aos serviços do Kubernetes. Se true, um endereço IP nesse pool só será usado quando for especificado explicitamente por um serviço. É possível omitir esse campo. O valor padrão dele é false. Este campo pode ser modificado.
  • addresses: uma lista de um ou mais intervalos de endereços IP não sobrepostos. ip-range pode ser especificado na notação CIDR (como 198.51.100.0/24) ou na notação de intervalo (como 198.51.100.0-198.51.100.10, sem espaços ao redor do travessão). Este campo não pode ser modificado.

Os intervalos de endereços IP na lista addresses não podem se sobrepor e precisam estar na mesma sub-rede que os nós que executam balanceadores de carga.

loadBalancer.nodePoolSpec

Nesta seção da configuração, é especificada uma lista de nós em que os balanceadores de carga serão executados. Os nós do balanceador de carga podem executar cargas de trabalho regulares por padrão. não há taints especiais nesses nós. Embora os nós no pool de nós do balanceador de carga podem executar cargas de trabalho, elas são separadas dos nós nos pools de nós de trabalho. Você não pode incluir um determinado nó de cluster em mais de um pool de nós. Nó sobreposto Endereços IP entre pools de nós bloqueiam a criação de clusters e outros clusters operações.

Se você quiser impedir que cargas de trabalho sejam executadas em um nó no balanceador de carga pool de nós, adicione o seguinte taint ao nó:

node-role.kubernetes.io/load-balancer:NoSchedule

O Google Distributed Cloud adiciona tolerâncias desse taint aos pods necessários para balanceamento de carga.

O exemplo a seguir mostra um pool de nós de balanceamento de carga com dois nós. O primeiro nó tem um endereço IP padrão nodePoolSpec.nodes.address ("1.2.3.4") e um endereço IP do Kubernetes nodePoolSpec.nodes.k8sIP (10.0.0.32). Quando você especifica o endereço k8sIP opcional para um nó, ele é dedicado ao processamento de tráfego de dados para o nó, como solicitações e respostas para a API Kubernetes, o kubelet e as cargas de trabalho. Nesse caso, o endereço IP padrão nodePoolSpec.nodes.address é usado para conexões SSH com o nó para operações administrativas do cluster. Se você não especificar um endereço k8sIP, o endereço IP padrão do nó processará todo o tráfego dele.

nodePoolSpec:
  nodes:
  - address: 1.2.3.4
    k8sIP: 10.0.0.32
  - address: 10.0.0.33

Por padrão, todos os nós no pool de nós do balanceador de carga precisam estar na mesma sub-rede de camada 2 que os VIPs do balanceador de carga configurados na seção loadBalancer.addressPools do arquivo de configuração. No entanto, se você especificar um endereço IP k8sIP do Kubernetes para um nó, somente esse endereço precisará estar na mesma sub-rede de camada 2 que os outros VIPs do balanceador de carga.

Se nodePoolSpec não estiver definido, os balanceadores de carga em pacote serão executados no sistema nós do plano de controle. Recomendamos executar balanceadores de carga em pools de nós separados, se possível.

Balanceamento de carga do plano de controle

O balanceador de carga desse plano de controle disponibiliza o endereço IP virtual (VIP, na sigla em inglês) do plano de controle. O Google Distributed Cloud executa o Keepa Pesquisa e o GCE como pods estáticos do Kubernetes na os nós do balanceador de carga para anunciar o VIP do plano de controle. O Keepalived usa o protocolo de redundância de roteador virtual (VRRP) nos nós do balanceador de carga para alta disponibilidade.

Balanceamento de carga do plano de dados

O balanceador de carga do plano de dados é para todos os Serviços do Kubernetes do tipo LoadBalancer. O Google Distributed Cloud usa MetalLB em execução no modo de Camada 2 para balanceamento de carga do plano de dados. Balanceamento de carga do plano de dados só pode ser configurado usando o Google Distributed Cloud, não modifique o MetalLB ConfigMap diretamente. É possível usar todos os recursos do MetalLB, incluindo compartilhamento de endereço IP entre os serviços. Consulte a documentação do MetalLB para obter informações sobre os recursos.

O MetalLB executa um pod de alto-falante em cada nó usando um daemonset, usando memberlist para alta disponibilidade. Há um nó de balanceador de carga dedicado do MetalLB para cada serviço do Kubernetes, em vez de um para todo o cluster. Dessa forma, o tráfego será distribuído entre nós do balanceador de carga se houver vários serviços.

Os balanceadores de carga do plano de dados podem ser executados nos nós do plano de controle ou em um subconjunto de nós de trabalho. A divisão de balanceadores de carga do plano de dados nos nós do plano de controle aumenta a utilização dos nós do plano de controle. Além disso, a divisão nos nós do plano de controle também aumenta o risco de sobrecarregá-lo e aumenta o perfil de risco de informações confidenciais no plano de controle, como as chaves SSH.

Separação do balanceador de carga

Antes da versão 1.32, quando você configurava o balanceamento de carga da camada 2 com o MetalLB, os balanceadores de carga do plano de controle e do plano de dados eram executados nos mesmos nós. Dependendo da configuração, todos os balanceadores de carga são executados nos nós do plano de controle ou no pool de nós do balanceador de carga.

O diagrama a seguir mostra a configuração padrão do balanceador de carga em pacote com balanceadores de carga do plano de controle e do plano de dados em execução nos nós do plano de controle ou ambos em execução no pool de nós do balanceador de carga:

Configuração padrão do balanceador de carga

Com os clusters da versão 1.32, é possível configurar os balanceadores de carga do plano de controle para serem executados nos nós do plano de controle e os balanceadores de carga do plano de dados para serem executados no pool de nós de balanceadores de carga. É possível especificar essa separação de balanceadores de carga ao criar um novo cluster da versão 1.32 ou atualizar um cluster da versão 1.32 para migrar os balanceadores de carga do plano de dados dos nós do plano de controle para o pool de nós do balanceador de carga.

A configuração do cluster para balanceadores de carga separados deve ser semelhante a este exemplo:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: hybrid-ha-lb
  namespace: cluster-hybrid-ha-lb
spec:
  type: hybrid
  profile: default
  anthosBareMetalVersion: 1.32
  gkeConnect:
    projectID: project-fleet
  controlPlane:
    loadBalancer:
      mode: bundled
    nodePoolSpec:
      nodes:
      - address: 10.200.0.2
      - address: 10.200.0.3
      - address: 10.200.0.4
  clusterNetwork:
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...
  loadBalancer:
    mode: bundled
    ...
    nodePoolSpec:
      nodes:
      - address: 10.200.0.5
      - address: 10.200.0.6
      - address: 10.200.0.7
  clusterOperations:
  ...

Separar balanceadores de carga ao criar um cluster

Se você estiver criando um novo cluster da versão 1.32 ou mais recente, será possível configurar os balanceadores de carga para executar os balanceadores de carga do plano de controle nos nós do plano de controle e os balanceadores de carga do plano de dados no pool de nós do balanceador de carga.

O diagrama a seguir mostra os balanceadores de carga do plano de controle e do plano de dados separados em diferentes nós:

Balanceadores de carga separados do plano de controle e do plano de dados

Para separar os balanceadores de carga ao criar um cluster, siga estas etapas:

  1. No arquivo de configuração do cluster, especifique um pool de nós do balanceador de carga com loadBalancer.nodePoolSpec, conforme descrito na seção loadBalancer.nodePoolSpec deste documento.

  2. Adicione controlPlane.loadBalancer.mode ao arquivo de configuração do cluster e defina o valor mode como bundled.

  3. Conclua a configuração do cluster e execute bmctl create cluster para criá-lo.

Migrar balanceadores de carga do plano de dados para fora do plano de controle

Se você tiver um cluster da versão 1.32 ou mais recente em que nem controlPlane.loadBalancer.mode nem loadBalancer.nodePoolSpec estejam definidos, o balanceador de carga do plano de controle e o balanceador de carga do plano de dados serão executados no pool de nós do plano de controle. É possível atualizar o cluster para migrar o balanceador de carga do plano de dados para um pool de nós do balanceador de carga.

O diagrama a seguir mostra os balanceadores de carga do plano de controle e do plano de dados separados depois que o balanceador de carga do plano de dados foi migrado dos nós do plano de controle:

O balanceador de carga do plano de dados foi migrado para o pool de nós do balanceador de carga.

Para migrar o balanceador de carga do plano de dados para um pool de nós do balanceador de carga ao atualizar um cluster, siga estas etapas:

  1. No arquivo de configuração do cluster, especifique um pool de nós do balanceador de carga com loadBalancer.nodePoolSpec, conforme descrito na seção loadBalancer.nodePoolSpec deste documento.

  2. Adicione controlPlane.loadBalancer.mode ao arquivo de configuração do cluster e defina o valor mode como bundled.

  3. Atualize o cluster executando o seguinte comando:

    bmctl update cluster -c CLUSTER_NAME --kubeconfig=ADMIN_KUBECONFIG
    

    Substitua:

    • CLUSTER_NAME: o nome do cluster que você está atualizando.

    • ADMIN_KUBECONFIG: o caminho do arquivo kubeconfig do cluster de administrador.

Como preservar o endereço IP da origem do cliente

O serviço LoadBalancer criado com a solução de balanceamento de carga em lote de camada 2 usa a configuração Cluster padrão para a política de tráfego externo. Essa configuração, spec.externalTrafficPolicy: Cluster, direciona o tráfego externo para os endpoints de todo o cluster, mas também oculta o endereço IP da origem do cliente.

O Google Distributed Cloud oferece suporte a dois métodos para preservar o endereço IP de origem do cliente:

  • Defina o modo de encaminhamento do balanceamento de carga como retorno direto do servidor (DSR). Para mais informações sobre o modo de encaminhamento do DSR, incluindo instruções para ativar, consulte Configurar o modo de encaminhamento do balanceamento de carga.

  • Defina a política de tráfego externa como local para o serviço LoadBalancer e configure os serviços e Entrada relacionados de acordo. As seções a seguir descrevem como configurar o cluster para usar esse método.

Serviços de LoadBalancer

Ao usar externalTrafficPolicy: Local nos serviços LoadBalancer, defina os pods do aplicativo para serem executados exatamente nos nós do balanceador de carga. Adicione o nodeSelector a seguir aos pods do aplicativo para fazer a mudança:

apiVersion: v1
kind: Pod
...
spec:
  nodeSelector:
      baremetal.cluster.gke.io/lbnode: "true"
...

Serviços de NodePort

O Kubernetes faz a conversão de endereços de rede (SNAT) de origem para os serviços NodePort. Para manter os endereços IP de origem do cliente, defina service.spec.externalTrafficPolicy como Local. O Kubernetes não executará mais a SNAT, mas você precisa garantir que haja pods em execução exatamente no IP do nó escolhido.

Entrada

Se os aplicativos forem serviços HTTP, é possível conseguir a visibilidade IP do cliente configurando componentes de entrada:

  1. Abra o serviço istio-ingress para edição:

    kubectl edit service -n gke-system istio-ingress
    
  2. Adicione externalTrafficPolicy: Local a spec, salve e saia do editor.

    apiVersion: v1
    kind: Service
    ...
    spec:
    ...
      externalTrafficPolicy: Local
    
  3. Abra a implantação istio-ingress para edição:

    kubectl edit deployment -n gke-system istio-ingress
    
  4. Adicione o nodeSelector a seguir à implantação, salve e saia do editor.

    apiVersion: apps/v1
    kind: Deployment
    ...
    spec:
      ...
      template:
        ...
        spec:
          ...
          nodeSelector:
              baremetal.cluster.gke.io/lbnode: "true"
    ...
    

Agora, todos os seus serviços por trás do Ingress veem um cabeçalho X-Forwarded-For com o IP do cliente, como o exemplo a seguir:

X-Forwarded-For: 21.0.104.4