Compartilhar via


Diagnosticar e resolver quedas de pacotes UDP no Serviço de Kubernetes do Azure (AKS)

O protocolo UDP é um protocolo sem conexão usado em clusters gerenciados do AKS. Os pacotes UDP são enviados sem qualquer garantia de entrega, confiabilidade ou ordem, pois não estabelecem uma conexão antes da transferência de dados. Isso significa que os pacotes UDP podem ser perdidos, duplicados ou chegar fora de ordem no destino devido a vários motivos.

Este artigo descreve como diagnosticar e resolver problemas de queda de pacote UDP causados por um pequeno buffer de leitura que pode estourar em casos em que você tem alto tráfego de rede.

Pré-requisitos

  • Um cluster do AKS com pelo menos um pool de nós e um pod executando um aplicativo baseado em UDP.
  • CLI do Azure instalada e configurada. Para obter mais informações, consulte Instalar a CLI do Azure.
  • Kubectl instalado e configurado para se conectar ao cluster do AKS. Para obter mais informações, confira Instalar o kubectl.
  • Um computador cliente que pode enviar e receber pacotes UDP de e para o cluster do AKS.

Problema: as conexões UDP têm uma alta taxa de queda de pacotes

Uma possível causa da perda de pacote UDP é que o tamanho do buffer UDP é muito pequeno para lidar com o tráfego de entrada. O tamanho do buffer UDP determina quantos dados podem ser armazenados no kernel antes de serem processados pelo aplicativo. Se o tamanho do buffer for insuficiente, o kernel poderá remover os pacotes que excedem a capacidade do buffer. Essa configuração é gerenciada no nível da máquina virtual (VM) para seus nós e o valor padrão é definido para 1048576 bytes ou 1 MB.

Observação

Versões do Ubuntu anteriores a 24.10, exceto 20.04, 22.04 e 24.04, têm a capacidade padrão de buffer UDP definida para 212992 bytes ou 0.2 MB.

Há duas variáveis diferentes no nível da VM que se aplicam aos tamanhos de buffer:

  • net.core.rmem_max = 1048576 bytes: o maior valor de buffer que um proprietário de soquete pode definir explicitamente.
  • net.core.rmem_default = 1048576 bytes: o máximo para o qual o sistema pode aumentar o buffer se um valor rmem_max não for definido explicitamente.

Para permitir que o buffer cresça para atender a altas intermitências de tráfego, precisamos atualizar os valores de tamanho do buffer.

Observação

Este artigo se concentra nos tamanhos de buffer do kernel do Ubuntu Linux. Se você quiser ver outras configurações para Linux e Windows, consulte Personalizar a configuração de nós para pools de nós do AKS.

Diagnosticar

Verificar as configurações atuais do buffer UDP

  1. Obtenha uma lista dos seus nós usando o comando kubectl get nodes e escolha um nó para o qual quer verificar as configurações do buffer.

    kubectl get nodes
    
  2. Configure um pod de depuração no nó selecionado usando o comando kubectl debug. Substitua <node-name> pelo nome do banco de dados que você quer depurar.

    kubectl debug -it node/<node-name> --image=ubuntu --share-processes -- bash
    
  3. Obtenha o valor das variáveis net.core.rmem_max e net.core.rmem_default usando o seguinte comando sysctl:

    sysctl net.core.rmem_max net.core.rmem_default
    

Medir o tráfego UDP de entrada

Para verificar se seu buffer é muito pequeno para seu aplicativo e está descartando pacotes, comece simulando um tráfego de rede realista nos seus pods e configurando um pod de depuração para monitorar o tráfego de entrada. Em seguida, você pode usar os comandos a seguir para medir o tráfego UDP de entrada.

  1. Verifique o arquivo UDP enquanto o teste está em execução usando o seguinte comando cat:

    cat /proc/net/udp
    

    Este arquivo mostra as estatísticas das conexões abertas atuais na coluna rx_queue. Ele não mostra dados históricos.

  2. Verifique o arquivo snmp e compare o valor RcvbufErrors antes e depois do teste usando o seguinte comando cat:

    cat /proc/net/snmp
    

    Este arquivo mostra os pacotes UDP desde o início até o momento (LTD), incluindo quantos pacotes foram descartados na coluna RcvbufErrors.

