Condividi tramite


Risolvere i problemi relativi a server API e etcd in servizio Azure Kubernetes

Questa guida è progettata per identificare e risolvere eventuali problemi improbabili che potrebbero verificarsi all'interno del server API in distribuzioni di Microsoft servizio Azure Kubernetes (AKS) di grandi dimensioni.

Microsoft ha testato l'affidabilità e le prestazioni del server API su una scala di 5.000 nodi e 200.000 pod. Il cluster che contiene il server API ha la possibilità di aumentare e distribuire automaticamente gli obiettivi del livello di servizio di Kubernetes. Se si riscontrano latenze elevate o timeout, è probabile che si verifichi una perdita di risorse nella directory distribuita etc (etcd) o che un client che causa un'eccessiva perdita di API.

Prerequisiti

  • Interfaccia della riga di comando di Azure.

  • Lo strumento kubectl kubernetes. Per installare kubectl usando l'interfaccia della riga di comando di Azure, eseguire il comando az aks install-cli .

  • Log di diagnostica del servizio Azure Kubernetes (in particolare eventi kube-audit) abilitati e inviati a un'area di lavoro Log Analytics. Per determinare se i log vengono raccolti usando la modalità di diagnostica specifica della risorsa o di Azure, controllare il pannello Impostazioni di diagnostica nella portale di Azure.

  • Il livello Standard per i cluster del servizio Azure Kubernetes. Se si usa il livello Gratuito, il server API e etcd contengono risorse limitate. I cluster del servizio Azure Kubernetes nel livello gratuito non offrono disponibilità elevata. Questa è spesso la causa radice del server API e dei problemi etcd.

  • Plug-in kubectl-aks per l'esecuzione di comandi direttamente nei nodi del servizio Azure Kubernetes senza usare il piano di controllo Kubernetes.

Controlli integrità di base

  • Eventi di Integrità risorse

    Il servizio Azure Kubernetes fornisce eventi di integrità delle risorse per tempi di inattività critici dei componenti. Prima di procedere, assicurarsi che non siano presenti eventi critici segnalati in Integrità risorse.

    Screenshot che mostra un evento di integrità delle risorse.

  • Diagnostica e risoluzione dei problemi

    Il servizio Azure Kubernetes offre una categoria dedicata per la disponibilità e le prestazioni del piano di controllo e del cluster.

    Screenshot che mostra la categoria

Sintomi

La tabella seguente illustra i sintomi comuni degli errori del server API:

Sintomo Descrizione
Timeout dal server API Timeout frequenti che superano le garanzie del contratto di servizio del server API del servizio Azure Kubernetes. Ad esempio, kubectl i comandi hanno un timeout.
Latenze elevate Latenze elevate che rendono i contratti di servizio Kubernetes non riuscita. Ad esempio, il kubectl comando richiede più di 30 secondi per elencare i pod.
Pod del server API con CrashLoopbackOff stato o errori di chiamata webhook Verificare che non sia presente alcun webhook di ammissione personalizzato (ad esempio il motore dei criteri Kyverno ) che blocca le chiamate al server API.

Elenco di controllo per la risoluzione dei problemi

Se si verificano tempi di latenza elevati, seguire questa procedura per individuare il client che causa l'errore e i tipi di chiamate API che hanno esito negativo.

Passaggio 1: Identificare gli agenti utente principali in base al numero di richieste

Per identificare i client che generano la maggior parte delle richieste (e potenzialmente il maggior carico del server API), eseguire una query simile al codice seguente. La query seguente elenca i primi 10 agenti utente in base al numero di richieste del server API inviate.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_

Note

Se la query non restituisce risultati, è possibile che sia stata selezionata la tabella errata per eseguire query sui log di diagnostica. In modalità specifica della risorsa, i dati sono scritti in singole tabelle a seconda della categoria della risorsa. I log di diagnostica vengono scritti nella AKSAudit tabella. In modalità diagnostica di Azure tutti i dati vengono scritti nella AzureDiagnostics tabella. Per altre informazioni, vedere Log delle risorse di Azure.

Anche se è utile sapere quali client generano il volume di richieste più elevato, il volume di richieste elevato da solo potrebbe non essere una causa di preoccupazione. Un indicatore migliore del carico effettivo generato da ogni client nel server API è la latenza di risposta che riscontrano.

