Resolver problemas de distribuição de tráfego desigual

Neste documento, mostramos como resolver problemas de distribuição desigual de tráfego para serviços do Kubernetes.

Identificar sintomas de distribuição de tráfego desigual

A distribuição desigual de tráfego, geralmente chamada de pontos de acesso, ocorre quando um subconjunto de pods ou nós processa uma quantidade desproporcional da carga de trabalho total, enquanto outros permanecem subutilizados.

Os sintomas comuns incluem:

  • Gargalos de desempenho: os usuários podem ter tempos limite intermitentes, erros HTTP 5xx ou perda de pacotes em conexões de rede superutilizadas.
  • Esgotamento de recursos: pods ou nós específicos mostram uma utilização de CPU ou memória significativamente maior do que o restante da frota.
  • Padrões de desequilíbrio de tráfego:
    • Desequilíbrio por pod: o tráfego atinge apenas um pequeno subconjunto de pods disponíveis, mesmo que todos os pods sejam informados como íntegros e prontos.
    • Desequilíbrio por nó: um ou mais nós recebem significativamente mais pacotes ou solicitações do que outros, o que geralmente acontece ao usar externalTrafficPolicy: Local com posicionamento desigual de pods.
    • Sessões de clientes fixas: todas as solicitações de um único cliente de alto volume são sempre encaminhadas para o mesmo pod de back-end.

Diagnóstico usando o Cloud Monitoring

Para confirmar esses sintomas, visualize os padrões de tráfego usando as seguintes métricas:

  • Para a camada 7 (entrada/gateway): plote loadbalancing.googleapis.com/backend/request_count e agrupe por backend_target para comparar volumes de solicitações em diferentes back-ends.

Entender as causas comuns da distribuição desigual de tráfego

Esta seção descreve as causas comuns da distribuição desigual de tráfego para serviços do Kubernetes. Esse desequilíbrio pode levar a gargalos de desempenho, esgotamento de recursos em determinados pods e redução da disponibilidade do aplicativo, com alguns pods recebendo significativamente mais tráfego do que outros, enquanto alguns recebem muito pouco ou nenhum.

A afinidade da sessão causa distribuição desigual

O problema a seguir ocorre quando os balanceadores de carga com a afinidade da sessão ativada sempre encaminham solicitações do mesmo cliente para o mesmo pod de back-end. Se um cliente específico gerar um grande volume de tráfego, esse pod ficará sobrecarregado, levando a um ponto de acesso em que ele recebe uma carga significativamente maior do que outros, enquanto outros pods permanecem subutilizados.

É possível configurar a afinidade da sessão em objetos de serviço do Kubernetes usando o campo sessionAffinity.

Quando sessionAffinity está definido como ClientIP, o serviço garante que todas as conexões originadas do mesmo endereço IP do cliente sejam sempre encaminhadas para o mesmo pod de back-end. Isso fornece a verdadeira afinidade da sessão baseada em IP do cliente.

Quando sessionAffinity está definido como None (o comportamento padrão), os balanceadores de carga da camada 4 normalmente distribuem conexões usando um hash de vários parâmetros de rede, como uma tupla de 4 (endereço IP do cliente, endereço IP de destino, porta de destino, protocolo) ou uma tupla de 5 (incluindo a porta de origem). Embora esse hash possa fornecer alguma "fixação" de conexão, encaminhando sempre conexões com valores de tupla idênticos para o mesmo back-end, ele não garante que todas as conexões de um endereço IP de cliente específico sempre vão para o mesmo pod se outros elementos de tupla mudarem.

Para mais informações, consulte Afinidade de sessão.

Para o GKE Gateway, o CRD GCPTrafficDistributionPolicy configura a afinidade da sessão. Para mais informações, consulte Configurar recursos do Gateway usando políticas.

Para balanceadores de carga de rede de passagem externa regional, é possível usar a afinidade da sessão para manter a fixação de conexão a um back-end específico. No entanto, a afinidade da sessão pode causar distribuição desigual se alguns clientes gerarem mais tráfego do que outros.

Para mais informações, consulte Afinidade de sessão e Visão geral do balanceador de carga de rede de passagem externa baseado em serviço de back-end.

O exemplo a seguir mostra um manifesto de serviço com sessionAffinity: ClientIP:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  sessionAffinity: ClientIP  # This can cause uneven distribution
  ports:
  -   port: 80
    targetPort: 8080
  selector:
    app: my-app

