Configurar o balanceamento de carga com base em verificações de integridade

Este documento mostra como implementar alta disponibilidade para endereços IP persistentes no Google Kubernetes Engine (GKE) usando o balanceamento de carga baseado em verificação de integridade. Embora as configurações de IP persistente padrão mapeiem um único endereço IP persistente para um único pod, o balanceamento de carga baseado em verificação de integridade permite distribuir o tráfego de um ou mais endereços IP persistentes em um pool de pods íntegros.

Para reivindicar endereços IP persistentes específicos e identificar quais pods recebem tráfego, crie um recurso personalizado GKEIPRoute. Ao integrar o recurso GKEIPRoute com verificações de integridade regionais, o GKE monitora suas cargas de trabalho na camada de rede e encaminha o tráfego apenas para pods que estão prontos para recebê-lo. Também é possível designar pods de backup opcionais usando o objeto GKEIPRoute. O GKE só roteia o tráfego para esses pods em espera se todos os pods ativos principais falharem na verificação de integridade.

Requisitos e limitações

  • Para usar o balanceamento de carga baseado em verificação de integridade, o cluster precisa estar na versão 1.32.3-gke.1440000 ou mais recente do GKE. O GKE permite selecionar pods de backup apenas na versão 1.35.0-gke.1403000 ou mais recente.
  • O cluster precisa ter o GKE Dataplane V2 e a API Gateway ativados.
  • Um único objeto GKEIPRoute oferece suporte a apenas um pod correspondente por nó. Se vários pods em um nó corresponderem ao seletor de pods do GKEIPRoute, o GKE escolherá o pod criado mais recentemente nesse nó.
  • Não é possível modificar uma classe Gateway depois de criar o objeto GKEIPRoute.
  • O balanceamento de carga baseado em verificação de integridade é compatível apenas com tráfego iniciado de fora da carga de trabalho. O tráfego iniciado na carga de trabalho para o endereço IP persistente não é compatível.

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.

Implementar o balanceamento de carga com base em verificações de integridade

Esta seção resume o fluxo de trabalho para implementar o balanceamento de carga com base em verificações de integridade:

  1. Crie uma verificação de integridade regional: defina os parâmetros que o GKE usa para monitorar o status dos seus pods. Esse objeto informa à camada de rede quais endpoints estão íntegros e qualificados para receber tráfego do endereço IP permanente.
  2. Criar um cluster: configure um cluster do GKE com o GKE Dataplane V2 e a API Gateway ativados. Esses componentes fornecem a infraestrutura subjacente necessária para gerenciar o roteamento IP persistente e o balanceamento de carga baseado em verificação de integridade.
  3. Reservar um endereço IP: selecione e reserve um endereço IP interno ou externo estático na mesma região do cluster. Esse endereço serve como o ponto de entrada persistente que o GKE distribui no seu pool de pods ativos ou de backup.
  4. Crie um gateway: configure um objeto de gateway para gerenciar seus endereços IP persistentes reservados. O objeto GKEIPRoute reivindica e usa endereços IP específicos do gateway para suas cargas de trabalho.
  5. Crie um objeto GKEIPRoute: defina as regras de roteamento que mapeiam seu endereço IP persistente para um grupo de pods usando seletores de rótulos. Nesse objeto, você faz referência à sua verificação de integridade regional e, opcionalmente, designa pods de backup para cenários de failover.
  6. Ver endpoints correspondentes: verifique se o GKE identificou corretamente seus pods ativos e de backup inspecionando os EndpointSlices gerados automaticamente. Essa etapa confirma se seus rótulos correspondem aos pods esperados e se a camada de rede está pronta para rotear o tráfego.

Etapa 1: criar uma verificação de integridade regional e regras de firewall

Para criar uma verificação de integridade regional, siga as etapas em Criar verificações de integridade. O nome fornecido aqui será usado na sua configuração do GKEIPRoute. Exemplo:

gcloud compute health-checks create http reg-lb-hc \
    --region=us-central1 \
    --check-interval=5s \
    --timeout=5s \
    --healthy-threshold=2 \
    --unhealthy-threshold=2

Para permitir que as sondagens de verificação de integridade do Google Cloud alcancem seus nós, também é necessário criar regras de firewall.

Etapa 2: criar um cluster do GKE

Crie um cluster com a API Gateway e o GKE Dataplane V2 ativados. Exemplo:

