'Terminating' 状態で停止した Kubernetes Pod を強制削除する方法

intermediate☸️ Kubernetes2026-07-05| Kubernetes (全バージョン), kubectl CLI, Linux/macOS/Windows

Error Message

pod "my-pod" stuck in Terminating state, DeletionTimestamp set but pod not deleted after grace period
#kubernetes#pod#terminating#finalizer#kubectl#devops

厄介な「ゴースト」Pod

誰もが一度は経験したことがあるでしょう。kubectl delete pod を実行し、数秒待ってから get pods を実行したのに、ステータスが Terminating のまま止まっていることがあります。数分が数時間になっても、Pod は一向に消えません。通常、以下のような状態になります:

NAME               READY   STATUS        RESTARTS   AGE
web-server-v2-7x   1/1     Terminating   0          14h

kubectl describe pod web-server-v2-7x で詳細を確認すると、DeletionTimestamp は設定されているものの、猶予期間(通常30秒)を大幅に過ぎても Pod が削除されないというメッセージが表示されます。

なぜ Pod が削除されないのか

原因のほとんどは Finalizer です。Finalizer は、フライト前のチェックリストのようなものだと考えてください。Kubernetes に対して「待って!クリーンアップが終わるまでこのオブジェクトを削除しないで」と伝えます。

Finalizer はデータ損失を防ぐためのものですが、以下のような理由で停止してしまうことがよくあります:

  • 応答しないノード: ワーカーノードの電源が切れている、またはネットワーク接続が失われているため、kubelet が Pod の削除を確認できません。
  • ストレージのハング: AWS EBS や Azure Disk などの外部ボリュームが、標準の6分間のタイムアウトを過ぎてもデタッチ(切り離し)に失敗しています。
  • ゾンビコントローラー: クリーンアップを担当するカスタムオペレーターやコントローラーがクラッシュしたか、それ自体が削除されています。
  • ネットワークパーティション: API サーバーがノードと通信できず、Pod の状態を検証できません。

解決策:ステップバイステップの復旧手順

ステップ1:停止している Finalizer を特定する

強引な操作を始める前に、何が実際に削除を妨げているのかを確認しましょう。Pod の設定を YAML 形式で出力し、metadata を確認します:

kubectl get pod web-server-v2-7x -o yaml

metadata.finalizers ブロックまでスクロールしてください。おそらく以下のようなエントリが表示されます:

metadata:
  finalizers:
  - kubernetes.io/pvc-protection
  - custom-cleanup-logic.io/wait-for-log-flush

ステップ2:削除開始からの経過時間を確認する

Pod がどのくらいの時間ハングしているかを正確に把握することは、一時的な遅延なのか、それとも完全にロックされているのかを判断するのに役立ちます。次のコマンドでタイムスタンプを抽出します:

kubectl get pod web-server-v2-7x -o jsonpath='{.metadata.deletionTimestamp}'

出力結果が3時間前などの古い時刻を示している場合、自動クリーンアップは明らかに失敗しています。

ステップ3:パッチを適用して Finalizer を消去する

停止した Pod を削除する最も確実な方法は、Finalizer のリストを手動でクリアすることです。リストを null に設定することで、Kubernetes に対しチェックリストをスキップして即座にリソースを削除するように指示します。

次のパッチコマンドを実行します:

kubectl patch pod web-server-v2-7x -p '{"metadata":{"finalizers":null}}' --type=merge

これで、Pod は即座にリストから消えるはずです。

ステップ4:最終手段(強制削除)

万が一パッチが機能しない場合は(稀ですが)、kubelet の確認を完全にバイパスできます。猶予期間を0秒に設定し、force フラグを使用します:

kubectl delete pod web-server-v2-7x --grace-period=0 --force

警告: この操作は慎重に行ってください。ノードがまだ稼働している状態で Pod を強制削除すると、Deployment がすぐに新しい Pod を作成しようとした場合に、同じ Pod のインスタンスが2つ同時に実行されてしまう可能性があります。

確認と予防策

最後にネームスペースをもう一度確認します:kubectl get pods。ゴースト Pod は消えているはずです。Deployment を使用している場合は、すでに正常な新しい Pod が代わりに起動しているでしょう。

複数のタイムゾーンにまたがって調査を行う際、私はよく ToolCraft の Timestamp Converter を使用します。2023-10-27T14:22:11Z のような文字列をローカル時間に素早く変換でき、Pod の停止時間を ELK や Datadog ログの特定のエラーと照らし合わせるのに役立ちます。

今後のためにクラスタをクリーンに保つポイント:

  • ノードの状態を注意深く監視してください。NotReady 状態のノードは Pod が停止する最大の原因です。
  • ストレージ関連の Finalizer がハングし続ける場合は、CSI ドライバのログを確認してください。
  • カスタム Finalizer は、コントローラーの可用性が確実に保証されている(高可用性構成など)場合にのみ使用してください。

Related Error Notes