問題の背景
Kubernetes クラスターにおいて、ストレージ(特に NFS など)に依存する Service や Pod を削除する場合、対象のリソースが「Terminating」状態で完全に削除されない現象が発生することがあります。これは主に、オブジェクト削除時の最終処理やノード内のコンテナ終了プロセスにおける障害が起因しています。
削除不能の原因特定
オブジェクトが削除処理から解放されない場合、以下のような機構的な要因が考えられます。
- ファイナライザー(Finalizers)によるブロック
リソースに対して登録された最終処理関数が実行できていないケースです。例えば、カスタムコントローラーがクラッシュダウンしている場合や、アグリゲーションされた API サーバーが応答していない場合などがあります。制御側のサービスが復旧しない限り、このフラグが外れず削除が阻止されます。 - 優雅な終了(Graceful Shutdown)の実行失敗
Pod などのリソースは通常、Kubelet が通知を送信してコンテナを終了させる必要があります。しかし、以下の状況ではこのプロセスが完了しません。- OS レベルのプロセスが D ステート(Uninterruptible Sleep)に入り、ランタイムが終了信号を受け付けない場合。
- 管理ノードとの接続が切断されており、Kubelet が削除コマンドを受け取れていない場合。
対応措置
方法 1:即座な強制削除
待ち時間を設定せず、リソース定義を即座に API サーバーから抹消する手法です。ただし、実際のコンテナプロセスがクラスター内で残存するリスクがあるため注意が必要です。
# Pod の即時削除を実行(待機時間 0 秒)
kubectl delete pod backend-worker --grace-period=0 -n kube-system
方法 2:ファイナライザーフィールドの書き換え
パッチ操作を用いて、削除を阻害しているメタデータのフィルタリング条件(finalizers)をクリアします。これにより、API サーバーが削除承認を出せるようになります。
# JSON パッチ形式を使用して finalizers アレイを削除
kubectl patch pod backend-worker -n kube-system \
--type=json \
-p '[{"op": "remove", "path": "/metadata/finalizers"}]'
Kubernetes 内部の削除フロー
API サーバー側での処理ロジックは概ね以下のように進行します。
- クライアントからの DELETE リクエストを受信します。ここで指定された《GracePeriod》パラメータがチェックされます。
- リソースがサポートする削除戦略に基づき、丁寧な終了が必要か判定されます。
- 詳細な判定:
- 丁寧な削除が必要な場合: `deletionTimestamp` がセットされ、データは永続ストアに残ります。`finalizers` が空でない限り、完全な消去は行われません。
- 即時削除の場合: `finalizers` が配列として空(empty array)であれば、直ちにストアから物理削除が行われます。
- コントロールプレーン上の各コントローラーが `finalizers` を順次除外すると、最終的に API サーバーが実体の破棄を実行します。