PDB による退避の失敗が原因で発生する UpgradeFailed エラーのトラブルシューティング

まとめ

この記事では、Azure Kubernetes Service (AKS) クラスターをアップグレードしようとしたときに発生するポッド中断予算 (PDB) による削除エラーによるUpgradeFailed エラーを特定して解決する方法について説明します。

前提条件

この記事では、Azure CLI バージョン 2.67.0 以降のバージョンが必要です。 バージョン番号を見つけるには、 az --versionを実行します。 Azure CLIをインストールまたはアップグレードする必要がある場合は、「Azure CLIを参照してください。

アップグレード プロセスの詳細については、「 Azure Kubernetes Service (AKS) クラスターをアップグレードする」の「AKS クラスターのアップグレード」セクションを参照してください。

ヒント

AKS アップグレードを開始する前に、Azure ポータルでアップグレード準備チェックを実行します。

AKS クラスター>>>

ターゲットの Kubernetes バージョンを選択したら、[アップグレードの準備] の横にある [確認] を選択します。 この事前検証では、アップグレード中にノードのドレインが正常に行われるのを妨げる可能性があるポッド中断バジェット (PDB) 構成など、潜在的なアップグレード ブロッカーを特定できます。

症状

AKS クラスターのアップグレード操作が失敗し、次のいずれかのエラー メッセージが表示されます。

  • (UpgradeFailed) ポッド node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx の退避が失敗し、要求が多すぎるエラーのため、ドレイン <pod-name> が失敗しました。 このエラーは、多くの場合、制限の厳しいポッド中断予算 (PDB) ポリシーが原因で発生します。 以下を参照してください。https://aka.ms/aks/debugdrainfailures 元のエラー: ポッドの中断予算に違反する可能性があるため、ポッドを削除できません。. PDB デバッグ情報: <namespace>/<pod-name> 0 個の未読ポッドを含む pdb <pdb-name> によってブロックされます。

  • コード: UpgradeFailed
    メッセージ: ドレインノードaks-<nodepool-name>-xxxxxxxx-vmssxxxxxxが失敗しました。ポッド<pod-name>の退避中に「要求数が多すぎます」エラーが発生しました。 このエラーは、多くの場合、制限の厳しいポッド中断予算 (PDB) ポリシーが原因で発生します。 以下を参照してください。https://aka.ms/aks/debugdrainfailures 元のエラー: ポッドの中断予算に違反する可能性があるため、ポッドを削除できません。. PDB デバッグ情報: <namespace>/<pod-name> 0 個の未読ポッドを含む pdb <pdb-name> によってブロックされます。

原因

このエラーは、ポッドがポッド中断予算 (PDB) ポリシーによって保護されている場合に発生します。 この状況では、ポッドは排出されることを拒みます。 数回試行すると、アップグレード操作が失敗し、クラスターまたはノード プールが Failed 状態になります。

PDB の構成 ( ALLOWED DISRUPTIONS 値) を確認します。 値は 1 以上にする必要があります。 詳細については、ポッドディスラプションバジェットを使用した可用性の計画をご覧ください。 たとえば、ワークロードとその PDB を次のように確認できます。 ALLOWED DISRUPTIONS列で中断が許可されないのを確認する必要があります。 ALLOWED DISRUPTIONS値が0されている場合、ポッドは削除されず、アップグレード プロセス中にノードのドレインが失敗します。

$ 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: ポッドをドレイン状態にする

  1. PDB を調整してポッドのドレインを有効にします。 一般に、許可される中断は、 Min Available / Max unavailable または Running pods / Replicas パラメーターによって制御されます。 PDB レベルで Min Available / Max unavailable パラメーターを変更するか、 Running pods / Replicas の数を増やして、許可される中断の値を 1 以上にプッシュします。

  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 のバックアップ、削除、再デプロイ

注:

PDB リソースの編集が実行可能なオプションではない場合は、このソリューションを使用します。

  1. 次のコマンドを実行して PDB をバックアップします。

    kubectl get pdb <pdb-name> -n <pdb-namespace> -o yaml > pdb-name-backup.yamlそして

  2. 次のコマンドを実行して、PDB を削除します。

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

  3. 新しいアップグレードの試行が完了したら、次のコマンドを使用してバックアップ ファイルを適用して PDB を再デプロイします。

    kubectl apply -f pdb-name-backup.yaml

  4. 以前にアップグレードしようとしたのと同じバージョンに 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: ドレインできない、またはワークロードをゼロまでスケールダウンできないポッドを削除する

  1. ドレインできないポッドを削除してください。

注:

Deployment または StatefulSet によってポッドが作成された場合、ReplicaSet によってポッドが制御されます。 その場合は、Deployment または StatefulSet のワークロード レプリカを削除するか、ゼロにスケーリングすることが必要になる場合があります。 この変更を行う前に、 kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yamlを実行してリソースをバックアップします。

  1. ワークロードをスケールダウンするには、 kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>を使用します。

  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