排查由于 PDB 导致的逐出失败而导致的 UpgradeFailed 错误

本文介绍如何识别和解决由于 Pod 中断预算(PDB)导致逐出失败而导致的 UpgradeFailed 错误,这些错误在尝试升级 Azure Kubernetes 服务 (AKS) 群集时发生。

先决条件

本文需要 Azure CLI 2.67.0 或更高版本。 若要查找版本号,请运行 az --version。 如果必须安装或升级 Azure CLI,请参阅 如何安装 Azure CLI

有关升级过程的详细信息,请参阅升级 Azure Kubernetes 服务 (AKS) 群集中的“升级 AKS 群集”部分。

症状

AKS 群集升级作失败,并出现以下错误消息之一:

  • (UpgradeFailed)逐出 Pod <pod-name> 失败并出现“请求过多”错误时,清空node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx失败。 这通常是由限制性 Pod 中断预算 (PDB) 策略引起的。 请参阅 https://aka.ms/aks/debugdrainfailures。 原始错误:无法逐出 Pod,因为它违反了 Pod 的中断预算。 PDB 调试信息: <namespace>/<pod-name> pdb <pdb-name> 阻止了 0 个未读 Pod。

  • 代码:UpgradeFailed
    消息:逐出 Pod <pod-name> 失败并出现“请求过多”错误时,清空节点aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx失败。 这通常是由限制性 Pod 中断预算 (PDB) 策略引起的。 请参阅 https://aka.ms/aks/debugdrainfailures。 原始错误:无法逐出 Pod,因为它违反了 Pod 的中断预算。 PDB 调试信息: <namespace>/<pod-name> pdb <pdb-name> 阻止了 0 个未读 Pod。

原因

如果 Pod 受到 Pod 中断预算 (PDB) 策略的保护,则可能会发生此错误。 在这种情况下,Pod 会拒绝耗尽,在多次尝试后,升级作会失败,群集/节点池处于 Failed 状态。

检查 PDB 配置: ALLOWED DISRUPTIONS 值。 该值应 1 或更大。 有关详细信息,请参阅 使用 Pod 中断预算规划可用性。 例如,可以按如下所示检查工作负荷及其 PDB。 应观察到该 ALLOWED DISRUPTIONS 列不允许发生任何中断。 ALLOWED DISRUPTIONS如果值为0,则 Pod 不会被逐出,节点排出在升级过程中失败:

$ 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

还可以使用命令 kubectl get events | grep -i drain检查 Kubernetes 事件中的任何条目。 类似的输出显示消息“被过多请求阻止的逐出(通常为 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>

若要解决此问题,请使用以下解决方案之一。

解决方案 1:允许 Pod 清空

  1. 调整 PDB 以启用 Pod 清空。 通常,允许的中断由 Min Available / Max unavailableRunning pods / Replicas 参数控制。 可以在 PDB 级别修改Min Available / Max unavailable参数,或者将允许的中断值推送到 1 或更大的数目Running pods / Replicas

  2. 请重试将 AKS 群集升级到以前尝试升级到的同一版本。 此过程触发对帐。

    $ 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
    

解决方案 2:备份、删除和重新部署 PDB

  1. 使用命令 kubectl get pdb <pdb-name> -n <pdb-namespace> -o yaml > pdb-name-backup.yaml备份 PDB,然后使用命令 kubectl delete pdb <pdb-name> -n <pdb-namespace>删除 PDB。 完成新的升级尝试后,可以使用命令 kubectl apply -f pdb-name-backup.yaml重新部署 PDB 以应用备份文件。

  2. 请重试将 AKS 群集升级到以前尝试升级到的同一版本。 此过程触发对帐。

    $ 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
    

解决方案 3:删除无法清空的 Pod 或将工作负荷缩减到零(0)

  1. 删除无法清空的 Pod。

    备注

    如果 Pod 是由部署或 StatefulSet 创建的,它们将由 ReplicaSet 控制。 如果是这种情况,可能需要删除或将工作负荷副本缩放到部署或 StatefulSet 的零(0)。 在执行此作之前,建议进行备份: kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yaml

  2. 若要缩减,可以在对帐之前使用kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>

  3. 请重试将 AKS 群集升级到以前尝试升级到的同一版本。 此过程触发对帐。

    $ 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
    

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区