0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kubebuilder/controller-runtimeなどでControllerReference(OwnerReference)をセットしたいときに便利なイディオム

Posted at

この記事では、Kubebuilder/controller-runtimeなどでControllerReference(OwnerReference)をセットしたいときに便利なイディオムについて紹介します。

便利なヘルパー関数

次のようなヘルパー関数を定義しておくと、所有権関係の設定が簡単になります:

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func setOwnerReference(parent *myprojv1.SomeResource, child metav1.Object) {
  child.SetOwnerReferences([]metav1.OwnerReference{
    *metav1.NewControllerRef(parent, parent.GroupVersionKind()),
  })
}

この関数は親リソースから子リソースへの所有権関係(ControllerReference)を設定します。親リソース削除時に小リソースを自動削除(いわゆるカスケード削除、GCなんて呼ばれたりするやつ)できたり、Owns()で子リソースを監視(watch)できたり便利になります。

重要な注意点

parent.GroupVersionKind()メソッドは、client.Get()などのKubernetesクライアント操作で取得したオブジェクトの場合のみ、正しいGroupVersionKindが設定されていることが保証されます。それ以外の方法(例:新規作成したオブジェクトや、自前でUnmarshalしたオブジェクト)の場合、GroupVersionKindがゼロ値になっている可能性があります。

そのため、より安全な実装としては、明示的にGroupVersionKindを指定する方法が推奨されます:

func setOwnerReference(parent *myprojv1.SomeResource, child metav1.Object) {
  child.SetOwnerReferences([]metav1.OwnerReference{
    *metav1.NewControllerRef(parent, myprojv1.GroupVersion.WithKind("SomeResource")),
  })
}

この方法であれば、親オブジェクトの取得方法に関わらず、常に正しいGroupVersionKindが設定されることが保証されます。

ただ、書き方が冗長になるので、「クライアントから取得したオブジェクトしか使わない」というケースでは最初に紹介したイディオムでもいいと思っています。

ちなみに、ControllerReferenceとOwnerReferenceの違いとは

OwnerReferenceは単にリソース間の所有権関係を示しますが、ControllerReferenceは「Controller」フィールドがtrueに設定された特殊なOwnerReferenceです。OwnerReferenceの一種ということですね。

一つのリソースは複数のOwnerReferenceを持つことができますが、ControllerReferenceは最大で1つしか持てません。

これは、リソースを実際に制御する権限を持つコントローラーは一つだけであるべきという原則に基づいています。この区別により、複数のコントローラーが同一リソースを管理しようとする際の競合を防げるわけです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?