O pool de conexões causa distribuição desigual

O pool de conexões ocorre quando os balanceadores de carga reutilizam conexões atuais para pods específicos, mesmo que outros pods tenham capacidade disponível. Esse comportamento pode causar um desequilíbrio se algumas conexões forem mais longas ou processarem significativamente mais solicitações do que outras. Isso concentra o tráfego em determinados pods, semelhante à afinidade da sessão, criando pontos de acesso em que esses pods ficam sobrecarregados, enquanto outros permanecem subutilizados.

Os balanceadores de carga implementam o pool de conexões para melhorar o desempenho, reduzindo o overhead de estabelecer novas conexões. No entanto, se não for gerenciado corretamente, o pool de conexões poderá causar distribuição desigual de tráfego, especialmente com aplicativos que mantêm conexões de longa duração.

Para atenuar a distribuição desigual causada pelo pool de conexões, implemente estratégias no nível do aplicativo ou do cliente:

  • Configure os clientes para usar várias conexões: em vez de depender de uma única conexão de longa duração, configure os clientes para abrir e gerenciar um pool de várias conexões com o balanceador de carga. Isso permite que o balanceador de carga distribua novas tentativas de conexão entre os pods de back-end disponíveis, melhorando a distribuição geral de tráfego.

  • Feche e reabra conexões periodicamente: para aplicativos que naturalmente mantêm conexões de longa duração, configure-os ou os clientes para fechar e reabrir conexões periodicamente. Embora isso incorra em um pequeno overhead de restabelecimento de conexão, ele oferece ao balanceador de carga novas oportunidades de distribuir tentativas de conexão subsequentes para pods de back-end diferentes e menos utilizados. Essa abordagem é particularmente eficaz para serviços em que o encerramento e o restabelecimento da conexão não são muito disruptivos.

  • Implemente a diminuição agressiva da conexão: verifique se os pods estão configurados para encerramento completo e diminuição da conexão. Quando um pod é encerrado normalmente (por exemplo, durante uma implantação ou redução), o balanceador de carga precisa parar de enviar novas conexões para ele e permitir que as conexões atuais sejam concluídas ou diminuídas. Isso permite que o tráfego mude para outros pods com mais facilidade e ajuda a evitar que o tráfego seja concentrado em pods de encerramento.

Ao gerenciar ativamente o comportamento da conexão, é possível ajudar os balanceadores de carga a distribuir o tráfego de maneira mais uniforme, mesmo com conexões de longa duração.

O hash de 5 tuplas causa distribuição desigual

Esse é o comportamento padrão de muitos balanceadores de carga da camada 4 quando você não configura explicitamente a afinidade da sessão. Se muitas conexões forem originadas do mesmo cliente ou usarem as mesmas combinações de porta, isso resultará em uma distribuição desigual.

Para resolver desequilíbrios causados por hash, considere o seguinte:

  • Use o balanceamento de carga da camada 7: o GKE Ingress e o Gateway operam no nível da solicitação, permitindo que eles distribuam solicitações de um único cliente em vários pods de back-end.

  • Ajuste o comportamento do cliente: configure os clientes para usar várias conexões ou um pool maior de portas de origem.

A distribuição desigual de pods entre nós causa distribuição desigual

Esse problema surge quando os pods não são distribuídos uniformemente entre os nós e o balanceador de carga não usa o balanceamento de carga nativo de contêiner. Os nós com mais pods recebem mais tráfego, o que pode levar à sobrecarga de alguns nós, enquanto outros são subutilizados.

Esse problema é especialmente relevante quando você usa externalTrafficPolicy: Local.

As configurações de política de tráfego externa causam distribuição desigual

A configuração externalTrafficPolicy no serviço afeta a maneira como o tráfego é roteado.

  • Cluster: permite que o balanceador de carga distribua o tráfego para qualquer nó no cluster. Use a configuração Cluster para a distribuição mais uniforme em todos os nós e pods disponíveis.
  • Local: encaminha o tráfego apenas para pods em execução no mesmo nó que recebeu o tráfego. Isso pode levar a uma distribuição desigual se você não distribuir os pods uniformemente entre os nós.

A afinidade de nó causa distribuição desigual

O uso da afinidade de nó para restringir pods a um subconjunto de nós pode fazer com que esses nós fiquem sobrecarregados, especialmente se a carga de trabalho não estiver bem balanceada entre eles.

Verifique se os pods não estão fixados a nós específicos.