亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Kubernetes 對象所有者與依賴者

2024-03-14 01:23:57
0
0

所有者與依賴者

在 Kubernetes 中,所有者(owner)對象可以擁有(own)一個或多個依賴者(dependent)對象。所有者對象通常是控制器資源,比如 ReplicaSet、StatefulSet、Deployment 或 DaemonSet 等。這些控制器創建(即“擁有”)Pod,Pod 就是它們的依賴者。

所有者與依賴者的關系是通過 ControllerRef 字段建立的。ControllerRef 是一個字段,它指向創建它的控制器對象。每個 Kubernetes 對象都可以有一個 ControllerRef,但只能有一個。如果一個對象有多個所有者,那么它實際上沒有所有者。

垃圾收集

所有者與依賴者的關系在 Kubernetes 的垃圾收集(garbage collection)機制中發揮著重要作用。當所有者對象被刪除時,Kubernetes 垃圾收集器會負責刪除所有擁有該所有者的依賴者對象。這種機制有助于確保在刪除控制器時,其管理的所有 Pod 也會被相應地刪除。

垃圾收集器默認啟用,并且作用于所有具有 ControllerRef 的對象。但是,用戶可以通過設置對象的 metadata.finalizers 字段來禁用垃圾收集。當 finalizer 列表不為空時,Kubernetes 不會從 API 中刪除對象,即使刪除請求已經提交。這允許外部控制器在對象被刪除前執行任何必要的清理邏輯。

設置所有者引用

在創建依賴者對象時,可以通過在其 metadata 字段中包含 ownerReferences 字段來設置所有者引用。ownerReferences 字段是一個 OwnerReference 對象的列表,每個 OwnerReference 對象都表示一個對所有者對象的引用。

OwnerReference 對象包含以下字段:

  • apiVersion:所有者對象的 API 版本。
  • kind:所有者對象的種類。
  • name:所有者對象的名稱。
  • uid:所有者對象的唯一標識符。
  • controller:一個布爾值,表示此引用是否由 Kubernetes 控制器管理。如果為 true,則當所有者被刪除時,此依賴者也會被垃圾收集器刪除。
  • blockOwnerDeletion:如果為 true,則當存在任何具有此值的依賴者時,不可以刪除所有者對象。這可以防止級聯刪除。

使用場景

所有者與依賴者的概念在 Kubernetes 中有多種應用場景。以下是一些常見的例子:

  1. 控制器與 Pod:如前所述,控制器(如 Deployment、StatefulSet 等)創建并管理 Pod。在這種情況下,控制器是所有者,Pod 是依賴者。當控制器被刪除時,其管理的所有 Pod 也將被刪除。
  2. 自定義資源與依賴對象:當用戶定義自定義資源(Custom Resource, CR)并創建相應的控制器來管理這些資源時,自定義資源可以成為其他對象的所有者。例如,一個自定義的數據庫資源可以擁有一個用于存儲數據的 PersistentVolumeClaim。當數據庫資源被刪除時,相應的 PersistentVolumeClaim 也將被刪除。
  3. 防止級聯刪除:通過設置 blockOwnerDeletion 字段為 true,可以確保在刪除所有者對象之前不會刪除其依賴者。這在某些場景下非常有用,例如當依賴者對象包含重要數據或配置時,用戶可能希望在刪除所有者之前手動處理這些依賴者。

通過理解和利用所有者與依賴者的概念,用戶可以更有效地管理 Kubernetes 集群中的資源,并確保在刪除或更新對象時保持資源的完整性和一致性。

 

舉個例子,當你嘗試刪除一個仍然被 Pod 使用的 PersistentVolume 時,由于 PersistentVolume 上有 kubernetes.io/pv-protection finalizer,刪除操作不會立即生效。相反,該 PersistentVolume 會保持在 Terminating 狀態,直到 Kubernetes 清除了 finalizer,而這只會在 PersistentVolume 不再綁定到任何 Pod 時發生。

package main

