Risolvere gli errori UpgradeFailed dovuti a fallimenti di evacuazione causati dai PDB.

Sommario

Questo articolo illustra come identificare e risolvere gli errori UpgradeFailed dovuti a mancate espulsioni causate dai Pod Disruption Budgets (PDB) che si verificano durante il tentativo di aggiornare un cluster Servizio Azure Kubernetes (AKS).

Prerequisiti

Questo articolo richiede l'interfaccia della riga di comando di Azure versione 2.67.0 o successiva. Per trovare il numero di versione, eseguire az --version. Se è necessario installare o aggiornare interfaccia della riga di comando di Azure, vedere Come installare il interfaccia della riga di comando di Azure.

Per informazioni più dettagliate sul processo di aggiornamento, vedere la sezione "Aggiornare un cluster di Servizio Azure Kubernetes (AKS)" in Aggiornare un cluster di Servizio Azure Kubernetes (AKS).

Sintomi

Un'operazione di aggiornamento di un cluster AKS (Azure Kubernetes Service) fallisce con uno dei seguenti messaggi di errore:

  • (UpgradeFailed) Lo svuotamento node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx non è riuscito durante la rimozione del pod <pod-name> con errore Troppe richieste. Questo errore è spesso causato da un Pod Disruption Budget (PDB) restrittivo. Vedete https://aka.ms/aks/debugdrainfailures. Errore originale: impossibile eliminare il pod poiché violerebbe il budget delle interruzioni del pod. Informazioni di debug PDB: <namespace>/<pod-name> bloccate da pdb <pdb-name> con 0 pod non pronti.

  • Codice: UpgradeFailed
    Messaggio: Il drenaggio del nodo aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx non è riuscito a rimuovere il pod <pod-name> a causa dell'errore Troppe Richieste. Questo errore è spesso causato da una policy PDB (Pod Disruption Budget) restrittiva. Vedete https://aka.ms/aks/debugdrainfailures. Errore originale: impossibile eliminare il pod poiché violerebbe il budget delle interruzioni del pod. Informazioni di debug PDB: <namespace>/<pod-name> bloccate da pdb <pdb-name> con 0 pod non pronti.

Causa

Questo errore si verifica se un pod è protetto dal criterio PDB (Pod Disruption Budget). In questa situazione, il pod si oppone allo svuotamento. Dopo diversi tentativi, l'operazione di aggiornamento ha esito negativo e il cluster o il pool di nodi rientra in uno Failed stato.

Controllare il valore della configurazione PDB: ALLOWED DISRUPTIONS. Il valore deve essere 1 o maggiore. Per ulteriori informazioni, vedere Pianificare la disponibilità usando i budget di interruzione dei pod. Ad esempio, è possibile controllare il carico di lavoro e il relativo PDB come indicato di seguito. È consigliabile osservare che la ALLOWED DISRUPTIONS colonna non consente alcuna interruzione. Se il ALLOWED DISRUPTIONS valore è 0, i pod non vengono rimossi e lo svuotamento dei nodi non riesce durante il processo di aggiornamento:

$ kubectl get deployments.apps nginx
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           62s

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7854ff8877-gbr4m   1/1     Running   0          68s
nginx-7854ff8877-gnltd   1/1     Running   0          68s

$ kubectl get pdb
NAME        MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
nginx-pdb   2               N/A               0                     24s

Puoi anche verificare se negli eventi di Kubernetes sono presenti voci usando il comando kubectl get events | grep -i drain. Un output simile mostra il messaggio "Eliminazione bloccata da un eccesso di richieste (di solito correlato a un pdb)":

$ kubectl get events | grep -i drain
LAST SEEN   TYPE      REASON                    OBJECT                                   MESSAGE
(...)
32m         Normal    Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Draining node: aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx
2m57s       Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
12m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
32m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
32m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
31m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>

Per risolvere questo problema, usare una delle soluzioni seguenti.

Soluzione 1: Abilitare lo svuotamento dei pod

  1. Modificare il PDB per abilitare lo svuotamento dei pod. In genere, l'interruzione consentita è controllata dal Min Available / Max unavailable parametro o Running pods / Replicas . Modificare il parametro Min Available / Max unavailable a livello di PDB o aumentare il numero di Running pods / Replicas per portare il valore Allowed Disruption a 1 o superiore.

  2. Prova nuovamente ad aggiornare il cluster AKS alla stessa versione che hai tentato di aggiornare in precedenza. Questo processo attiva una riconciliazione.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y
    

Soluzione 2: Eseguire il backup, eliminare e ridistribuire il database PDB

Nota

Usare questa soluzione se la modifica della risorsa PDB non è un'opzione valida.

  1. Eseguire il backup dei PDB eseguendo il comando seguente:

    kubectl get pdb <pdb-name> -n <pdb-namespace> -o yaml > pdb-name-backup.yamle

  2. Eliminare il PDB eseguendo il comando seguente:

    kubectl delete pdb <pdb-name> -n <pdb-namespace>

  3. Al termine del nuovo tentativo di aggiornamento, ridistribuire il PDB applicando il file di backup usando il comando seguente:

    kubectl apply -f pdb-name-backup.yaml.

  4. Provate ad aggiornare nuovamente il cluster AKS alla stessa versione a cui si era tentato di aggiornarlo precedentemente. Questo processo attiva una riconciliazione.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y
    

Soluzione 3: Eliminare i pod che non è possibile svuotare o ridimensionare il carico di lavoro fino a zero

  1. Eliminare i pod che non è possibile svuotare.

Nota

Se un oggetto Deployment o StatefulSet crea i pod, un oggetto ReplicaSet li controlla. Se è così, potrebbe essere necessario eliminare o portare a zero il numero di repliche del carico di lavoro per il Deployment o lo StatefulSet. Prima di apportare questa modifica, eseguire il backup della risorsa eseguendo: kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yaml.

  1. Per ridurre il carico di lavoro, usare kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>.

  2. Prova nuovamente ad aggiornare il cluster AKS alla stessa versione che hai tentato di aggiornare in precedenza. Questo processo attiva una riconciliazione.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y