Solución de problemas de errores UpgradeFailed debido a fallas de desalojo causadas por PDBs

Resumen

En este artículo se explica cómo identificar y resolver UpgradeFailed errores debido a errores de expulsión causados por presupuestos de interrupciones de pods (PDB) que se producen al intentar actualizar un clúster de Azure Kubernetes Service (AKS).

Requisitos previos

En este artículo se requiere la versión 2.67.0 de la CLI de Azure o una versión posterior. Para buscar el número de versión, ejecute az --version. Si necesita instalar o actualizar CLI de Azure, consulte Cómo instalar el CLI de Azure.

Para más información sobre el proceso de actualización, consulte la sección "Actualización de un clúster de AKS" en Actualización de un clúster de Azure Kubernetes Service (AKS).

Sugerencia

Antes de iniciar una actualización de AKS, ejecute la comprobación de preparación de actualizaciones en el portal de Azure:

Clúster de AKS>Configuración>Actualizaciones>Versión de la actualización

Después de seleccionar la versión de Kubernetes de destino, seleccione Comprobar junto a Preparación para la actualización. Esta validación previa puede identificar posibles obstáculos para la actualización, incluidas las configuraciones de Pod Disruption Budget (PDB) que podrían impedir drenar correctamente el nodo durante la actualización.

Síntomas

Se produce un error en una operación de actualización del clúster de AKS con uno de los siguientes mensajes de error:

  • (UpgradeFailed) El drenaje node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx falló al expulsar el pod <pod-name> con un error de 'demasiadas solicitudes'. Este error suele deberse a una directiva restrictiva de presupuesto de interrupción del pod (PDB). Vea https://aka.ms/aks/debugdrainfailures. Error original: No se puede expulsar el pod, puesto que infringiría el presupuesto de interrupción del pod. Información de depuración de PDB: <namespace>/<pod-name> bloqueada por pdb <pdb-name> con 0 pods no leídos.

  • Código: UpgradeFailed
    Mensaje: Error en el nodo aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx de purga al expulsar el pod <pod-name> con un error de demasiadas solicitudes. Este error suele deberse a una directiva restrictiva de presupuesto de interrupción del pod (PDB). Vea https://aka.ms/aks/debugdrainfailures. Error original: No se puede expulsar el pod, puesto que infringiría el presupuesto de interrupción del pod. Información de depuración de PDB: <namespace>/<pod-name> bloqueada por pdb <pdb-name> con 0 pods no leídos.

Causa

Este error se produce si un pod está protegido por la directiva presupuesto de interrupciones del pod (PDB). En esta situación, el pod se resiste a ser drenado. Después de varios intentos, se produce un error en la operación de actualización y el clúster o grupo de nodos entra en un Failed estado.

Compruebe el ajuste de PDB: valor ALLOWED DISRUPTIONS. El valor debe ser 1 o mayor. Para obtener más información, consulte Planear la disponibilidad mediante presupuestos de interrupciones de pod. Por ejemplo, puede comprobar la carga de trabajo y su PDB de la siguiente manera. Debería observar que la ALLOWED DISRUPTIONS columna no permite ninguna interrupción. Si el valor ALLOWED DISRUPTIONS es 0, los pods no se expulsan y se produce un error en el drenaje de nodos durante el proceso de actualización.

$ 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

También puede comprobar si hay entradas en eventos de Kubernetes mediante el comando kubectl get events | grep -i drain. Una salida similar muestra el mensaje "Expulsión bloqueada por demasiadas solicitudes (normalmente 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>

Para resolver el problema, utilice una de las siguientes soluciones.

Solución 1: Habilitar el drenaje de los pods

  1. Ajuste la PDB para habilitar la purga de pods. Por lo general, la interrupción permitida se controla mediante el Min Available / Max unavailable parámetro o Running pods / Replicas . Modifique el parámetro Min Available / Max unavailable a nivel de PDB o aumente el número de Running pods / Replicas para elevar el valor de Interrupción permitida a 1 o más.

  2. Inténtelo de nuevo para actualizar el clúster de AKS a la misma versión a la que intentó actualizar previamente. Este proceso desencadena una conciliación.

    $ 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
    

Solución 2: Copia de seguridad, eliminación y reimplementación de PDB

Nota:

Use esta solución si la edición del recurso PDB no es una opción viable.

  1. Realice una copia de seguridad de los archivos PDB mediante la ejecución del comando siguiente:

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

  2. Para eliminar la PDB, ejecute el siguiente comando:

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

  3. Una vez finalizado el nuevo intento de actualización, vuelva a implementar la PDB aplicando el archivo de copia de seguridad mediante el siguiente comando:

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

  4. Intente actualizar de nuevo el clúster de AKS a la misma versión a la que intentó actualizarlo anteriormente. Este proceso desencadena una conciliación.

    $ 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
    

Solución 3: Elimine los pods que no se pueden drenar o reduzca la carga de trabajo a cero

  1. Elimine los pods que no se pueden purgar.

Nota:

Si un Deployment o un StatefulSet crea los pods, estos están controlados por un ReplicaSet. Si es así, puede que necesite eliminar o escalar a cero las réplicas de la carga de trabajo del Deployment o del StatefulSet. Antes de realizar este cambio, realice una copia de seguridad del recurso mediante la ejecución de : kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yaml.

  1. Para reducir la carga de trabajo, use kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>.

  2. Inténtelo de nuevo para actualizar el clúster de AKS a la misma versión a la que intentó actualizar previamente. Este proceso desencadena una conciliación.

    $ 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