import (
	"context"
	"flag"
	"fmt"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	kubeconfig := flag.String("kubeconfig", "", "Path to the kubeconfig file")
	flag.Parse()

	// 創建 Kubernetes 客戶端
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	// 創建一個測試 Namespace
	namespace := &corev1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name: "test-namespace",
		},
	}
	_, err = clientset.CoreV1().Namespaces().Create(context.TODO(), namespace, metav1.CreateOptions{})
	if err != nil {
		panic(err)
	}

	// 創建一個測試 Pod,將 Namespace 設置為 owner
	pod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "test-pod",
			Namespace: "test-namespace",
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: "v1",
					Kind:       "Namespace",
					Name:       "test-namespace",
					UID:        namespace.UID,
					Controller: func(b bool) *bool { return &b }(true),
				},
			},
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  "nginx",
					Image: "nginx",
				},
			},
		},
	}
	_, err = clientset.CoreV1().Pods("test-namespace").Create(context.TODO(), pod, metav1.CreateOptions{})
	if err != nil {
		panic(err)
	}

	// 向 Pod 添加 finalizer
	podWithFinalizer, err := clientset.CoreV1().Pods("test-namespace").Get(context.TODO(), "test-pod", metav1.GetOptions{})
	if err != nil {
		panic(err)
	}
	podWithFinalizer.ObjectMeta.Finalizers = append(podWithFinalizer.ObjectMeta.Finalizers, "finalizer.example.com/cleanup")
	_, err = clientset.CoreV1().Pods("test-namespace").Update(context.TODO(), podWithFinalizer, metav1.UpdateOptions{})
	if err != nil {
		panic(err)
	}

	// 刪除 Pod,觸發 finalizer 清理邏輯
	err = clientset.CoreV1().Pods("test-namespace").Delete(context.TODO(), "test-pod", metav1.DeleteOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("Pod deletion triggered")

	// 在這里可以添加對 finalizer 的清理邏輯
	// 比如發送通知郵件等操作
}

0條評論
0 / 1000
yesplease
26文章數
1粉絲數
yesplease
26 文章 | 1 粉絲
原創

Kubernetes 對象所有者與依賴者

2024-03-14 01:23:57
0
0

所有者與依賴者

在 Kubernetes 中,所有者(owner)對象可以擁有(own)一個或多個依賴者(dependent)對象。所有者對象通常是控制器資源,比如 ReplicaSet、StatefulSet、Deployment 或 DaemonSet 等。這些控制器創建(即“擁有”)Pod,Pod 就是它們的依賴者。

所有者與依賴者的關系是通過 ControllerRef 字段建立的。ControllerRef 是一個字段,它指向創建它的控制器對象。每個 Kubernetes 對象都可以有一個 ControllerRef,但只能有一個。如果一個對象有多個所有者,那么它實際上沒有所有者。

垃圾收集

所有者與依賴者的關系在 Kubernetes 的垃圾收集(garbage collection)機制中發揮著重要作用。當所有者對象被刪除時,Kubernetes 垃圾收集器會負責刪除所有擁有該所有者的依賴者對象。這種機制有助于確保在刪除控制器時,其管理的所有 Pod 也會被相應地刪除。

垃圾收集器默認啟用,并且作用于所有具有 ControllerRef 的對象。但是,用戶可以通過設置對象的 metadata.finalizers 字段來禁用垃圾收集。當 finalizer 列表不為空時,Kubernetes 不會從 API 中刪除對象,即使刪除請求已經提交。這允許外部控制器在對象被刪除前執行任何必要的清理邏輯。

設置所有者引用

在創建依賴者對象時,可以通過在其 metadata 字段中包含 ownerReferences 字段來設置所有者引用。ownerReferences 字段是一個 OwnerReference 對象的列表,每個 OwnerReference 對象都表示一個對所有者對象的引用。