gcloud container clusters create cluster-1 \
    --enable-dataplane-v2 \
    --gateway-api=standard \
    --region=us-central1

Se você configurar o objeto GKEIPRoute em uma rede VPC diferente da rede VPC padrão do cluster, crie um cluster do GKE com recursos de várias redes. Para mais informações, consulte Configurar o suporte a várias redes para pods.

Etapa 3: reservar endereços IP

Reserve os endereços IP que você quer usar para suas cargas de trabalho. Você pode escolher entre reservar endereços IP fornecidos pelo Google ou usar seus próprios (BYOIP).

Etapa 3a: reservar endereços IP fornecidos pelo Google

Para reservar endereços IP externos, execute o seguinte comando:

gcloud compute addresses create ADDRESS_NAME \
   --region=REGION

Substitua:

  • ADDRESS_NAME: o nome que você quer associar a esse endereço.
  • REGION: a região em que você quer reservar o endereço. Ela precisa ser a mesma região do Pod ao qual o endereço IP será anexado.

    Observação: especifique uma região ao reservar um endereço IP porque as regras de encaminhamento, que lidam com o roteamento de tráfego para endereços IP persistentes, são regionais. Seu endereço IP e o cluster do GKE precisam estar na mesma região para que o roteamento funcione corretamente.

Para reservar endereços IP internos, execute o seguinte comando:

gcloud compute addresses create ADDRESS_NAME \
    --region REGION
    --subnet SUBNETWORK \
    --addresses IP_ADDRESS

Substitua:

  • ADDRESS_NAME: os nomes de um ou mais endereços que você quer reservar. No caso de vários endereços, especifique todos os endereços como uma lista separados por espaços. Por exemplo, example-address-1 example-address-2 example-address-3.
  • REGION: a região desta solicitação
  • SUBNETWORK: a sub-rede deste endereço IPv4 interno
  • IP_ADDRESS: um endereço IP interno não utilizado do intervalo de endereços IP principal da sub-rede selecionada.

Para garantir que o tráfego seja roteado corretamente dentro da rede privada, os endereços IP internos precisam pertencer à sub-rede padrão do cluster ou a uma sub-rede de rede adicional.

Para mais informações sobre endereços IP externos e internos ou para saber como reservar endereços usando o console do Google Cloud , consulte Reservar um endereço IP externo estático e Reservar um endereço IP interno estático.

Etapa 3b: usar seus próprios endereços IP (BYOIP)

Você pode trazer seus próprios endereços IP (BYOIP), em vez de depender dos endereços IP fornecidos pelo Google. O BYOIP é útil se você precisa de endereços IP específicos para seus aplicativos ou está migrando sistemas atuais para o Google Cloud. Para usar o método BYOIP, o Google valida que você é proprietário do intervalo de endereços IP e após a importação dos endereços para Google Cloud, é possível atribuí-los como endereços IP para pods do GKE. Para mais informações, consulte Trazer seus próprios endereços IP.

Etapa 4: criar objetos de gateway

Você cria um gateway usando uma das seguintes classes de gateway que oferecem suporte apenas ao tipo de rede L3:

  • gke-passthrough-lb-external-managed ou
  • gke-passthrough-lb-internal-managed.

O exemplo a seguir define um gateway que gerencia um pool de endereços IP externo:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: lb-gateway
spec:
  gatewayClassName: gke-passthrough-lb-external-managed

  listeners:
    - name: default
      port: 443
      protocol: none
      allowedRoutes:
        namespaces:
          from: All

  addresses:
    - value: "34.123.10.1/32"
      type: "gke.networking.io/cidr"
    - value: "34.123.10.2/32"
      type: "gke.networking.io/cidr"

No exemplo anterior, observe os seguintes campos:

  • endereços: lista todos os intervalos de endereços IP para os quais o gateway específico gerencia permissões.
  • listeners: identifica os namespaces dos quais os objetos GKEIPRoute podem fazer referência a esse gateway.

Para detalhes sobre o uso do listener, consulte Criar objetos de gateway.

Etapa 5: criar um objeto GKEIPRoute com configuração de balanceamento de carga e verificação de integridade

Crie um objeto GKEIPRoute em que você define os seletores de pod principal e de backup e associa a verificação de integridade criada na etapa 1.

kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
  namespace: default
  name: my-ip-route
