PodDisruptionBudgets によってブロックされたノードを削除する

特定の条件下では、PodDisruptionBudgets(PDB)ポリシーにより、ノードプールからノードが正常に削除されない場合があります。そのような状況下では、ノード ステータスは削除されても Ready,SchedulingDisabled を通知します。このドキュメントでは、現在 PDB の問題によってブロックされている Google Distributed Cloud クラスタからノードを削除する方法について説明します。

このページは、基盤となる技術インフラストラクチャのライフサイクルを管理し、サービスレベル目標(SLO)が達成されていない場合やアプリケーションで障害が発生した場合にアラートやページに対応する管理者、アーキテクト、オペレーターを対象としています。Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

PDB は、使用可能な Pod の数と競合します。

PDB ポリシーは、システムを変更する際に Pod が同時に停止しないようにすることで、アプリのパフォーマンスを保証します。その結果、PDB ポリシーは、複製されたアプリケーションで同時に使用できない Pod の数を制限します。

ただし、ノードを削除することで、ポリシーに違反する可能性がある場合、PDB ポリシーにより、ノードの削除ができないことがあります。

例えば、PDF ポリシーで、システム内で使用可能な Pod は、常に 2 つであると定義できます。(.spec.minAvailable が 2)。ただし、Pod が 2 つしかない場合、その内の 1 つを含むノードを削除しようとすると、PDB ポリシーが有効になり、ノードの削除が妨げられます。

同様に、PDB ポリシーで、使用できない Pod がない(.spec.maxUnavailable が 0)と定義すると、そのポリシーにより関連するノードはどれも削除が妨げられます。一度に 1 つの Pod を削除しようとしても、PDB ポリシーにより、影響を受けるノードを削除することはできません。

PDB ポリシーを無効にしてから再度有効にする

PDB の競合を解決するには、PDB ポリシーのバックアップを作成してから削除します。PDB が正常に削除された後、ノードがドレインされ、関連する Pod が削除されます。それから必要な変更を行い、PDB ポリシーを再度有効にできます。

次の例は、この条件のノードを削除する方法を示しています。このノードは、あらゆる種類の Google Distributed Cloud クラスタ(管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタ、ユーザー クラスタ)に影響を与える可能性があります。

