Use o MetalLB em modo Layer 2 para dar IPs públicos do seu bloco /28 a Services LoadBalancer no k3s, com IP fixo por serviço e failover entre nós.

Para que serve

Em nuvem pública, um Service do tipo LoadBalancer ganha um IP externo automaticamente. Em servidor dedicado não existe esse serviço, e o Service fica eternamente em <pending>. O MetalLB resolve isso: ele entrega aos Services os IPs públicos do seu bloco /28 e responde ARP por eles no nó escolhido, como se o IP estivesse configurado ali. Assim você pode ter, por exemplo, um IP para o Ingress (sites), outro para um servidor de jogos e outro para um banco exposto só a parceiros.

Pré-requisitos

  • Cluster k3s com nós em VMs no Proxmox ligadas em modo bridge à vmbr0 (veja Configurar a rede do Proxmox para as VMs). Cada VM precisa estar no mesmo segmento do gateway do bloco.
  • IPs livres do bloco reservados para o MetalLB. Nos exemplos: bloco 203.0.113.0/28, gateway .1, Proxmox .2, VMs do cluster .3 a .5 e IPs para o MetalLB de .10 a .13. Troque pelos seus.
  • Acesso ao console IPMI/iLO, caso um conflito de IP derrube o acesso a alguma VM.
Atenção: nunca coloque no pool do MetalLB um IP que já esteja em uso (o do Proxmox, o de uma VM ou o gateway). Duas máquinas respondendo ARP pelo mesmo IP causam queda intermitente difícil de diagnosticar. Mantenha uma planilha com a destinação de cada um dos 13 IPs. Se perder o acesso ao Proxmox, entre pelo console IPMI/iLO e remova o pool com kubectl -n metallb-system delete ipaddresspool --all a partir de um nó do cluster.

Como o modo Layer 2 funciona

Para cada IP, o MetalLB elege um nó "líder" que passa a responder ARP com o seu MAC. O roteador do datacenter entrega o tráfego àquele nó, e o kube-proxy encaminha aos pods. Se o nó cair, outro assume em poucos segundos e anuncia a mudança com ARP gratuito. Consequências práticas:

  • Não é balanceamento entre nós: todo o tráfego de um IP entra por um nó só (limite de 1 Gbps do uplink, de qualquer forma).
  • O failover depende de o equipamento vizinho atualizar a tabela ARP. Teste antes de depender disso.

Etapa 1: desativar o ServiceLB do k3s

O k3s traz o ServiceLB (Klipper), que usa os IPs dos próprios nós e conflita com o MetalLB. Em todos os servidores, edite /etc/rancher/k3s/config.yaml:

disable:
  - servicelb

Depois, um servidor por vez: systemctl restart k3s. O Service do Traefik ficará em <pending> até o MetalLB estar pronto; os sites ficam fora do ar nesse intervalo, então faça em janela de manutenção.

Etapa 2: instalar o MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml
kubectl -n metallb-system wait --for=condition=ready pod --all --timeout=180s

Ou, pelo Helm: helm repo add metallb https://metallb.github.io/metallb e helm install metallb metallb/metallb -n metallb-system --create-namespace. Confira a versão atual na documentação. O k3s usa kube-proxy em modo iptables, então o ajuste strictARP (necessário só no modo IPVS) não se aplica.

Etapa 3: criar o pool com os IPs do bloco

Salve como metallb-pool.yaml:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: publicos
  namespace: metallb-system
spec:
  addresses:
    - 203.0.113.10-203.0.113.13
  autoAssign: false
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: publicos-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - publicos
  interfaces:
    - ens18

Com autoAssign: false, nenhum Service pega um IP público por acidente: é preciso pedir explicitamente. O campo interfaces limita os anúncios à placa ligada na vmbr0 (confira o nome com ip -br addr), evitando ARP pela rede privada do cluster. Aplique com kubectl apply -f metallb-pool.yaml.

Etapa 4: dar um IP fixo ao Traefik e a outros serviços

Para o Traefik do k3s, crie (ou complemente) o HelmChartConfig em /var/lib/rancher/k3s/server/manifests/traefik-config.yaml:

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    service:
      annotations:
        metallb.io/loadBalancerIPs: 203.0.113.10
    # mantenha aqui também outras opções que você já usa, como additionalArguments

Para um serviço qualquer, use a mesma anotação:

apiVersion: v1
kind: Service
metadata:
  name: jogo
  annotations:
    metallb.io/loadBalancerIPs: 203.0.113.11
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: jogo
  ports:
    - name: game
      port: 27015
      protocol: UDP

O externalTrafficPolicy: Local preserva o IP real do cliente (importante para logs, bloqueios e jogos), mas só entrega tráfego aos pods que estão no nó líder; o MetalLB escolhe como líder um nó que tenha pod do serviço.

Como saber se funcionou

kubectl get svc -A | grep LoadBalancer
kubectl -n metallb-system logs -l component=speaker --tail=50
# de fora do servidor (seu computador):
ping -c3 203.0.113.10
curl -I http://203.0.113.10

A coluna EXTERNAL-IP deve mostrar o IP pedido. Para testar o failover, desligue a VM líder (os logs do speaker mostram quem anuncia cada IP) e veja quanto tempo o IP leva para voltar a responder.

Problemas comuns

Service continua em pending

Veja kubectl describe svc NOME. Causas: pool com autoAssign: false e Service sem anotação, IP pedido fora do pool, IP já usado por outro Service ou ServiceLB do k3s ainda ativo.

IP aparece no Service mas não responde de fora

Confira se a interface do L2Advertisement está certa e se o firewall da VM ou do Proxmox permite o tráfego. Se a rede do Proxmox estiver em modo roteado em vez de bridge, o roteador do datacenter não enxerga o ARP das VMs; nesse caso o host precisa rotear cada IP do MetalLB para a VM, e a solução fica bem mais trabalhosa.

Failover demora minutos

O equipamento vizinho está ignorando o ARP gratuito e esperando o cache expirar. Registre o horário do teste e abra um ticket para avaliarmos.

Perguntas frequentes

Posso usar o modo BGP?

O BGP exige uma sessão com o roteador do datacenter, que não faz parte da entrega padrão. Para servidores dedicados, use o modo Layer 2.

Funciona com IPv6?

Sim. O MetalLB responde NDP para endereços IPv6; inclua uma faixa do seu /56 no pool e configure o cluster em pilha dupla (dual-stack).

Preciso de MetalLB com um nó só?

Não necessariamente. O ServiceLB do k3s já publica os serviços no IP do nó. O MetalLB vale a pena quando você quer IPs diferentes por serviço ou failover entre nós.

Leitura complementar

Precisa de ajuda?

Se precisar confirmar quais IPs do bloco estão livres ou suspeitar de conflito de IP, abra um ticket com a lista de IPs em uso e a saída de kubectl get svc -A.

Esta resposta lhe foi útil? 0 Usuários acharam útil (0 Votos)

Leia também