spec:
  parentRefs:
  - name: lb-gateway
  addresses:
  - value: "34.123.10.1/32"
    type: "gke.networking.io/cidr"
  - value: "34.123.10.2/32"
    type: "gke.networking.io/cidr"
  network: default
  podSelector:
    matchLabels:
      component: activePodSelector

  loadBalancing:
    healthCheckName: "reg-lb-hc"
    backupPodSelector:
      namespaceSelector:
        matchLabels:
          environment: test
          dc: us-central
      podSelector:
        matchLabels:
          component: backupPodSelector
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: proxy-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: proxy
  template:
    metadata:
      # annotations:  <- Include these lines if the pods are multi-nic pods
      #   networking.gke.io/default-interface: 'eth0'
      #   networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
      labels:
        component: proxy
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

Observe o seguinte:

  • podSelector: identifica os pods ativos principais que recebem tráfego dos endereços IP persistentes definidos. Esse campo usa rótulos para corresponder a pods no mesmo namespace que o recurso GKEIPRoute. O GKE distribui o tráfego por todos os pods íntegros que correspondem a esse seletor. Se vários pods correspondentes residirem no mesmo nó, o GKE selecionará apenas o pod criado mais recentemente para receber tráfego. Os rótulos definidos aqui não podem se sobrepor aos do campo backupPodSelector. Este campo pode ser modificado.
  • backupPodSelector: define os pods em espera que recebem tráfego somente se todos os pods principais que correspondem ao objeto podSelector falharem nas verificações de integridade. Esse seletor inclui o seguinte:
    • namespaceSelector: determina quais namespaces o GKE pesquisa para encontrar esses pods de backup. É possível limitar a pesquisa a namespaces específicos usando seletores de rótulo. Se esse campo for omitido ou estiver vazio, o GKE vai procurar pods de backup em todos os namespaces do cluster.
    • podSelector: corresponde aos pods de backup com base nos rótulos deles. Esses rótulos precisam ser diferentes daqueles usados no objeto podSelector principal.

Para mais detalhes sobre os outros campos neste manifesto, consulte Criar o objeto GKEIPRoute.

Etapa 6: usar os endereços IP atribuídos no pod

Atribuir um endereço IP a um pod do GKE usando um objeto GKEIPRoute não torna os endereços IP utilizáveis automaticamente pelo aplicativo. Os endereços IP são tratados no nível de roteamento de rede, mas a configuração padrão do pod não terá conhecimento deles. Configure a especificação do pod para reconhecer e usar o endereço no pod. Para isso, seu pod precisa de permissões de privilégios.

É possível configurar a especificação do pod usando uma das seguintes opções:

  • Modificar o sysctl net.ipv4.ip_nonlocal_bind

    É possível modificar as configurações do sistema para permitir que o aplicativo use endereços IP não atribuídos diretamente à interface definindo net.ipv4.ip_nonlocal_bind sysctl no pod securityContext. Essa opção é útil se o aplicativo puder se vincular a um endereço IP que não está em uma interface.

    Adicione o seguinte à especificação YAML de implantação ou StatefulSet em spec.template.spec:

    securityContext:
      sysctls:
      - name: net.ipv4.ip_nonlocal_bind
        value: "1"
    
  • Adicione o endereço IP atribuído à interface do pod

    É possível adicionar manualmente o endereço IP reivindicado pelo objeto GKEIPRoute a uma das interfaces do pod usando um contêiner de inicialização. Isso torna o endereço IP visível para o pod como se ele tivesse sido atribuído diretamente. Isso requer a competência NET_ADMIN.

    Adicione o seguinte à especificação YAML de implantação ou StatefulSet em spec.template.spec:

    initContainers:
    - name: configure-ips
      image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
      command: ['sh', '-c', 'ip address add ASSIGNED_IP/32 dev eth0']
      securityContext:
        capabilities:
          add:
          - NET_ADMIN
    

    Substitua ASSIGNED_IP por um dos endereços IP atribuídos ao objeto GKEIPRoute.

  • Soquetes brutos:para ter ainda mais controle, o aplicativo pode interagir diretamente com a pilha de rede (avançado).

  • Pilha de endereços IP do espaço do usuário:em casos especializados, um aplicativo separado pode ser executado no pod para gerenciar o endereço IP (muito avançado).

Etapa 7: ativar o ARP para os endereços IP atribuídos (somente rede padrão)

Para gerar solicitações e respostas válidas do protocolo de resolução de endereços (ARP) e estabelecer uma nova conexão com um pod usando o endereço IP atribuído pelo objeto GKEIPRoute na rede padrão, configure a variável arp_announce.