Passaggio 2: Identificare e creare un grafico della latenza media delle richieste del server API per agente utente

Per identificare la latenza media delle richieste del server API per agente utente come tracciato in un grafico temporale, eseguire la query seguente:

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

Questa query è un completamento della query nella sezione "Identificare gli agenti utente principali in base al numero di richieste ". Potrebbe fornire maggiori informazioni sul carico effettivo generato da ogni agente utente nel corso del tempo.

Suggerimento

Analizzando questi dati, è possibile identificare modelli e anomalie che possono indicare problemi nel cluster o nelle applicazioni del servizio Azure Kubernetes. Ad esempio, è possibile notare che un determinato utente riscontra una latenza elevata. Questo scenario può indicare il tipo di chiamate API che causano un carico eccessivo nel server API o etcd.

Passaggio 3: Identificare le chiamate API non valido per un determinato agente utente

Eseguire la query seguente per tabulare la latenza del 99° percentile (P99) delle chiamate API tra diversi tipi di risorse per un determinato client:

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

I risultati di questa query possono essere utili per identificare i tipi di chiamate API che hanno esito negativo per i contratti di servizio Kubernetes upstream. Nella maggior parte dei casi, un client offensivo LIST potrebbe effettuare troppe chiamate su un set elevato di oggetti o oggetti troppo grandi. Sfortunatamente, non sono disponibili limiti di scalabilità rigidi per guidare gli utenti sulla scalabilità del server API. I limiti di scalabilità del server API o etcd dipendono da vari fattori illustrati in Soglie di scalabilità di Kubernetes.

Causa 1: una regola di rete blocca il traffico dai nodi agente al server API

Una regola di rete può bloccare il traffico tra i nodi dell'agente e il server API.

Per verificare se i criteri di rete configurati in modo errato bloccano la comunicazione tra il server API e i nodi agente, eseguire i comandi kubectl-aks seguenti:

kubectl aks config import \
    --subscription <mySubscriptionID> \
    --resource-group <myResourceGroup> \
    --cluster-name <myAKSCluster>

kubectl aks check-apiserver-connectivity --node <myNode>

Il comando config import recupera le informazioni sul set di scalabilità di macchine virtuali per tutti i nodi del cluster. Il comando check-apiserver-connectivity usa quindi queste informazioni per verificare la connettività di rete tra il server API e un nodo specificato, in particolare per l'istanza del set di scalabilità sottostante.

Note

Se l'output del check-apiserver-connectivity comando contiene il Connectivity check: succeeded messaggio, la connettività di rete non viene implementata.

Soluzione 1: Correggere i criteri di rete per rimuovere il blocco del traffico

Se l'output del comando indica che si è verificato un errore di connessione, riconfigurare i criteri di rete in modo che non blocchi inutilmente il traffico tra i nodi dell'agente e il server API.

Causa 2: un client offensivo perde oggetti etcd e comporta un rallentamento di etcd

Un problema comune è la creazione continua di oggetti senza eliminare quelli inutilizzati nel database etcd. Ciò può causare problemi di prestazioni quando etcd gestisce troppi oggetti (più di 10.000) di qualsiasi tipo. Un rapido aumento delle modifiche apportate a tali oggetti potrebbe anche causare il superamento delle dimensioni del database etcd (4 gigabyte per impostazione predefinita).

Per controllare l'utilizzo del database etcd, passare a Diagnosticare e risolvere i problemi nella portale di Azure. Eseguire lo strumento di diagnosi dei problemi di disponibilità etcd cercando "etcd" nella casella di ricerca. Lo strumento di diagnosi mostra la suddivisione dell'utilizzo e le dimensioni totali del database.

portale di Azure screenshot che mostra la diagnosi della disponibilità Etcd per servizio Azure Kubernetes (servizio Azure Kubernetes).

Se si vuole solo un modo rapido per visualizzare le dimensioni correnti del database etcd in byte, eseguire il comando seguente:

kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"

Note

Il nome della metrica nel comando precedente è diverso per le diverse versioni di Kubernetes. Per Kubernetes 1.25 e versioni precedenti, usare etcd_db_total_size_in_bytes. Per Kubernetes da 1.26 a 1.28, usare apiserver_storage_db_total_size_in_bytes.

Soluzione 2: Definire quote per la creazione di oggetti, eliminare oggetti o limitare la durata degli oggetti in etcd