OwnerReference 對象包含以下字段:

  • apiVersion:所有者對象的 API 版本。
  • kind:所有者對象的種類。
  • name:所有者對象的名稱。
  • uid:所有者對象的唯一標識符。
  • controller:一個布爾值,表示此引用是否由 Kubernetes 控制器管理。如果為 true,則當所有者被刪除時,此依賴者也會被垃圾收集器刪除。
  • blockOwnerDeletion:如果為 true,則當存在任何具有此值的依賴者時,不可以刪除所有者對象。這可以防止級聯刪除。

使用場景

所有者與依賴者的概念在 Kubernetes 中有多種應用場景。以下是一些常見的例子:

  1. 控制器與 Pod:如前所述,控制器(如 Deployment、StatefulSet 等)創建并管理 Pod。在這種情況下,控制器是所有者,Pod 是依賴者。當控制器被刪除時,其管理的所有 Pod 也將被刪除。
  2. 自定義資源與依賴對象:當用戶定義自定義資源(Custom Resource, CR)并創建相應的控制器來管理這些資源時,自定義資源可以成為其他對象的所有者。例如,一個自定義的數據庫資源可以擁有一個用于存儲數據的 PersistentVolumeClaim。當數據庫資源被刪除時,相應的 PersistentVolumeClaim 也將被刪除。
  3. 防止級聯刪除:通過設置 blockOwnerDeletion 字段為 true,可以確保在刪除所有者對象之前不會刪除其依賴者。這在某些場景下非常有用,例如當依賴者對象包含重要數據或配置時,用戶可能希望在刪除所有者之前手動處理這些依賴者。

通過理解和利用所有者與依賴者的概念,用戶可以更有效地管理 Kubernetes 集群中的資源,并確保在刪除或更新對象時保持資源的完整性和一致性。

 

舉個例子,當你嘗試刪除一個仍然被 Pod 使用的 PersistentVolume 時,由于 PersistentVolume 上有 kubernetes.io/pv-protection finalizer,刪除操作不會立即生效。相反,該 PersistentVolume 會保持在 Terminating 狀態,直到 Kubernetes 清除了 finalizer,而這只會在 PersistentVolume 不再綁定到任何 Pod 時發生。

package main

import (
	"context"
	"flag"
	"fmt"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	kubeconfig := flag.String("kubeconfig", "", "Path to the kubeconfig file")
	flag.Parse()

	// 創建 Kubernetes 客戶端
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	// 創建一個測試 Namespace
	namespace := &corev1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name: "test-namespace",
		},
	}
	_, err = clientset.CoreV1().Namespaces().Create(context.TODO(), namespace, metav1.CreateOptions{})
	if err != nil {
		panic(err)
	}

	// 創建一個測試 Pod,將 Namespace 設置為 owner
	pod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "test-pod",
			Namespace: "test-namespace",
			OwnerReferences: []metav1.OwnerReference{
				{
					APIVersion: "v1",
					Kind:       "Namespace",
					Name:       "test-namespace",
					UID:        namespace.UID,
					Controller: func(b bool) *bool { return &b }(true),
				},
			},
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  "nginx",
					Image: "nginx",
				},
			},
		},
	}
	_, err = clientset.CoreV1().Pods("test-namespace").Create(context.TODO(), pod, metav1.CreateOptions{})
	if err != nil {
		panic(err)
	}

	// 向 Pod 添加 finalizer
	podWithFinalizer, err := clientset.CoreV1().Pods("test-namespace").Get(context.TODO(), "test-pod", metav1.GetOptions{})
	if err != nil {
		panic(err)
	}
	podWithFinalizer.ObjectMeta.Finalizers = append(podWithFinalizer.ObjectMeta.Finalizers, "finalizer.example.com/cleanup")
	_, err = clientset.CoreV1().Pods("test-namespace").Update(context.TODO(), podWithFinalizer, metav1.UpdateOptions{})
	if err != nil {
		panic(err)
	}

	// 刪除 Pod,觸發 finalizer 清理邏輯
	err = clientset.CoreV1().Pods("test-namespace").Delete(context.TODO(), "test-pod", metav1.DeleteOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("Pod deletion triggered")

	// 在這里可以添加對 finalizer 的清理邏輯
	// 比如發送通知郵件等操作
}

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0