Résoudre les erreurs de type "UpgradeFailed" en raison d’échecs d’éviction causés par des PDBs

Résumé

Cet article explique comment identifier et résoudre les erreurs UpgradeFailed dues à des échecs d’éviction causés par des budgets de perturbation de pod (PDB) qui surviennent lorsque vous tentez de mettre à niveau un cluster Azure Kubernetes Service (AKS).

Prerequisites

Cet article nécessite Azure CLI version 2.67.0 ou une version ultérieure. Pour rechercher le numéro de version, exécutez az --version. Si vous devez installer ou mettre à niveau Azure CLI, consultez How to install the Azure CLI.

Pour plus d’informations sur le processus de mise à niveau, consultez la section « Mettre à niveau un cluster AKS » dans Mettre à niveau un cluster Azure Kubernetes Service (AKS).

Tip

Avant de commencer une mise à niveau AKS, exécutez la vérification de préparation de la mise à niveau dans le portail Azure :

Cluster> AKSParamètres>Améliorations>Version de mise à niveau

Après avoir sélectionné la version de Kubernetes cible, sélectionnez Vérifier en regard de La préparation à la mise à niveau. Cette pré-validation peut identifier les bloqueurs de mise à niveau potentiels, y compris les configurations PDB (Pod Disruption Budget) susceptibles d’empêcher le drainage de nœud réussi pendant la mise à niveau.

Symptômes

Une opération de mise à niveau du cluster AKS échoue avec l’un des messages d’erreur suivants :

  • (Échec de la mise à niveau) Échec du drainage node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx lors de l’échec de la suppression du pod <pod-name> avec une erreur Trop de requêtes. Cette erreur est souvent due à une stratégie PDB (Pod Disruption Budget) restrictive. Consultez l’article https://aka.ms/aks/debugdrainfailures. Erreur originale : Impossible d'évincer le pod car cela violerait le budget d'interruption du pod. Informations de débogage PDB : <namespace>/<pod-name> bloquées par PDB <pdb-name> avec 0 pods non prêts.

  • Code : Échec de la mise à niveau
    Message : Échec du drainage du nœud aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx lors de l’éviction du pod <pod-name> avec une erreur Trop de requêtes. Cette erreur est souvent due à une stratégie PDB (Pod Disruption Budget) restrictive. Consultez l’article https://aka.ms/aks/debugdrainfailures. Erreur originale : Impossible d'évincer le pod car cela violerait le budget d'interruption du pod. Informations de débogage PDB : <namespace>/<pod-name> bloquées par PDB <pdb-name> avec 0 pods non prêts.

Cause

Cette erreur se produit si un pod est protégé par la stratégie PDB (Pod Disruption Budget). Dans cette situation, le pod résiste à être drainé. Après plusieurs tentatives, l’opération de mise à niveau échoue et le cluster ou le pool de nœuds tombe dans un Failed état.

Vérifiez la configuration PDB : ALLOWED DISRUPTIONS valeur. La valeur doit être 1 ou supérieure. Pour plus d'informations, consultez Planifier la disponibilité à l’aide des budgets d'interruption de pods. Par exemple, vous pouvez vérifier la charge de travail et sa base de données PDB comme suit. Vous devez noter que la ALLOWED DISRUPTIONS colonne ne permet aucune perturbation. Si la valeur de ALLOWED DISRUPTIONS est 0, les pods ne sont pas expulsés et le drainage du nœud échoue pendant le processus de mise à niveau :

$ 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

Vous pouvez également rechercher toutes les entrées dans les événements Kubernetes à l’aide de la commande kubectl get events | grep -i drain. Une sortie similaire montre le message « Éviction bloquée par trop de requêtes (généralement 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>

Pour résoudre ce problème, appliquez l’une des solutions suivantes.

Solution 1 : Activer les pods pour drainer

  1. Ajustez la base de données PDB pour activer le drainage des pods. En règle générale, la perturbation autorisée est contrôlée par le paramètre Min Available / Max unavailable ou Running pods / Replicas. Modifiez le paramètre Min Available / Max unavailable au niveau du PDB ou augmentez le nombre de Running pods / Replicas pour porter la valeur d’interruption autorisée à 1 ou plus.

  2. Réessayez de mettre à niveau le cluster AKS vers la même version que celle que vous avez tenté de mettre à niveau précédemment. Ce processus déclenche une réconciliation.

    $ 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
    

Solution 2 : Sauvegarder, supprimer et redéployer la base de données PDB

Remarque

Utilisez cette solution si la modification de la ressource PDB n’est pas une option viable.

  1. Sauvegardez les bases de données en exécutant la commande suivante :

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

  2. Supprimez la base de données PDB en exécutant la commande suivante :

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

  3. Une fois la nouvelle tentative de mise à niveau terminée, redéployez la base de données PDB en appliquant le fichier de sauvegarde à l’aide de la commande suivante :

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

  4. Essayez de mettre à niveau le cluster AKS vers la même version que celle que vous avez tenté de mettre à niveau précédemment. Ce processus déclenche une réconciliation.

    $ 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
    

Solution 3 : Supprimer les pods que vous ne pouvez pas vider ou mettre à l’échelle la charge de travail jusqu’à zéro

  1. Supprimez les pods que vous ne pouvez pas drainer.

Remarque

Si un Deployment ou un StatefulSet crée des pods, un ReplicaSet les gère. Si c’est le cas, vous devrez peut-être supprimer la charge de travail ou ramener à zéro le nombre de réplicas du déploiement ou du StatefulSet. Avant d’apporter cette modification, sauvegardez la ressource en exécutant : kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yaml.

  1. Pour effectuer un scale-down de la charge de travail, utilisez kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>.

  2. Réessayez de mettre à niveau le cluster AKS vers la même version que celle que vous avez tenté de mettre à niveau précédemment. Ce processus déclenche une réconciliation.

    $ 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