O ACK KubeSkoop (anteriormente ACK Net Exporter) é um pacote de monitoramento e solução de problemas de rede de código aberto do Container Service for Kubernetes (ACK) da Alibaba Cloud. Ele ajuda a monitorar e solucionar rapidamente problemas complexos de rede em seus clusters. As práticas recomendadas para usar o KubeSkoop no cluster gerenciado pelo ACK ajudam a começar e a resolver problemas reais.
Informações de contexto
O KubeSkoop fornece recursos baseados em eBPF, como monitoramento de rede detalhado, diagnósticos de conectividade de rede, captura de pacotes e sondagem de latência, além de expor métricas do Prometheus e eventos de anomalia. O KubeSkoop é executado nos nós como Pods daemon. Ele usa o eBPF para coletar informações do nó e agregá-las em Pods específicos, e fornece uma interface padronizada para observar informações de rede de alto nível. A figura a seguir mostra a arquitetura principal do KubeSkoop.
Instale e configure o complemento ACK KubeSkoop
Instale o complemento ACK KubeSkoop
Faça login no ACK console. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em Components and Add-ons .
Na página Add-ons, pesquise por ACK KubeSkoop, encontre o complemento e clique em Install.
Na página InstallACK KubeSkoop, clique em Confirm.
Configure o complemento KubeSkoop
-
Execute o comando a seguir para configurar o complemento KubeSkoop com um ConfigMap.
kubectl edit cm kubeskoop-config -n ack-kubeskoop -
Também é possível configurar o complemento KubeSkoop no console.
Faça login no ACK console. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em .
Na página ConfigMaps, defina o Namespace como ack-kubeskoop e pesquise por kubeskoop-config. Para kubeskoop-config, na coluna Actions à direita, clique em Edit.
-
No painel Edit, configure os parâmetros e clique em OK. O KubeSkoop oferece suporte aos seguintes itens de configuração:
Parâmetro
Descrição
Valor padrão
debugmode
Especifica se o modo de depuração será ativado. Valores válidos:
-
false: desativa o modo de depuração.
-
true: ative o modo de depuração, com suporte a logs de nível DEBUG, interfaces de depuração e ferramentas de diagnóstico Go pprof e gops.
falseport
A porta na qual o service de métricas fornece acesso HTTP.
9102enableController
Especifica se o componente controller será ativado. O controller interage com a API do Kubernetes para executar tarefas de monitoramento ou gerenciamento.
truecontrollerAddr
O endereço do service do controller, usado para localizar o componente controller do KubeSkoop.
dns:kubeskoop-controller:10263metrics.probes
A lista de tipos de métricas a serem coletadas. Cada probe corresponde a uma categoria de métrica.
metrics: probes: - name: conntrack - name: qdisc - name: netdev - name: io - name: sock - name: tcpsummary - name: tcp - name: tcpext - name: udp - name: rdmaPara obter mais informações sobre cada probe, consulte Probes, Metrics, and Events.
Após atualizar o ConfigMap, não é necessário reiniciar o complemento ACK KubeSkoop. O complemento recarrega as alterações automaticamente e ativa ou desativa as probes correspondentes.
-
Configure o painel do Prometheus do Application Real-Time Monitoring Service (ARMS)
Faça login no ARMS console.
No painel de navegação à esquerda, clique em Integration Management.
Na página Integration Management, clique em Add Integration, pesquise por KubeSkoop na caixa de pesquisa do Integration Center e clique em ACK KubeSkoop Network Monitor.
Na página ACK KubeSkoop Network Monitor exibida, selecione o cluster do Container Service for Kubernetes a ser integrado, insira um Integration Name e clique em OK para ativar o monitoramento do KubeSkoop.
Faça login no ACK console. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em .
Clique na guia Others. Na lista de painéis, visualize os painéis de monitoramento de nós e Pods criados pelo KubeSkoop. Na página Prometheus Monitoring, clique na guia Others e localize as guias Ack KubeSkoop Network Monitor - Node e Ack KubeSkoop Network Monitor - Pod para visualizar o painel de monitoramento de rede do KubeSkoop.
Para obter mais informações sobre o Managed Service for Prometheus, consulte Configure Managed Service for Prometheus.
Usar o KubeSkoop
Visualizar manualmente as métricas de monitoramento do KubeSkoop
O KubeSkoop fornece dados de monitoramento no formato do Prometheus. Após instalar o KubeSkoop, acesse a porta do service de qualquer instância de Pod do KubeSkoop para obter todas as informações de métricas:
-
Execute o comando a seguir para obter todas as instâncias do KubeSkoop.
kubectl get pod -n ack-kubeskoop -o wide | grep kubeskoop-agentSaída esperada:
kubeskoop-agent-2chvw 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none> kubeskoop-agent-2qtbf 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none> kubeskoop-agent-72pgf 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none> -
Execute o comando a seguir para obter as informações de métricas. Substitua
172.16.xxx.xxxno comando pelo endereço da instância do KubeSkoop obtido na etapa anterior.curl http://172.16.16.xxx:9102/metrics
Os dados de métricas de monitoramento fornecidos pelo KubeSkoop estão no seguinte formato:
kubeskoop_netdev_rxbytes{k8s_namespace="",k8s_node="cn-hangzhou.172.16.16.xxx",k8s_pod=""} 2.970963745e+09
Como usar o ACK KubeSkoop para solucionar problemas complexos intermitentes em redes de contêineres
O conteúdo a seguir fornece guias de solução de problemas para alguns problemas típicos nativos da cloud. Com o ACK KubeSkoop, esses guias ajudam a obter rapidamente informações relacionadas ao problema.
Problemas de tempo limite de DNS
Em ambientes nativos da cloud, os tempos limite do service de DNS causam falhas no acesso ao service. As causas comuns de tempos limite de acesso ao DNS incluem:
O service de DNS responde lentamente e não consegue concluir uma consulta DNS antes do tempo limite do aplicativo.
O remetente não consegue enviar o pacote de consulta DNS de forma fluida ou dentro do prazo devido a um problema no lado do remetente.
O servidor responde ao pacote dentro do prazo, mas os pacotes são descartados por problemas como memória insuficiente no remetente.
Use as métricas a seguir para ajudar a solucionar problemas intermitentes de tempo limite de DNS:
|
Métrica |
Descrição |
|
kubeskoop_pod_udpsndbuferrors |
Número de erros que ocorrem ao enviar pacotes UDP por métodos da camada de rede. |
|
kubeskoop_pod_udpincsumerrors |
Número de erros de verificação CSUM ao receber pacotes UDP. |
|
kubeskoop_pod_udpnoports |
Número de vezes que a chamada da camada de rede |
|
kubeskoop_pod_udpinerrors |
Número de erros ao receber pacotes UDP. |
|
kubeskoop_pod_udpoutdatagrams |
Número de pacotes UDP enviados com sucesso por métodos da camada de rede. |
|
kubeskoop_pod_udprcvbuferrors |
Número de erros ao copiar dados do protocolo da camada de aplicação para a fila de recebimento do socket quando a fila não tem espaço suficiente. |
Em ambientes nativos da cloud, muitos services dependem do CoreDNS para a resolução de DNS. Quando ocorre um problema de DNS, se a solicitação DNS com falha envolver o CoreDNS, verifique também as métricas anteriores dos Pods do CoreDNS em busca de anomalias.
Problemas de código de status de resposta HTTP 499/502/503/504 do Nginx Ingress
Em ambientes nativos da cloud, exceções intermitentes em um gateway Ingress ou em outros services de proxy que atuam como intermediário são problemas complexos comuns. Para o Nginx Ingress e outros services de proxy baseados no Nginx, 499/502/503/504 são os quatro tipos mais comuns de problemas. Eles indicam o seguinte:
-
499: O cliente que envia solicitações ao Nginx fecha a conexão TCP antes da resposta do Nginx. As causas comuns incluem:Após estabelecer a conexão, o cliente envia a solicitação com atraso e atinge o tempo limite enquanto o Nginx responde. Isso é comum em frameworks de requisição assíncrona de clientes Android.
O servidor processa a conexão lentamente após estabelecer a conexão, o que exige mais investigação.
O backend responde lentamente quando o servidor envia uma solicitação ao upstream.
-
502: Esse cenário geralmente é causado por problemas no nível de conexão entre o Nginx e o upstream, como falhas no estabelecimento de conexão ou fechamentos anormais pelo backend. As causas comuns incluem:A resolução de DNS falha para o nome de domínio configurado para o backend. Isso geralmente ocorre quando um Service do Kubernetes é usado como backend.
Falha ao estabelecer uma conexão com o upstream.
A solicitação ou resposta do upstream é grande demais para a alocação de memória, o que interrompe as interações normais do service.
-
503: No Nginx, esse código de status indica ao cliente que todos os upstreams estão indisponíveis. Em cenários nativos da cloud, possui significados específicos. As causas comuns incluem:Nenhum backend está disponível. Essa situação é rara.
O volume de tráfego é muito alto e sofre limitação pelo recurso Limit Req do Ingress.
504: Esse código de status indica que os pacotes de service relacionados ao upstream atingem o tempo limite no Nginx. Uma causa comum é os pacotes de service retornados pelo upstream não chegarem a tempo.
Ao encontrar os tipos de problema acima, primeiro colete algumas informações gerais para determinar o possível escopo do problema e os próximos passos da solução de problemas:
As informações de access_log fornecidas pelo Nginx, especialmente
request_time,upstream_connect_timeeupstream_response_time.As informações de error_log fornecidas pelo Nginx, especialmente a presença de mensagens de erro anômalas quando o problema ocorre.
Os resultados da verificação de integridade, caso as verificações de liveness ou readiness estejam configuradas.
Com base nas informações anteriores, caso haja suspeita de falhas de conexão, monitore as alterações nas métricas a seguir de acordo com os sintomas específicos do problema:
|
Métrica |
Descrição |
|
kubeskoop_tcpext_listenoverflow |
Número de vezes que a fila de conexão semi-aberta transborda quando um socket no estado LISTEN aceita uma conexão. |
|
kubeskoop_tcpext_listendrops |
Número de vezes que um socket no estado LISTEN falha ao criar um socket no estado SYN_RECV. |
|
kubeskoop_netdev_txdropped |
Número de erros de envio da NIC que resultam em pacotes descartados. |
|
kubeskoop_netdev_rxdropped |
Número de erros de recebimento da NIC que resultam em pacotes descartados. |
|
kubeskoop_tcp_activeopens |
Número de vezes que o TCP em um único Pod inicia com sucesso o primeiro handshake SYN. Retransmissões SYN não estão incluídas, mas falhas no estabelecimento de conexão também aumentam essa métrica. |
|
kubeskoop_tcp_passiveopens |
Número acumulado de vezes que o TCP em um único Pod conclui o handshake e aloca com sucesso um socket. Essa métrica geralmente representa o número de conexões estabelecidas com sucesso. |
|
kubeskoop_tcp_retranssegs |
Número total de pacotes retransmitidos em um único Pod. A contagem é calculada antecipadamente com base na segmentação TSO. |
|
kubeskoop_tcp_estabresets |
Número de vezes que as conexões TCP são fechadas anormalmente em um único Pod. Esta métrica conta apenas o resultado. |
|
kubeskoop_tcp_outrsts |
Número de pacotes Reset que o TCP envia em um único Pod. |
|
kubeskoop_conntrack_invalid |
Número de vezes que a criação de uma entrada conntrack (CT) falha por vários motivos, sem descartar o pacote. |
|
kubeskoop_conntrack_drop |
Número de pacotes descartados devido à falha na criação de uma entrada conntrack (CT). |
Se ocorrer um problema semelhante a respostas lentas do Nginx, por exemplo, se ocorrer um tempo limite, mas o request_time do Nginx for curto, monitore as alterações nas seguintes métricas:
|
Métrica |
Descrição |
|
kubeskoop_tcpsummary_tcpestablishedconn |
Número de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_pod_tcpsummarytcptimewaitconn |
Número de conexões TCP atualmente no estado TIME_WAIT. |
|
kubeskoop_tcpsummary_tcptimewaitconn |
Número total de bytes de pacotes na fila de envio de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_tcpsummary_tcprxqueue |
Número total de bytes de pacotes na fila de recebimento de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_tcpext_tcpretransfail |
Número de vezes que um pacote retransmitido retorna um erro diferente de EBUSY, indicando que a retransmissão não pode ser concluída normalmente. |
Com base nas informações de métricas anteriores, restrinja o escopo da solução de problemas ao examinar as mudanças nas métricas no momento em que o problema ocorre .
Problemas de pacotes TCP Reset
Um pacote TCP Reset é uma ação de resposta do protocolo TCP a situações inesperadas. Geralmente, causa os seguintes impactos nos aplicativos do usuário:
Erro
connection reset by peer, que geralmente ocorre em services que dependem da biblioteca C, como o Nginx.Erro
Broken pipe, que geralmente ocorre em services que encapsulam conexões TCP, como aplicativos Java ou Python.
Em ambientes de rede nativos da cloud, os pacotes Reset possuem diversas causas. A lista a seguir apresenta as mais comuns:
Exceções no lado do servidor que impedem a entrega normal do service, como memória insuficiente alocada ao TCP. Nesses casos, um pacote Reset geralmente é enviado de forma ativa.
Tráfego encaminhado para um backend inesperado porque um mecanismo stateful, como Endpoint ou conntrack, apresenta anomalias quando um Service ou balanceador de carga é usado.
Liberação de conexão causada por motivos de segurança.
Protection Against Wrapped Sequence Numbers (PAWS) ou wraparound de números de sequência em cenários como ambientes NAT e alta simultaneidade.
TCP Keepalive usado para manter uma conexão ativa enquanto nenhuma comunicação normal de service ocorre por um longo período.
Para distinguir rapidamente as causas raiz acima, colete algumas informações e métricas básicas:
Organize a topologia de rede entre o cliente e o servidor no momento em que o pacote Reset for gerado.
-
Monitore as alterações nas seguintes métricas:
Métrica
Descrição
kubeskoop_tcpext_tcpabortontimeout
Número de vezes que um pacote Reset é enviado porque as chamadas de keepalive, window probe ou retransmissão excedem o limite superior.
kubeskoop_tcpext_tcpabortonlinger
Número de vezes que um pacote Reset é enviado para reciclar rapidamente uma conexão no estado FIN_WAIT2 após a ativação da opção TCP Linger2.
kubeskoop_tcpext_tcpabortonclose
Número de vezes que um pacote Reset é enviado porque dados não lidos permanecem quando uma conexão TCP é fechada por motivos fora da máquina de estado.
kubeskoop_tcpext_tcpabortonmemory
Número de vezes que um pacote Reset é enviado para encerrar uma conexão devido à memória insuficiente acionada por tcp_check_oom na lógica que aloca tw_sock ou tcp_sock.
Número de pacotes Reset enviados para reciclar rapidamente uma conexão por meio de Reset quando a opção Linger ou Linger2 está ativada.
kubeskoop_tcpext_tcpackskippedsynrecv
Número de vezes que um socket no estado SYN_RECV não responde com um pacote ACK.
kubeskoop_tcpext_tcpackskippedpaws
Número de vezes que o mecanismo PAWS aciona uma correção, mas a limitação de taxa OOW restringe o envio do pacote ACK.
kubeskoop_tcp_estabresets
Número de vezes que as conexões TCP são fechadas anormalmente em um único Pod. Esta métrica conta apenas o resultado.
kubeskoop_tcp_outrsts
Número de pacotes Reset que o TCP envia em um único Pod.
Problemas de variação intermitente de latência de rede
A variação intermitente da latência de rede é o tipo de problema mais comum e mais difícil de localizar em ambientes nativos da cloud. Possui uma grande variedade de causas, e a latência também pode desencadear os três tipos de problemas descritos anteriormente. Em cenários de rede de contêineres, a latência de rede dentro de um nó geralmente é causada por um dos seguintes motivos:
Um processo em tempo real gerenciado pelo agendador RT é executado por muito tempo, o que causa filas longas ou processamento lento em processos de service ou threads de kernel de rede.
O processo faz chamadas externas lentas intermitentemente, como respostas lentas de disco em cloud ou aumentos intermitentes no RTT do RDS, o que retarda o processamento de solicitações.
Problemas de configuração do nó causam cargas desequilibradas em diferentes CPUs ou nós NUMA, e o sistema com carga pesada sofre paralizações.
Mecanismos stateful do kernel causam latência, como a operação conntrack confirm ou um grande número de sockets órfãos que afetam as consultas normais de sockets.
Para esse tipo de problema, embora pareça ser um problema de rede, a causa raiz geralmente está em outro lugar no sistema operacional. Monitore as seguintes métricas para restringir o escopo da solução de problemas:
|
Métrica |
Descrição |
|
kubeskoop_io_ioreadsyscall |
Número de operações de leitura do sistema de arquivos, como read e pread, executadas por um processo. |
|
kubeskoop_io_iowritesyscall |
Número de operações de gravação do sistema de arquivos, como write e pwrite, executadas por um processo. |
|
kubeskoop_io_ioreadbytes |
Número de bytes lidos por um processo do sistema de arquivos, geralmente de um dispositivo de bloco. |
|
kubeskoop_io_iowritebytes |
Número de bytes gravados por um processo no sistema de arquivos. |
|
kubeskoop_tcpext_tcptimeouts |
Número de retransmissões executadas quando um pacote SYN não recebe resposta. Esta métrica é acionada quando o estado CA não entra em recovery, loss ou disorder. |
|
kubeskoop_tcpsummary_tcpestablishedconn |
Número de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_tcpsummary_tcptimewaitconn |
Número de conexões TCP atualmente no estado TIME_WAIT. |
|
kubeskoop_tcpsummary_tcptxqueue |
Número total de bytes de pacotes na fila de envio de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_tcpsummary_tcprxqueue |
Número total de bytes de pacotes na fila de recebimento de conexões TCP atualmente no estado ESTABLISHED. |
|
kubeskoop_softnet_processed |
Número de pacotes processados por todas as CPUs em um único Pod a partir do backlog da CPU preenchido pela NIC. |
|
kubeskoop_softnet_dropped |
Número de pacotes descartados por todas as CPUs em um único Pod. |
Estudos de caso de clientes
Os casos a seguir mostram como alguns clientes de rede de contêineres usaram o ACK KubeSkoop para solucionar e analisar problemas complexos. Compare os sintomas para referência.
Caso 1: Problemas intermitentes de tempo limite de DNS
Sintomas
O Cliente A detectou uma anomalia: ocorreram tempos limite intermitentes de resolução de DNS. O service do cliente usa PHP e o CoreDNS está configurado como o service de DNS.
Processo de solução de problemas
Com base na descrição, a equipe comunicou-se com o cliente para obter os dados relacionados ao DNS do sistema de monitoramento do cliente.
-
A análise dos dados no intervalo de tempo dos erros identificou os seguintes problemas:
Dentro do intervalo de tempo do erro,
kubeskoop_udp_noportsaumentou em 1, e o valor geral da métrica é pequeno.kubeskoop_packetloss_totalaumentou em 1, e o número de pacotes descartados mudou ligeiramente.
O cliente relatou que o endereço DNS configurado pertence a um provedor de service na rede pública. Com base nas informações de monitoramento, a causa raiz dos erros do cliente é que as solicitações DNS têm resposta lenta: o pacote de resposta DNS chega após o tempo limite do espaço de usuário (user-space) ser acionado.
Caso 2: Falhas de conexão intermitentes em um aplicativo Java
Sintomas
O Cliente B detectou uma anomalia: o Tomcat ficou indisponível intermitentemente, e cada ocorrência durou cerca de 5 a 10 segundos.
Processo de solução de problemas
A análise de logs confirmou que o Java Runtime do cliente estava executando o GC quando o problema ocorreu.
Após a implantação do monitoramento do KubeSkoop, a métrica
kubeskoop_tcpext_listendropsaumentou significativamente no momento do problema.A análise concluiu que, quando o Java Runtime do cliente executava o GC, as solicitações eram processadas mais lentamente, o que retardava a liberação das solicitações. No entanto, a criação de novas solicitações não era limitada, e um grande número de conexões foi gerado. Isso preencheu o backlog do socket listen e causou um transbordamento, o que levou a um aumento em
kubeskoop_tcpext_listendrops.Nesse caso, o acúmulo de conexões do cliente durou pouco tempo e a capacidade de processamento em si era normal. Sugerimos que o cliente ajustasse os parâmetros do Tomcat, o que resolveu o problema.
Caso 3: Variação intermitente de latência de rede para um cliente
Sintomas
O Cliente C detectou uma anomalia: as solicitações entre o aplicativo do cliente e o Redis apresentaram intermitentemente um aumento no RTT, o que causou tempos limite de service. O problema não pôde ser reproduzido.
Processo de solução de problemas
A análise de logs mostrou que o tempo total de resposta das solicitações do Redis excedeu intermitentemente 300 ms para o cliente.
Após a implantação do KubeSkoop, o monitoramento mostrou que a métrica
kubeskoop_virtcmdlatency_latencyaumentou quando o problema ocorreu. Os buckets le (Level no monitoramento do Prometheus) com aumento foram 18 e 15. Após a conversão, duas chamadas de virtualização com alta latência ocorreram naquele momento: le 15 produziu latência superior a 36 ms e le 18 produziu latência superior a 200 ms.Como as chamadas de virtualização do kernel ocupam a CPU enquanto são executadas e não podem ser preemptadas, a latência intermitente do cliente foi causada por algumas chamadas de virtualização com tempo de execução muito longo durante a criação e exclusão em massa de Pods.
Caso 4: Falhas intermitentes de verificação de integridade no Ingress Nginx
Sintomas
As máquinas Ingress falharam intermitentemente nas verificações de integridade, o que foi acompanhado por falhas na solicitação de service.
Processo de solução de problemas
-
Após a implantação do monitoramento, a equipe descobriu que o problema envolvia alterações anormais em várias métricas.
kubeskoop_tcpsummary_tcprxqueueekubeskoop_tcpsummary_tcptxqueueaumentaram.kubeskoop_tcpext_tcptimeoutsaumentou.kubeskoop_tcpsummary_tcptimewaitconndiminuiu ekubeskoop_tcpsummary_tcpestablishedconnaumentou.
A análise confirmou que, no momento do problema, o kernel funcionava normalmente e as conexões eram estabelecidas normalmente, mas o processo se comportava de forma anômala ao processar os pacotes recebidos nos sockets e ao executar as operações reais de envio de pacotes. A equipe deduziu que o processo do usuário tinha um problema de agendamento ou limitação naquele momento.
Após a sugestão de verificar o monitoramento do Cgroup, o cliente descobriu que ocorreu CPU Throttled no momento do problema. Isso confirmou que o processo do usuário sofria falhas intermitentes de agendamento devido ao Cgroup.
Para obter mais informações, consulte Enable the CPU Burst performance optimization policy. Após configurar o recurso CPU Burst para o Ingress, esse tipo de problema foi resolvido.