Para definir a variável arp_announce, execute o seguinte comando no seu pod:

echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce

em que a variável arp_announce controla como os anúncios de ARP são processados. Definir como "2" garante que os anúncios de ARP sejam feitos para o endereço IP persistente, permitindo que outros dispositivos na rede saibam sobre a nova associação.

Etapa 8: ver os endpoints correspondentes

Para gerenciar a distribuição de tráfego, o GKE cria EndpointSlices para cada objeto GKEIPRoute. Esses intervalos atuam como um registro de todos os pods designados como destinos de roteamento para essa rota específica.

O GKE gera EndpointSlices separados para endpoints ativos e de backup. O sistema escalona automaticamente o número de EndpointSlices com base na sua carga de trabalho. Embora um único EndpointSlice suporte até 1.000 endpoints, o GKE cria mais frações se a contagem de pods correspondentes ultrapassar esse limite.

Para conferir todas as EndpointSlices de um objeto GKEIPRoute específico, execute o seguinte comando:

kubectl get endpointslices --all-namespaces -l \
  networking.gke.io/gkeiproute-name=GKEIPROUTE_NAME,\
  networking.gke.io/gkeiproute-namespace=GKEIPROUTE_NAMESPACE

Substitua:

  • GKEIPROUTE_NAME: o nome do manifesto GKEIPRoute.
  • GKEIPROUTE_NAMESPACE: o namespace do manifesto GKEIPRoute.

A saída a seguir mostra um exemplo de EndpointSlice:

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
 name: {gkeiproute_name-truncated}-{gkeiproute_namespace-truncated}-backup-{unique_hash}
 namespace: {gkeiproute_namespace}
 labels:
  endpointslice.kubernetes.io/managed-by: gkeiproute-controller
  networking.gke.io/gkeiproute-name: {gkeiproute_name}
  networking.gke.io/gkeiproute-namespace: {gkeiproute_namespace}
  networking.gke.io/pip-es-role: backup
 ownerReferences:
  - kind: GKEIPRoute
    name: {gkeiproute_name}
    apiVersion: networking.gke.io/v1
    uid: {uid}
    controller: true
addressType: IPv4
endpoints:
 - addresses:
     - "{pod_ip_address}"
   targetRef:
     Name: {pod_name}
   nodeName: {node_name}

Para ver EndpointSlices especificamente para endpoints ativos ou de backup, filtre os resultados usando o rótulo pip-eps-role. Exemplo:

kubectl get endpointslices --all-namespaces -l \
   networking.gke.io/pip-eps-role=ROLE \
  networking.gke.io/gkeiproute-name=GKEIPROUTE_NAME,

Substitua:

  • ROLE: o tipo de endpoint que você quer ver, active ou backup.
  • GKEIPROUTE_NAME: o nome do seu objeto GKEIPRoute específico.

Solucionar problemas de balanceamento de carga com base em verificações de integridade

Nesta seção, mostramos como resolver problemas relacionados ao balanceamento de carga baseado em verificação de integridade.

Alguns pods ativos não estão íntegros, mas os pods de backup não recebem tráfego

Sintoma

O status do GKEIPRoute mostra Ready, o que indica que a configuração do endereço IP para pods correspondentes foi concluída. As verificações de integridade ou outros diagnósticos mostram que alguns pods ativos não estão íntegros. No entanto, os pods de backup não recebem tráfego.

Causa

Os pods de backup não recebem tráfego até que todos os pods ativos não estejam íntegros. Até lá, todo o tráfego será distribuído entre os pods íntegros e ativos restantes.

Resolução

Se necessário, atualize os rótulos dos campos podSelector para que não correspondam mais a nenhum pod ativo. O GKE roteia automaticamente o tráfego para o grupo de back-end.

GKEIPRoute está configurado, mas nem todos os pods recebem tráfego

Sintoma

O status do GKEIPRoute mostra Ready, o que indica que a configuração de endereço IP para pods correspondentes foi concluída, mas alguns dos pods correspondentes não recebem tráfego.

Causa

Os pods que não recebem tráfego podem não estar íntegros ou não estar respondendo corretamente às verificações de integridade. Se todos os pods correspondentes não estiverem íntegros, o GKE vai distribuir o tráfego entre todos os pods, independente do status de integridade.

