Solucionar problemas de servidor de API e etc. nos Serviços de Kubernetes do Azure
Este guia foi projetado para ajudar você a identificar e resolve quaisquer problemas improváveis que você possa encontrar no servidor de API em grandes implantações do AKS (Serviços de Kubernetes do Microsoft Azure).
A Microsoft testou a confiabilidade e o desempenho do servidor de API em uma escala de 5.000 nós e 200.000 pods. O cluster que contém o servidor de API tem a capacidade de dimensionar e entregar automaticamente os SLOs (Objetivos de Nível de Serviço) do Kubernetes. Se você tiver altas latências ou tempo limite, provavelmente é porque há um vazamento de recursos no diretório distribuído etc
(etcd), ou um cliente ofensivo tem chamadas excessivas de API.
Pré-requisitos
A ferramenta kubernetes kubectl . Para instalar o kubectl usando a CLI do Azure, execute o comando az aks install-cli .
O AKS diagnóstico logs (especificamente, eventos de auditoria kube) habilitados e enviados para um workspace do Log Analytics. Para determinar se os logs são coletados usando o modo de diagnóstico específico do recurso ou do Azure, marcar a folha Configurações de Diagnóstico no portal do Azure.
A camada Standard para clusters AKS. Se você estiver usando a camada Livre, o servidor de API e etc. conterão recursos limitados. Os clusters do AKS na camada Livre não fornecem alta disponibilidade. Geralmente, essa é a causa raiz de problemas de servidor de API e etc..
O plug-in kubectl-aks para executar comandos diretamente em nós AKS sem usar o plano de controle kubernetes.
Sintomas
A tabela a seguir descreve os sintomas comuns de falhas do servidor de API:
Sintoma | Descrição |
---|---|
Tempo limite do servidor de API | Tempo limite frequente que estão além das garantias no SLA do servidor de API do AKS. Por exemplo, kubectl comanda o tempo limite. |
Altas latências | Latências altas que fazem com que os SLOs do Kubernetes falhem. Por exemplo, o kubectl comando leva mais de 30 segundos para listar pods. |
Pod do servidor de API no CrashLoopbackOff status ou enfrentando falhas de chamada do webhook |
Verifique se você não tem nenhum webhook de admissão personalizado (como o mecanismo de política kyverno ) que está bloqueando as chamadas para o servidor de API. |
Lista de verificação de solução de problemas
Se você estiver enfrentando tempos de alta latência, siga estas etapas para identificar o cliente infrator e os tipos de chamadas de API que falham.
Etapa 1: identificar os principais agentes de usuário pelo número de solicitações
Para identificar quais clientes geram mais solicitações (e potencialmente a maior carga de servidor de API), execute uma consulta que se assemelha ao código a seguir. A consulta a seguir lista os 10 principais agentes de usuário pelo número de solicitações de servidor de API enviadas.
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_
Observação
Se a consulta não retornar resultados, talvez você tenha selecionado a tabela errada para consultar diagnóstico logs. No modo específico do recurso, os dados são gravados em tabelas individuais, dependendo da categoria do recurso. Os logs de diagnóstico são gravados na AKSAudit
tabela. No modo diagnóstico do Azure, todos os dados são gravados na AzureDiagnostics
tabela. Para obter mais informações, confira Logs de recursos do Azure.
Embora seja útil saber quais clientes geram o maior volume de solicitação, o volume de solicitação alto por si só pode não ser motivo de preocupação. Um indicador melhor da carga real que cada cliente gera no servidor de API é a latência de resposta que eles experimentam.
Etapa 2: identificar e mapear a latência média de solicitações de servidor de API por agente de usuário
Para identificar a latência média das solicitações de servidor de API por agente de usuário conforme plotado em um gráfico de tempo, execute a seguinte consulta:
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize avg(latency) by UserAgent, bin(start_time, 5m)
| render timechart
Essa consulta é um acompanhamento da consulta na seção "Identificar os principais agentes de usuário pelo número de solicitações ". Ele pode fornecer mais informações sobre a carga real gerada por cada agente de usuário ao longo do tempo.
Dica
Analisando esses dados, você pode identificar padrões e anomalias que podem indicar problemas em seu cluster ou aplicativos AKS. Por exemplo, você pode notar que um determinado usuário está experimentando alta latência. Esse cenário pode indicar o tipo de chamadas de API que estão causando carga excessiva no servidor de API ou etc.
Etapa 3: identificar chamadas de API incorretas para um determinado agente de usuário
Execute a consulta a seguir para tabulizar a latência do 99º percentil (P99) de chamadas de API em diferentes tipos de recursos para um determinado cliente:
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend HttpMethod = Verb
| extend Resource = tostring(ObjectRef.resource)
| where UserAgent == "DUMMYUSERAGENT" // Filter by name of the useragent you are interested in
| where Resource != ""
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize p99latency=percentile(latency, 99) by HttpMethod, Resource
| render table
Os resultados dessa consulta podem ser úteis para identificar os tipos de chamadas de API que falham nos SLOs upstream Kubernetes. Na maioria dos casos, um cliente ofensivo pode estar fazendo muitas LIST
chamadas em um grande conjunto de objetos ou objetos que são muito grandes. Infelizmente, nenhum limite de escalabilidade difícil está disponível para orientar os usuários sobre a escalabilidade do servidor de API. Os limites de escalabilidade do servidor de API ou etc., dependem de vários fatores explicados nos limites de escalabilidade do Kubernetes.
Causa 1: uma regra de rede bloqueia o tráfego de nós de agente para o servidor de API
Uma regra de rede pode bloquear o tráfego entre os nós do agente e o servidor de API.
Para verificar se uma política de rede configurada incorreta está bloqueando a comunicação entre o servidor de API e os nós do agente, execute os seguintes comandos kubectl-aks :
kubectl aks config import \
--subscription <mySubscriptionID> \
--resource-group <myResourceGroup> \
--cluster-name <myAKSCluster>
kubectl aks check-apiserver-connectivity --node <myNode>
O comando de importação de configuração recupera as informações do Conjunto de Dimensionamento de Máquinas Virtuais para todos os nós do cluster. Em seguida, o comando marcar-apiserver-conectividade usa essas informações para verificar a conectividade de rede entre o servidor de API e um nó especificado, especificamente para sua instância de conjunto de escala subjacente.
Observação
Se a saída do check-apiserver-connectivity
comando contiver a Connectivity check: succeeded
mensagem, a conectividade de rede não serámpedida.
Solução 1: corrigir a política de rede para remover o bloqueio de tráfego
Se a saída de comando indicar que ocorreu uma falha de conexão, reconfigure a política de rede para que ela não bloqueie desnecessariamente o tráfego entre os nós do agente e o servidor de API.
Causa 2: um cliente ofensivo vaza objetos etc. e resulta em uma desaceleração de etcd
Um problema comum é criar objetos continuamente sem excluir os não utilizados no banco de dados etcd. Isso pode causar problemas de desempenho quando o etcd lida com muitos objetos (mais de 10.000) de qualquer tipo. Um aumento rápido de alterações nesses objetos também pode fazer com que o tamanho do banco de dados etcd (4 gigabytes por padrão) seja excedido.
Para marcar o uso de banco de dados etcd, navegue até Diagnosticar e Resolver problemas no portal do Azure. Execute a ferramenta de diagnóstico de problemas de disponibilidade etcd pesquisando "etcd" na caixa de pesquisa. A ferramenta de diagnóstico mostra a divisão de uso e o tamanho total do banco de dados.
Se você quiser apenas uma maneira rápida de exibir o tamanho atual do banco de dados etcd em bytes, execute o seguinte comando:
kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"
Observação
O nome da métrica no comando anterior é diferente para versões diferentes do Kubernetes. Para Kubernetes 1.25 e anterior, use etcd_db_total_size_in_bytes
. Para Kubernetes 1.26 a 1.28, use apiserver_storage_db_total_size_in_bytes
.
Solução 2: definir cotas para criação de objeto, excluir objetos ou limitar o tempo de vida do objeto em etcd
Para impedir que etcd alcance a capacidade e cause tempo de inatividade do cluster, você pode limitar o número máximo de recursos criados. Você também pode reduzir o número de revisões geradas para instâncias de recurso. Para limitar o número de objetos que podem ser criados, você pode definir cotas de objeto.
Se você identificou objetos que não estão mais em uso, mas estão ocupando recursos, considere excluí-los. Por exemplo, você pode excluir trabalhos concluídos para liberar espaço:
kubectl delete jobs --field-selector status.successful=1
Para objetos que dão suporte à limpeza automática, você pode definir valores de TTL (Time to Live) para limitar o tempo de vida desses objetos. Você também pode rotular seus objetos para que você possa excluir em massa todos os objetos de um tipo específico usando seletores de rótulo. Se você estabelecer referências de proprietário entre objetos, todos os objetos dependentes serão excluídos automaticamente após a exclusão do objeto pai.
Causa 3: um cliente ofensivo faz chamadas excessivas de LIST ou PUT
Se você determinar que o etcd não está sobrecarregado com muitos objetos, um cliente ofensivo pode estar fazendo muitas LIST
ou PUT
chamadas para o servidor de API.
Solução 3a: ajustar seu padrão de chamada de API
Considere ajustar o padrão de chamada de API do cliente para reduzir a pressão no plano de controle.
Solução 3b: limitar um cliente que está sobrecarregando o plano de controle
Se você não conseguir ajustar o cliente, poderá usar o recurso Prioridade e Justiça no Kubernetes para limitar o cliente. Esse recurso pode ajudar a preservar a integridade do plano de controle e evitar que outros aplicativos falhem.
O procedimento a seguir mostra como limitar a API list pods de um cliente ofensivo definida como cinco chamadas simultâneas:
Create um FlowSchema que corresponda ao padrão de chamada de API do cliente ofensivo:
apiVersion: flowcontrol.apiserver.k8s.io/v1beta2 kind: FlowSchema metadata: name: restrict-bad-client spec: priorityLevelConfiguration: name: very-low-priority distinguisherMethod: type: ByUser rules: - resourceRules: - apiGroups: [""] namespaces: ["default"] resources: ["pods"] verbs: ["list"] subjects: - kind: ServiceAccount serviceAccount: name: bad-client-account namespace: default
Create uma configuração de menor prioridade para limitar as chamadas de API incorretas do cliente:
apiVersion: flowcontrol.apiserver.k8s.io/v1beta2 kind: PriorityLevelConfiguration metadata: name: very-low-priority spec: limited: assuredConcurrencyShares: 5 limitResponse: type: Reject type: Limited
Observe a chamada limitada nas métricas do servidor de API.
kubectl get --raw /metrics | grep "restrict-bad-client"
Causa 4: um webhook personalizado pode causar um impasse em pods de servidor de API
Um webhook personalizado, como Kyverno, pode estar causando um impasse nos pods do servidor de API.
Verifique os eventos relacionados ao servidor de API. Você pode ver mensagens de evento que se assemelham ao seguinte texto:
Erro interno: falha ao chamar webhook de "mutate.kyverno.svc-fail": falha ao chamar webhook: Post "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @->/tunnel-uds/proxysocket: write: broken pipe
Neste exemplo, o webhook de validação está bloqueando a criação de alguns objetos de servidor de API. Como esse cenário pode ocorrer durante o tempo de inicialização, os pods de API e Konnectivity não podem ser criados. Portanto, o webhook não pode se conectar a esses pods. Essa sequência de eventos causa o impasse e a mensagem de erro.
Solução 4: excluir configurações de webhook
Para corrigir esse problema, exclua as configurações de webhook validando e mutando. Para excluir essas configurações de webhook no Kyverno, examine o artigo de solução de problemas do Kyverno.
Aviso de isenção de responsabilidade para contatos de terceiros
A Microsoft fornece informações de contato de terceiros para ajudá-lo a encontrar informações adicionais sobre esse tópico. Essas informações de contato podem ser alteradas sem aviso prévio. A Microsoft não garante a precisão das informações de contato de terceiros.
Aviso de isenção de responsabilidade para informações de terceiros
Os produtos de terceiros mencionados neste artigo são produzidos por empresas independentes da Microsoft. A Microsoft não oferece nenhuma garantia, implícita ou não, do desempenho ou da confiabilidade desses produtos.
Entre em contato conosco para obter ajuda
Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.