特定の条件下では、PodDisruptionBudgets(PDB)ポリシーにより、ノードプールからノードが正常に削除されない場合があります。そのような状況下では、ノード ステータスは削除されても Ready,SchedulingDisabled
を通知します。このドキュメントでは、現在 PDB の問題によってブロックされている Google Distributed 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 クラスタ(管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタ、ユーザー クラスタ)に影響を与える可能性があります。
同様の手順を、すべてのクラスタ タイプに適用できます。ただし、管理クラスタ ノードプール(管理クラスタ、ハイブリッド クラスタ、またはスタンドアロン クラスタ)からノードを削除する特定のコマンドは、ユーザー クラスタ ノードプールからノードを削除するコマンドとは若干異なります。
読みやすくするため、次のコマンドでは
${KUBECONFIG}
変数を使用します。クラスタの種類に応じて、管理クラスタの kubeconfig(
ADMIN_KUBECONFIG
)またはユーザー クラスタの kubeconfig(USER_CLUSTER_CONFIG
)パス$(KUBECONFIG)
にエクスポートし、以下の手順に従います。- ユーザー クラスタからノードプールを削除するには、
export KUBECONFIG=USER_CLUSTER_CONFIG
を設定します。 - 管理クラスタからノードを削除するには、
export KUBECONFIG=ADMIN_KUBECONFIG
を設定します。
- ユーザー クラスタからノードプールを削除するには、
省略可: ユーザー クラスタ ノードプールからノードを削除する場合は、次のコマンドを実行してユーザー クラスタ 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
: ユーザー クラスタの構成ファイルへのパス。
ノードプールからノードを削除した後、ノードのステータスを確認します。影響を受けるノードは、
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
クラスタ内の 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
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"}}}
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
該当する Pod を確認した後、PDB ポリシーのバックアップ コピーを作成します。次の例は、
log-aggregator
ポリシーのバックアップを示しています。kubectl get pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system \ -o yaml >> log-aggregator.yaml
特定の PDB ポリシーを削除します。次の例では、
log-aggregator
ポリシーを削除します。kubectl delete pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system
PDB ポリシーを削除すると、ノードがドレインを開始します。ただし、ノードが完全に削除されるまでに最大 30 分かかることがあります。ノードのステータスを継続的に確認して、プロセスが正常に完了したことを確認します。
ノードを完全に削除し、ノードに関連付けられたストレージ リソースも削除する場合、PDB ポリシーを復元する前に行います。詳細については、ストレージ リソースを削除するをご覧ください。
コピーから PDB ポリシーを復元します。
kubectl apply -f log-aggregator.yaml --kubeconfig ${KUBECONFIG}
削除された Pod が正常に再作成されていることを確認します。この例では、2 つの
stackdriver-log-aggregator-x
Pod がある場合、どちらも再作成されます。kubectl get pods -o wide --kubeconfig ${KUBECONFIG} -A
ノードを復元する場合は、ノードプール構成を適切に編集し、ノード IP アドレスを復元します。
完全に削除されたノードからストレージ リソースを削除する
ノードを完全に削除した後に、そのノードをシステムに復元しない場合は、そのノードに関連付けられているストレージ リソースを削除することもできます。
ノードに関連付けられた永続ボリューム(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}'
ノードに関連付けられた PV を削除します。
kubectl delete pv PV_NAME --kubeconfig ${KUBECONFIG}
PV_NAME
は、削除する永続ボリュームの名前に置き換えます。