Resolução

  • Verifique se o pod está íntegro: use a Google Cloud CLI ou o consoleGoogle Cloud para verificar se o pod responde corretamente às verificações de integridade.
  • Investigue mais se necessário: se o pod não estiver íntegro, verifique se você configurou corretamente os firewalls para as verificações de integridade e se o pod está respondendo.

Erros de configuração inválida do balanceador de carga

Esta seção ajuda a resolver erros de status do GKEIPRoute.

Backup pod and active pod are on the same node

Sintoma

O status do GKEIPRoute informa o seguinte erro:

invalid LB configuration: Backup pod %s and active pod %s are on the same node %s. Active and backup pods must reside on different nodes.

Causa

Um pod ativo e um pod de backup que correspondem ao mesmo objeto GKEIPRoute são programados no mesmo nó. Em outras palavras, há pods que correspondem aos objetos podSelector ativos e de backup no mesmo nó.

Resolução

Verifique se os pods ativos e de backup estão em nós diferentes. Atualize a configuração do GKEIPRoute e ajuste os rótulos podSelector ou backupPodSelector para que dois pods no mesmo nó não correspondam ao mesmo objeto GKEIPRoute.

Pod cannot be selected as both an active and a backup pod

Sintoma

O status do GKEIPRoute informa o seguinte erro:

invalid LB configuration: pod %s cannot be selected as both an active and a backup pod. Active and backup pod sets must be mutually exclusive

Causa

Um ou mais pods correspondem aos seletores de rótulo para os campos podSelector (ativo) e backupPodSelector (em espera). O GKE exige que esses dois grupos sejam mutuamente exclusivos. Um único pod não pode servir como backup dele mesmo.

Resolução

Verifique se os pods ativos e de backup são exclusivos. Modifique o campo podSelector ou o campo backupPodSelector no manifesto GKEIPRoute para usar chaves e valores de rótulo mais específicos ou distintos.

Status NoPodsFound

Sintoma

O manifesto GKEIPRoute mostra um status de NoPodsFound, o que indica que não há pods nos namespaces com rótulos correspondentes.

Causas possíveis

  • Rótulos incorretos: o pod em que você pretende usar o endereço IP configurado pode ter rótulos incorretos ou nenhum rótulo.
  • Não há pods: se reactionMode == Exists, verifique se o pod está atribuído a um nó ao verificar o campo pod.Spec.nodeName. Pode não haver pods em execução no namespace do GKEIPRoute que correspondam ao seletor.
  • Pods não estão prontos: se reactionMode == ReadyCondition, verifique se o status do pod é READY. Se houver um pod correspondente, mas ele não estiver em um estado READY, ele não poderá veicular tráfego e, por isso, não será selecionado.

Resolução

  • Verifique os rótulos: confirme se os rótulos no campo podSelector do objeto GKEIPRoute correspondem aos rótulos aplicados ao pod pretendido.
  • Verificar a existência do pod: confirme se um pod com os rótulos corretos existe nos namespaces do objeto GKEIPRoute especificados pelos listeners do gateway. Se reactionMode == Exists, verifique se o pod está atribuído a um nó ao verificar o campo pod.Spec.nodeName.
  • Confirme a prontidão do pod: se reactionMode == ReadyCondition, verifique se o status do pod é READY. Verifique se o pod está no estado Ready usando o seguinte comando:

    kubectl get pods -n NAMESPACE
    

    Os pods em outros estados (por exemplo, Pending, Error) não são selecionados.

Status Mutated quando um pod correspondente foi encontrado e a programação de endereços IP do GKEIPRoute está em andamento

Sintoma

O status do GKEIPRoute mostra Mutated, o que indica que a configuração do endereço IP de um pod correspondente está em andamento.

Possível causa

Você pode esperar o status Mutated durante a configuração enquanto o sistema está configurando o caminho de dados do GKE e os recursos Google Cloud para o endereço IP configurado.

Resolução

  1. Aguarde e tente novamente: na maioria dos casos, o processo de configuração é concluído automaticamente em pouco tempo. Verifique o status depois de esperar. Ele será alterado para Ready quando for bem-sucedido.
  2. Investigue mais (se necessário): se o status Mutated continuar por um longo período, isso pode indicar um erro de configuração. Examine as outras condições de status no objeto GKEIPRoute:

    • Aceita: indica se a configuração do GKEIPRoute é válida.
    • GCPReady: indica se os recursos do Google Cloud estão configurados como esperado.

Procure mensagens de erro nessas condições para ajudar a resolver o problema.

A seguir