こんにちは。KubernetesのownerReferences
について、クラスタースコープのリソースとネームスペースリソースが関わった場合、どのような振る舞いになるのか気になったので実験してみました。本稿では、その結果についてご紹介します。
結論
検証の結果をまず先にお伝えします:
- クラスタースコープのリソースをネームスペースリソースのownerReferencesに指定することは、APIサーバーレベルでは可能でした。
- ネームスペースリソースをクラスタースコープのリソースのownerReferencesに指定することは、APIサーバーレベルで完全に拒否されました。
検証の背景と目的
Kubernetesの公式ドキュメントには、ownerReferences
について以下のように記載されています:
namespace間のowner referenceは、設計上許可されていません。namespaceの依存関係は、クラスタースコープまたはnamespaceのオーナーを指定できます。namespaceのオーナーは、依存関係と同じnamespaceに存在する必要があります。そうでない場合、owner referenceは不在として扱われ、すべてのオーナーが不在であることが確認されると、依存関係は削除される可能性があります。
この記述を読んで、以下の2つのエッジケースについて疑問を持ちました。
- クラスタースコープのリソースをネームスペースリソースのownerReferencesに指定できるのか?
- ネームスペースリソースをクラスタースコープのリソースのownerReferencesに指定できるのか?
検証環境
検証には以下の環境を使用しました:
- Kubernetes v1.32.0(kind環境)
- kind
- kubectl
検証方法
検証のために、以下のカスタムリソース定義(CRD)を作成しました:
1. クラスタースコープのCRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: globalconfigs.example.com
spec:
group: example.com
names:
kind: GlobalConfig
listKind: GlobalConfigList
plural: globalconfigs
singular: globalconfig
scope: Cluster
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
configValue:
type: string
description:
type: string
required:
- configValue
2. ネームスペーススコープのCRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: appconfigs.example.com
spec:
group: example.com
names:
kind: AppConfig
listKind: AppConfigList
plural: appconfigs
singular: appconfig
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
appName:
type: string
settings:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- appName
検証1: クラスタースコープのリソースをネームスペースリソースのオーナーに指定
検証手順
- ローカルKubernetesクラスターを作成
kind create cluster --name owner-ref-test
- カスタムリソース定義(CRD)をインストール
# クラスタースコープのCRD
kubectl apply -f manifests/cluster-scoped-crd.yaml
# ネームスペーススコープのCRD
kubectl apply -f manifests/namespaced-crd.yaml
- テスト用ネームスペースを作成
kubectl create namespace test
- クラスタースコープのカスタムリソースを作成
kubectl apply -f manifests/cluster-resource.yaml
このコマンドは、以下の内容のクラスタースコープのカスタムリソースを作成します:
apiVersion: example.com/v1
kind: GlobalConfig
metadata:
name: global-config-1
spec:
configValue: "global-setting"
description: "クラスタースコープのリソース例"
- 無効なネームスペースリソースの作成(クラスタースコープリソースを参照)
kubectl apply -f manifests/invalid-namespaced-resource.yaml
このコマンドは、以下の内容のネームスペースリソースを作成しようとします。このリソースは、クラスタースコープのリソースをownerReferencesとして参照しています:
apiVersion: example.com/v1
kind: AppConfig
metadata:
name: invalid-app-config
namespace: test
ownerReferences:
- apiVersion: example.com/v1
kind: GlobalConfig
name: global-config-1
uid: "PLACEHOLDER_UID" # 実行時に実際のUIDに置き換える必要があります
spec:
appName: "invalid-test-app"
settings:
key1: "value1"
key2: "value2"
注:実際の検証では、PLACEHOLDER_UID
はkubectl get globalconfig global-config-1 -o jsonpath='{.metadata.uid}'
コマンドで取得した実際のUIDに置き換えられます。
検証結果
予想に反して、このコマンドは成功しました。エラーは発生せず、クラスタースコープのリソースをownerReferencesに持つネームスペースリソースが正常に作成されました。
# 作成されたリソースの確認
kubectl get appconfig -n test invalid-app-config -o yaml
apiVersion: example.com/v1
kind: AppConfig
metadata:
# ...
name: invalid-app-config
namespace: test
ownerReferences:
- apiVersion: example.com/v1
kind: GlobalConfig
name: global-config-1
uid: 741f513d-9b15-465e-a643-85fefd3bb3d4
# ...
spec:
appName: invalid-test-app
settings:
key1: value1
key2: value2
検証2: ネームスペースリソースをクラスタースコープのリソースのオーナーに指定
検証手順
- ローカルKubernetesクラスターを作成
kind create cluster --name owner-ref-reverse-test
- カスタムリソース定義(CRD)をインストール
kubectl apply -f manifests/cluster-scoped-crd.yaml
kubectl apply -f manifests/namespaced-crd.yaml
- テスト用ネームスペースを作成
kubectl create namespace test
- ネームスペースリソースを作成(所有者として使用)
kubectl apply -f manifests/namespaced-owner-resource.yaml
このコマンドは、以下の内容のネームスペースリソースを作成します:
apiVersion: example.com/v1
kind: AppConfig
metadata:
name: owner-app-config
namespace: test
spec:
appName: "owner-test-app"
settings:
key1: "value1"
key2: "value2"
- 無効なクラスタースコープリソースの作成(ネームスペースリソースを参照)
# 実際のUIDを取得
NAMESPACE_RESOURCE_UID=$(kubectl get appconfig -n test owner-app-config -o jsonpath='{.metadata.uid}')
# UIDを置き換えたマニフェストを適用
kubectl apply -f manifests/invalid-cluster-resource.yaml
このコマンドは、以下の内容のクラスタースコープリソースを作成しようとします:
apiVersion: example.com/v1
kind: GlobalConfig
metadata:
name: invalid-global-config
ownerReferences:
- apiVersion: example.com/v1
kind: AppConfig
name: owner-app-config
namespace: test
uid: "PLACEHOLDER_UID" # 実行時に実際のUIDに置き換える
spec:
configValue: "invalid-global-setting"
description: "ネームスペースリソースを所有者に持つクラスタースコープのリソース例"
検証結果
このコマンドは失敗し、以下のようなエラーメッセージが表示されました:
Error from server (BadRequest): error when creating "...": GlobalConfig in version "v1" cannot be handled as a GlobalConfig: strict decoding error: unknown field "metadata.ownerReferences[0].namespace"
まとめ
Kubernetes v1.32.0(kind環境)での検証結果から、以下のことがわかりました:
- クラスタースコープのリソースをネームスペースリソースのownerReferencesに指定することは可能
- ネームスペースリソースをクラスタースコープのリソースのownerReferencesに指定することは不可能
最後までお読みくださりありがとうございました。Twitterでは@suinで技術情報をツイートしていますので、よかったらフォローお願いします。