オーナーと従属
Kubernetesでは、いくつかのオブジェクトは他のオブジェクトのオーナーになっています。 例えば、ReplicaSetはPodの集合のオーナーです。 これらの所有されているオブジェクトはオーナーに従属しています。
オーナーシップはいくつかのリソースでも使われているラベルとセレクターとは仕組みが異なります。
例として、EndpointSliceオブジェクトを作成するServiceオブジェクトを考えてみます。
Serviceはラベルを使ってどのEndpointSliceがどのServiceに利用されているかをコントロールプレーンに判断させています。
ラベルに加えて、Serviceの代わりに管理される各EndpointSliceはオーナーリファレンスを持ちます。
オーナーリファレンスは、Kubernetesの様々な箇所で管理外のオブジェクトに干渉してしまうのを避けるのに役立ちます。
オブジェクト仕様におけるオーナーリファレンス
従属オブジェクトはオーナーオブジェクトを参照するためのmetadata.ownerReferencesフィールドを持っています。
有効なオーナーリファレンスは従属オブジェクトと同じ名前空間に存在するオブジェクトの名前とUIDで構成されます。
KubernetesはReplicaSet、DaemonSet、Deployment、Job、CronJob、ReplicationControllerのようなオブジェクトの従属オブジェクトに、自動的に値を設定します。
このフィールドの値を手動で変更することで、これらの関係性を自分で設定することもできます。
ただし、通常はその必要はなく、Kubernetesが自動で管理するようにすることができます。
従属オブジェクトは、オーナーオブジェクトが削除されたときにガベージコレクションをブロックするかどうかを管理する真偽値を取るownerReferences.blockOwnerDeletionフィールドも持っています。
Kubernetesは、コントローラー
(例:Deploymentコントローラー)がmetadata.ownerReferencesフィールドに値を設定している場合、自動的にこのフィールドをtrueに設定します。
blockOwnerDeletionフィールドに手動で値を設定することで、どの従属オブジェクトがガベージコレクションをブロックするかを設定することもできます。
Kubernetesのアドミッションコントローラーはオーナーの削除権限に基づいて、ユーザーが従属リソースのこのフィールドを変更できるかを管理しています。 これにより、認証されていないユーザーがオーナーオブジェクトの削除を遅らせることを防ぎます。
備考:
名前空間をまたぐオーナーリファレンスは仕様により許可されていません。 名前空間付き従属オブジェクトには、クラスタースコープ、または名前空間付きのオーナーを指定することができます。名前空間付きオーナーは必ず従属オブジェクトと同じ名前空間に存在していなければなりません。 そうでない場合、オーナーリファレンスはないものとして扱われ、全てのオーナーがいなくなった時点で従属オブジェクトは削除対象となります。
クラスタースコープの従属オブジェクトはクラスタースコープのオーナーのみ指定できます。 v1.20以降では、クラスタースコープの従属オブジェクトが名前空間付きのオブジェクトをオーナーとした場合、 解決できないオーナーリファレンスを持っているものとして扱われ、ガベージコレクションの対象とすることができません。
v1.20以降で、ガベージコレクターが無効な名前空間またぎのownerReferenceや名前空間付きのオーナーに依存するクラスタースコープのオブジェクトなどを検知した場合、OwnerRefInvalidNamespaceを理由とした警告のEventを出し、involvedObjectで無効な従属オブジェクトを報告します。
kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespaceを実行することで、この種類のEventを確認することができます。
オーナーシップとファイナライザー
Kubernetesでリソースを削除するとき、APIサーバーはリソースを管理するコントローラーにファイナライザールールを処理させることができます。
ファイナライザーはクラスターが正しく機能するために必要なリソースを誤って削除してしまうことを防ぎます。
例えば、まだPodが使用中のPersistentVolumeを削除しようとするとき、PersistentVolumeが持っているkubernetes.io/pv-protectionファイナライザーにより、削除は即座には行われません。
その代わり、Kubernetesがファイナライザーを削除するまでボリュームはTerminatingステータスのまま残り、PersistentVolumeがPodにバインドされなくなった後で削除が行われます。
またKubernetesはフォアグラウンド、孤立したオブジェクトのカスケード削除を行ったとき、オーナーリソースにファイナライザーを追加します。
フォアグラウンド削除では、foregroundファイナライザーを追加し、オーナーを削除する前にコントローラーがownerReferences.blockOwnerDeletion=trueを持っている従属リソースを削除するようにします。
孤立したオブジェクトの削除を行う場合、Kubernetesはorphanファイナライザーを追加し、オーナーオブジェクトを削除した後にコントローラーが従属リソースを無視するようにします。
次の項目
- Kubernetesのファイナライザーについてさらに学習しましょう。
- ガベージコレクションについて学習しましょう。
- オブジェクトのメタデータのAPIリファレンスをご覧ください。