Se você observar um aumento além do tamanho do buffer no rx_queue ou um aumento no valor de RcvbufErrors, será necessário aumentar o tamanho do buffer.

Observação

Aumentar o tamanho do buffer do sistema pode não ser eficaz se o aplicativo não conseguir acompanhar a taxa de pacotes de entrada. Aumentar o tamanho do buffer do sistema neste caso apenas atrasaria a queda do pacote. Você deve considerar examinar e melhorar seu aplicativo para saber como ele processa os pacotes UDP nessas situações. Um tamanho de buffer maior só será útil se você tiver picos ocasionais de tráfego que às vezes preencham o buffer, pois isso fornece ao kernel mais tempo/recursos para lidar com o aumento de solicitações.

Mitigar

Observação

O kernel aloca dinamicamente os buffers de leitura para cada soquete quando os pacotes chegam, em vez de alocá-los com antecedência. As configurações rmem_default e rmem_max especificam os limites do buffer do kernel para cada soquete antes da perda de pacote.

É possível alterar os valores de tamanho do buffer em um nível de pool de nós durante o processo de criação do pool de nós. As etapas desta seção mostram como você pode configurar o sistema operacional Linux e aplicar as alterações a todos os nós do pool de nós. Você não pode adicionar essa configuração a um pool de nós existente.

  1. Crie um arquivo linuxosconfig.json em seu computador local com o conteúdo a seguir. Você pode modificar os valores de acordo com os requisitos do aplicativo e a SKU do nó. O valor mínimo é 212992 bytes e o máximo é 134217728 bytes.

    {
        "sysctls": {
            "netCoreRmemMax": 1572864,
            "netCoreRmemDefault": 1572864
        }
    }
    
  2. Verifique se você está no mesmo diretório que o arquivo linuxosconfig.json e crie um novo pool de nós com a configuração de tamanho do buffer usando o comando az aks nodepool add.

    az aks nodepool add --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --name $NODE_POOL_NAME --linux-os-config ./linuxosconfig.json
    

    Este comando define o tamanho máximo do buffer UDP como 8 MB para cada soquete no nó. Você pode ajustar esses valores no arquivo linuxosconfig.json com base nos requisitos do aplicativo.

Validar

Depois de aplicar os novos valores, você poderá acessar sua VM para garantir que os novos valores sejam definidos como padrão.

  1. Obtenha uma lista dos seus nós usando o comando kubectl get nodes e escolha um nó para o qual quer verificar as configurações do buffer.

    kubectl get nodes
    
  2. Configure um pod de depuração no nó selecionado usando o comando kubectl debug. Substitua <node-name> pelo nome do banco de dados que você quer depurar.

    kubectl debug -it node/<node-name> --image=ubuntu --share-processes -- bash
    
  3. Obtenha o valor da variável net.core.rmem_max usando o seguinte comando sysctl:

    sysctl net.core.rmem_max net.core.rmem_default
    

    Seus valores agora devem ser definidos como os valores descritos em linuxosconfig.json.

Reversão para os valores originais

Se você quiser restaurar o tamanho do buffer para seu valor padrão de 1 MB, você poderá atualizar o arquivo linuxosconfig.json com os seguintes valores:

{
    "sysctls": {
        "netCoreRmemMax": 1048576,
        "netCoreRmemDefault": 1048576
    }
}

Próximas etapas

Neste artigo, você aprendeu a diagnosticar e resolver quedas de pacote UDP no Serviço de Kubernetes do Azure (AKS). Para obter mais informações sobre como solucionar problemas no AKS, consulte a Documentação de solução de problemas do Serviço de Kubernetes do Azure.