特定の条件下では、Pod 停止予算(PDB)ポリシーにより、ノードプールからノードが正常に削除されない場合があります。そのような状況下では、ノード ステータスは削除されても Ready,SchedulingDisabled
を通知します。
Pod 停止予算は、使用可能な 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 が正常に削除されると、ノードがドレインされ、関連する Pod が削除されます。必要な修正を加えたら、PDB ポリシーを再度有効にできます。
次の例は、この条件のノードを削除する方法を示しています。このノードは、あらゆる種類の GKE on Bare Metal クラスタ(管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタ、ユーザー クラスタ)に影響を与える可能性があります。
同様の手順を、すべてのクラスタ タイプに適用できます。ただし、管理クラスタ ノードプール(管理クラスタ、ハイブリッド クラスタ、またはスタンドアロン クラスタ)からノードを削除する特定のコマンドは、ユーザー クラスタ ノードプールからノードを削除するコマンドとは若干異なります。
クラスタ タイプ別のコマンド バリエーション
読みやすくするため、次のコマンドのプレースホルダ ${KUBECONFIG}
に注意してください。クラスタの種類に応じて、管理クラスタの kubeconfig(ADMIN_KUBECONFIG)または、ユーザー クラスタの kubeconfig(USER_CLUSTER_CONFIG)パスを $(KUBECONFIG)
にエクスポートし、以下の手順に従います。
- ユーザー クラスタからノードプールを削除するには、
export KUBECONFIG=USER_CLUSTER_CONFIG
。 - 管理クラスタからノードを削除するには、
export KUBECONFIG=ADMIN_KUBECONFIG
。
(省略可)ユーザー クラスタ ノードプールからノードを削除する場合は、次のコマンドを実行してユーザー クラスタ kubeconfig ファイルを抽出します。変数
ADMIN_KUBECONFIG
は管理クラスタ kubeconfig へのパスを指定し、変数USER_CLUSTER_NAME
はクラスタの名前を指定します。kubectl --kubeconfig ADMIN_KUBECONFIG -n cluster-USER_CLUSTER_NAME \ get secret USER_CLUSTER_NAME-kubeconfig \ -o 'jsonpath={.data.value}' | base64 -d > USER_CLUSTER_CONFIG
ノードプールからノードを削除した後、ノードのステータスを確認します。影響を受けるノードは、
Ready, SchedulingDisabled
を報告します。kubectl get nodes --kubeconfig ${KUBECONFIG}
ノードのステータスは次のようになります。
NAME STATUS ROLES AGE VERSION abmnewCP2 Ready Master 11m v.1.18.6-gke.6600 abmnewCP3 Ready,SchedulingDisabled <none> 9m22s v.1.18.6-gke.6600 abmnewCP4 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 abmnewCP3 stackdriver-log-aggregator-1 abmnewCP3
該当する 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 アドレスを復元します。
完全に削除されたノードからストレージ リソースを削除する
ノードを完全に削除した後に、そのノードをシステムに復元しない場合は、そのノードに関連付けられているストレージ リソースを削除することもできます。
次のコマンドでは、以下の変数にご注意ください。
ADMIN-KUBECONFIG
は、管理クラスタのパスを指定します。USER_CLUSTER_CONFIG
は、クラスタ構成 YAML ファイルへのパスを指定します。
ノードに関連付けられた永続ボリューム(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}