Per evitare che etcd raggiunga la capacità e causi tempi di inattività del cluster, è possibile limitare il numero massimo di risorse create. È anche possibile rallentare il numero di revisioni generate per le istanze delle risorse. Per limitare il numero di oggetti che è possibile creare, è possibile definire le quote degli oggetti.

Se sono stati identificati oggetti che non sono più in uso, ma che richiedono risorse, è consigliabile eliminarli. Ad esempio, è possibile eliminare i processi completati per liberare spazio:

kubectl delete jobs --field-selector status.successful=1

Per gli oggetti che supportano la pulizia automatica, è possibile impostare valori TTL (Time to Live) per limitare la durata di questi oggetti. È anche possibile etichettare gli oggetti in modo da poter eliminare in blocco tutti gli oggetti di un tipo specifico usando selettori di etichetta. Se si stabiliscono riferimenti di proprietario tra gli oggetti, tutti gli oggetti dipendenti vengono eliminati automaticamente dopo l'eliminazione dell'oggetto padre.

Causa 3: un client offensivo effettua chiamate LIST o PUT eccessive

Se si determina che etcd non è sottoposto a overload con troppi oggetti, un client offensivo potrebbe eseguire troppe LIST chiamate o PUT al server API.

Soluzione 3a: Ottimizzare il modello di chiamata API

Prendere in considerazione l'ottimizzazione del modello di chiamata API del client per ridurre la pressione sul piano di controllo.

Soluzione 3b: Limitare un client che sovraccarica il piano di controllo

Se non è possibile ottimizzare il client, è possibile usare la funzionalità Priorità e equità in Kubernetes per limitare il client. Questa funzionalità consente di mantenere l'integrità del piano di controllo e impedire che altre applicazioni non riescano.

La procedura seguente illustra come limitare un'API LIST Pods di un client in errore impostata su cinque chiamate simultanee:

  1. Creare un oggetto FlowSchema che corrisponda al modello di chiamata API del client che causa l'errore:

    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 
    
  2. Creare una configurazione con priorità inferiore per limitare le chiamate API non valida del client:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: PriorityLevelConfiguration
    metadata:
      name: very-low-priority
    spec:
      limited:
        assuredConcurrencyShares: 5
        limitResponse:
          type: Reject
      type: Limited
    
  3. Osservare la chiamata limitata nelle metriche del server API.

    kubectl get --raw /metrics | grep "restrict-bad-client"
    

Causa 4: un webhook personalizzato potrebbe causare un deadlock nei pod del server API

Un webhook personalizzato, ad esempio Kyverno, potrebbe causare un deadlock nei pod del server API.

Controllare gli eventi correlati al server API. Potrebbero essere visualizzati messaggi di evento simili al testo seguente:

Errore interno: impossibile chiamare il webhook "mutate.kyverno.svc-fail": failed to call webhook: Post "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @->/tunnel-uds/proxysocket: write: broken pipe

In questo esempio, la convalida del webhook blocca la creazione di alcuni oggetti server API. Poiché questo scenario può verificarsi durante il bootstrap, non è possibile creare il server API e i pod Konnectivity. Di conseguenza, il webhook non può connettersi a tali pod. Questa sequenza di eventi causa il deadlock e il messaggio di errore.

Soluzione 4: Eliminare le configurazioni del webhook

Per risolvere questo problema, eliminare le configurazioni di webhook di convalida e modifica. Per eliminare queste configurazioni webhook in Kyverno, vedere l'articolo sulla risoluzione dei problemi di Kyverno.

Dichiarazione di non responsabilità di contatti di terze parti

Microsoft fornisce informazioni di contatto di terze parti per aiutarti a trovare ulteriori informazioni su questo argomento. Queste informazioni di contatto sono soggette a modifica senza preavviso. Microsoft non garantisce l'accuratezza delle informazioni di contatto di terze parti.

Dichiarazione di non responsabilità sulle informazioni di terze parti

I prodotti di terzi citati in questo articolo sono prodotti da società indipendenti da Microsoft. Microsoft non rilascia alcuna garanzia implicita o esplicita relativa alle prestazioni o all'affidabilità di tali prodotti

Contattaci per ricevere assistenza

In caso di domande o bisogno di assistenza, creare una richiesta di supporto tecnico oppure formula una domanda nel Supporto della community di Azure. È possibile anche inviare un feedback sul prodotto al feedback della community di Azure.