📖

Kubernetesのガベージコレクションについてまとめる

2022/02/23に公開

この記事はKubernetes Document v1.23に依拠したものです。v1.23以降のバージョンでの情報の正確さは保証されていません。

Kubernetesのガベージコレクションとは何か

Kubernetesのガベージコレクションについて公式ドキュメントを読んで理解した内容をまとめておく。

プログラミング言語におけるガベージコレクションとは普通、動的に確保したメモリ領域を不要になったタイミングで自動的に解放する機能のことを指す。Kubernetesにおいては、ガベージコレクションという用語はより限定的な意味で使われてる。
 公式ドキュメントでは、以下の8種類のリソースに対するクリーンアップをガベージコレクションと呼んでいる。

  • 失敗したPod(Failed Pod)
  • 完了したJob(Completed Pod)
  • オーナーリファレンスのないオブジェクト
  • 使われていないコンテナやコンテナイメージ
  • 動的にプロビジョンされたPersistentVolumeで、StorageClassの再クレームポリシーがDeleteのもの
  • 古くなった、もしくは期限の切れたCertificateSigningRequests (CSRs)
  • 以下の経緯で削除されたNode
    • クラウドで、クラスタがクラウドコントローラマネージャを使用している場合
    • オンプレミスで、クラスタがクラウドコントローラマネージャに類似したアドオンを使用している場合
  • Node Lease オブジェクト

それぞれについて詳しく見てみよう。

失敗したPod

人力もしくはコントローラが削除するまで、失敗したPodのAPIオブジェクトはクラスタのAPIの中に残り続ける。Failed Podとは、pod.status.phaseの値がFailedであるようなPodのことを指す。Podの数がkube-controller-managerのterminated-pod-gc-thresholdで定められた閾値を超えると、コントロールプレーンは終了したPodをクリーンアップする。

完了したジョブ

実行終了後のジョブには、TTL-after-finishedコントローラーによってTTL機能が提供されている。ジョブの.spec.ttlSecondsAfterFinishedフィールドを指定することで、終了したジョブはTTL秒後にTTL-after-finishedコントローラーによってカスケード的に削除される。

オーナーリファレンスのないオブジェクト

オーナーによって所有されるようなオブジェクトに関して、オーナーリファレンスがない場合、クリーンアップされる。

そもそもオーナーリファレンスとは何か

Kubernetesの多くのオブジェクトはオーナーリファレンスを通じてリンクされている。例えばReplicaSetPodのオーナーである。オブジェクトのオーナーリファレンスはmetadata.ownerReferencesの値として表示される。オーナーリファンレスはどのオブジェクトがどのオブジェクトに依存しているかを表す。多くの場合ownerReferencesの値は自動的に設定されるが、手動で設定してあげることもできる。オーナーリファレンスとlabelsselectorsは似ているが別のものである。
 注意として、名前空間を跨いでオーナーリファレンスを設定することはできない。同じ名前空間に指定されたオーナーが存在しない場合、オーナーリファレンスが存在しないものとして扱われ、Kubernetesのガベージコレクションによってそのオブジェクトは削除される。ownerReferencesの設定が仕様に違反したときに発生する問題については以下の記事が詳しい。「KubernetesにおけるownerReferenceの誤用にご用心」

使われていないコンテナやコンテナイメージ

Kubeletは、使われていないコンテナイメージに対して5分おきにガベージコレクションを実行し、使われていないコンテナに対して10分おきにガベージコレクションを実行する。外部のガベージコレクションツールの使用は推奨されていない。
コンテナとコンテナイメージに対するガベージコレクションの設定を変えるにはKubeletのconfigファイルを設定してあげればよい。Set Kubelet parameters via a config fileを参照。

関連用語

カスケード削除

Kubernetesがオブジェクトを削除するときに、そのオブジェクトに依存するオブジェクトも自動的に削除することをカスケード削除という。カスケード削除にはフォアグラウンドでのカスケード削除とバックグラウンドでのカスケード削除がある。

フォアグラウンドなカスケード削除

フォアグラウンドでのカスケード削除では、削除しているオーナーオブジェクトはまずdeletion in progress状態になる。deletion in progress状態になると

  • Kubernetes API サーバーがそのオブジェクトのmetadata.deletionTimestampフィールドに時刻を設定する。
  • Kubernetes API サーバーがmetadata.finalizersの値をforegroundDeletionに設定する。
  • 削除プロセスが完了するまでKubernetes API サーバーを通じてそのオブジェクトは認識可能になる。
    オーナーオブジェクトがdeletion in progress状態になった後に、コントローラーは依存関係を削除していき、全ての依存オブジェクトが削除されてからオーナーオブジェクトを削除する。

バックグラウンドでのカスケード削除

バックグラウンドでのカスケード削除では、Kubernetes API サーバーがオーナーオブジェクトを直ちに削除して、コントローラーがバックグラウンドで依存オブジェクトをクリーンアップする。

オーファンオブジェクト

Kubernetesがオーナーオブジェクトを削除したとき、残った依存オブジェクトをオーファンオブジェクトと呼ぶ。デフォルトの設定ではオーファンオブジェクトは自動的に削除される。

Discussion