同様の手順を、すべてのクラスタ タイプに適用できます。ただし、管理クラスタ ノードプール(管理クラスタ、ハイブリッド クラスタ、またはスタンドアロン クラスタ)からノードを削除する特定のコマンドは、ユーザー クラスタ ノードプールからノードを削除するコマンドとは若干異なります。

  1. 読みやすくするため、次のコマンドでは ${KUBECONFIG} 変数を使用します。

    クラスタの種類に応じて、管理クラスタの kubeconfig(ADMIN_KUBECONFIG)またはユーザー クラスタの kubeconfig(USER_CLUSTER_CONFIG)パス $(KUBECONFIG) にエクスポートし、以下の手順に従います。

    • ユーザー クラスタからノードプールを削除するには、export KUBECONFIG=USER_CLUSTER_CONFIG を設定します。
    • 管理クラスタからノードを削除するには、export KUBECONFIG=ADMIN_KUBECONFIG を設定します。
  2. 省略可: ユーザー クラスタ ノードプールからノードを削除する場合は、次のコマンドを実行してユーザー クラスタ kubeconfig ファイルを抽出します。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n cluster-USER_CLUSTER_NAME \
      get secret USER_CLUSTER_NAME-kubeconfig  \
      -o 'jsonpath={.data.value}' | base64 -d > USER_CLUSTER_CONFIG
    

    次のエントリを、クラスタ環境に固有の情報に置き換えます。

    • ADMIN_KUBECONFIG: 管理クラスタの kubeconfig ファイルのパス。
    • CLUSTER_NAME: スナップショットをとるクラスタの名前。
    • USER_CLUSTER_CONFIG: ユーザー クラスタの構成ファイルへのパス。
  3. ノードプールからノードを削除した後、ノードのステータスを確認します。影響を受けるノードは、Ready, SchedulingDisabled を報告します。

    kubectl get nodes --kubeconfig ${KUBECONFIG}
    

    ノードのステータスは、次の出力例のようになります。

    NAME   STATUS                    ROLES      AGE      VERSION
    CP2    Ready                     Master     11m      v.1.18.6-gke.6600
    CP3    Ready,SchedulingDisabled  <none>     9m22s    v.1.18.6-gke.6600
    CP4    Ready                     <none>     9m18s    v.1.18.6-gke.6600
    
  4. クラスタ内の PDB を確認します。

    kubectl get pdb --kubeconfig ${KUBECONFIG} -A
    

    システムにより、次のような出力で PDB が報告されます。

    NAMESPACE     NAME             MIN AVAILABLE    MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    gke-system    istio-ingress    1                N/A               1                     19m
    gke-system    istiod           1                N/A               1                     19m
    kube-system   coredns          1                N/A               0                     19m
    kube-system   log-aggregator   N/A              0                 0                     19m
    kube-system   prometheus       N/A              0                 0                     19m
    
  5. PDB を検査します。PDB 内の Pod ラベルと、ノード内の一致する Pod の間で照合します。この照合により、正しい PDB を無効にしてノードを正常に削除できます。

    kubectl --kubeconfig ${KUBECONFIG} get pdb log-aggregator -n kube-system -o 'jsonpath={.spec}'
    

    PDB ポリシー内の一致するラベルの結果がシステムによって返されます。

    {"maxUnavailable":0,"selector":{"matchLabels":{"app":"stackdriver-log-aggregator"}}}
    
  6. PDB ポリシーラベルと一致する Pod を検索します。

    kubectl --kubeconfig ${KUBECONFIG} get pods -A --selector=app=stackdriver-log-aggregator  \
      -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'
    

    このコマンドは、PDB ラベルと一致する Pod のリストを返します。また、削除する必要がある PDB ポリシーを検証します。

    stackdriver-log-aggregator-0    CP3
    stackdriver-log-aggregator-1    CP3
    
  7. 該当する Pod を確認した後、PDB ポリシーのバックアップ コピーを作成します。次の例は、log-aggregator ポリシーのバックアップを示しています。

    kubectl get pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system  \
      -o yaml >> log-aggregator.yaml
    
  8. 特定の PDB ポリシーを削除します。次の例では、log-aggregator ポリシーを削除します。

    kubectl delete pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system
    

    PDB ポリシーを削除すると、ノードがドレインを開始します。ただし、ノードが完全に削除されるまでに最大 30 分かかることがあります。ノードのステータスを継続的に確認して、プロセスが正常に完了したことを確認します。

    ノードを完全に削除し、ノードに関連付けられたストレージ リソースも削除する場合、PDB ポリシーを復元する前に行います。詳細については、ストレージ リソースを削除するをご覧ください。

  9. コピーから PDB ポリシーを復元します。

    kubectl apply -f log-aggregator.yaml --kubeconfig ${KUBECONFIG}
    
  10. 削除された Pod が正常に再作成されていることを確認します。この例では、2 つの stackdriver-log-aggregator-x Pod がある場合、どちらも再作成されます。

    kubectl get pods -o wide --kubeconfig ${KUBECONFIG} -A
    
  11. ノードを復元する場合は、ノードプール構成を適切に編集し、ノード IP アドレスを復元します。

完全に削除されたノードからストレージ リソースを削除する

ノードを完全に削除した後に、そのノードをシステムに復元しない場合は、そのノードに関連付けられているストレージ リソースを削除することもできます。

  1. ノードに関連付けられた永続ボリューム(PV)の名前を確認し、取得します。

    kubectl get pv --kubeconfig ${KUBECONFIG}  \
      -A -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{.spec.claimRef.name}{":\t"}  \
      {.spec.nodeAffinity.required.nodeSelectorTerms[0].matchExpressions[0].values}{"\n"}{end}'
    
  2. ノードに関連付けられた PV を削除します。

    kubectl delete pv PV_NAME --kubeconfig ${KUBECONFIG}
    

    PV_NAME は、削除する永続ボリュームの名前に置き換えます。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。