主頁 > 後端開發 > kubernetes client-go功能介紹

kubernetes client-go功能介紹

2023-02-28 07:20:43 後端開發

原味地址

https://haiyux.cc/2023/02/26/k8s-client-go/

client-go是什么?

client-go是Kubernetes官方提供的Go語言客戶端庫,用于與Kubernetes API服務器互動,使用client-go,您可以撰寫Go語言程式來創建、修改和洗掉Kubernetes物件,如Pod、Deployment、Service等,

作用

client-go的主要功能包括:

  1. 連接Kubernetes API服務器:client-go提供了一個API客戶端,用于連接Kubernetes API服務器,
  2. 物件管理:client-go提供了一組API,用于創建、讀取、更新和洗掉Kubernetes物件,如Pod、Deployment、Service等,
  3. Watch API:client-go提供了一個Watch API,可以用于監視Kubernetes物件的變化,
  4. 命名空間支持:client-go支持多個命名空間,并提供了一組API,用于管理命名空間,
  5. 認證和授權:client-go提供了一組API,用于執行身份驗證和授權,以確保只有授權的用戶才能對Kubernetes物件進行操作,

client-go是使用Kubernetes API的標準方式,是Kubernetes生態系統中的重要組成部分,

api client

client-go 中包含四種client,RestClient, ClientSetDynamicClientDiscoveryClient

ClientSetDynamicClientDiscoveryClient都是RestClient上的封裝

RestClient

RestClient是最基礎的客戶端,它基于HTTP請求進行了封裝,實作了RESTful API,使用RESTClient提供的RESTful方法,如Get()、Put()、Post()和Delete(),可以直接與API進行互動,同時,它支持JSON和Protocol Buffers,并支持所有原生資源和自定義資源定義(CRDs),然而,為了更加優雅地處理API互動,一般需要進一步封裝,通過Clientset對RESTClient進行封裝,然后再對外提供介面和服務,

package main

import (
	"context"
	"fmt"
	"path/filepath"

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


func main() {
	// 使用kubeconfig生成配置
	config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
	if err != nil {
		panic(err)
	}
	config.APIPath = "api"
	config.GroupVersion = &corev1.SchemeGroupVersion
	config.NegotiatedSerializer = scheme.Codecs

	// 生成restClient
	restClient, err := rest.RESTClientFor(config)
	if err != nil {
		panic(err)
	}

	rest := &corev1.PodList{}
	if err = restClient.Get().Namespace("default").Resource("pods").VersionedParams(&metav1.ListOptions{},
		scheme.ParameterCodec).Do(context.TODO()).Into(rest); err != nil {
		panic(err)
	}
	for _, v := range rest.Items {
		fmt.Printf("NameSpace: %v  Name: %v  Status: %v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

/*
結果
NameSpace: default  Name: nginx-76d6c9b8c-8ljkt  Status: Running 
NameSpace: default  Name: nginx-76d6c9b8c-jqv9h  Status: Running 
NameSpace: default  Name: nginx-76d6c9b8c-kr9d2  Status: Running 
NameSpace: default  Name: nginx-76d6c9b8c-m4g5l  Status: Running 
NameSpace: default  Name: nginx-76d6c9b8c-n8st9  Status: Running 
*/

ClientSet

ClientSet是在RestClient的基礎上封裝了對資源和版本的管理方法,資源可以理解為一個客戶端,而ClientSet是多個客戶端的集合,在操作資源物件時,需要指定Group和Version,然后根據資源獲取,然而,ClientSet不支持自定義資源定義(CRDs),但使用kubebuilder生成代碼時,會生成相應的ClientSet,

package main

import (
	"context"
	"fmt"
	"path/filepath"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

func main() {
	ctx := context.Background()
	// 使用kubeconfig生成配置 ~/.kube/config
	config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
	if err != nil {
		panic(err)
	}
	// 生成clientSet
	clientSet, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}
	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	for _, node := range nodeList.Items {
		fmt.Printf("nodeName: %v, status: %v \n", node.GetName(), node.GetCreationTimestamp())
	}
  // pod 是有namespace資源所以指定namespace 而node沒有
	pods, err := clientSet.CoreV1().Pods("default").List(ctx, metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	for _, v := range pods.Items {
		fmt.Printf("namespace: %v podName: %v status: %v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

/*
結果:
nodeName: minikube, status: 2023-01-27 18:45:35 +0800 CST 
nodeName: minikube-m02, status: 2023-02-26 21:19:30 +0800 CST 
nodeName: minikube-m03, status: 2023-02-26 21:19:38 +0800 CST 
namespace: default podName: nginx-76d6c9b8c-8ljkt status: Running 
namespace: default podName: nginx-76d6c9b8c-jqv9h status: Running 
namespace: default podName: nginx-76d6c9b8c-kr9d2 status: Running 
namespace: default podName: nginx-76d6c9b8c-m4g5l status: Running 
namespace: default podName: nginx-76d6c9b8c-n8st9 status: Running 
*/

DynamicClient

DynamicClient是一種動態客戶端,它可以對任何資源進行RESTful操作,包括自定義資源定義(CRD),與ClientSet不同,DynamicClient回傳的物件是一個map[string]interface{},如果一個控制器需要控制所有的API,可以使用DynamicClient,目前,DynamicClient在垃圾回收器和命名空間控制器中被廣泛使用,

DynamicClient的處理程序將Resource(例如PodList)轉換為unstructured型別,Kubernetes的所有資源都可以轉換為這個結構型別,處理完畢后,再將其轉換回PodList,整個轉換程序類似于介面轉換,即通過interface{}的斷言實作,

DynamicClient是一種動態的客戶端,它能處理Kubernetes所有的資源,但僅支持JSON

package main

import (
	"context"
	"fmt"
	"path/filepath"

	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

func main() {
	ctx := context.Background()
	// 使用kubeconfig生成配置 ~/.kube/config
	config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
	if err != nil {
		panic(err)
	}
	// dynamicClient
	dynamicClient, err := dynamic.NewForConfig(config)
	if err != nil {
		panic(err)
	}
	// 定義組版本資源
	gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
	unStructObj, err := dynamicClient.Resource(gvr).Namespace("default").List(ctx, metav1.ListOptions{})
	if err != nil {
		panic(err)
	}
	podList := &apiv1.PodList{}

	if err = runtime.DefaultUnstructuredConverter.FromUnstructured(unStructObj.UnstructuredContent(), podList); err != nil {
		panic(err)
	}

	for _, v := range podList.Items {
		fmt.Printf("namespaces:%v  podName:%v status:%v \n", v.Namespace, v.Name, v.Status.Phase)
	}
}

/*
namespaces:default  podName:nginx-76d6c9b8c-8ljkt status:Running
namespaces:default  podName:nginx-76d6c9b8c-jqv9h status:Running
namespaces:default  podName:nginx-76d6c9b8c-kr9d2 status:Running
namespaces:default  podName:nginx-76d6c9b8c-m4g5l status:Running
namespaces:default  podName:nginx-76d6c9b8c-n8st9 status:Running
*/

其中,GVR(group,version,resource) 用于標識 Kubernetes API 中的資源型別,其中 Group 表示 API 群組,Version 表示 API 版本,Resource 表示資源型別,例如,Deployment 的 GVR 為 "apps/v1/deployments",其中 "apps" 是 API 群組,"v1" 是 API 版本,"deployments" 是資源型別,

DiscoveryClient

DiscoveryClient 是一個發現客戶端,它的主要作用是用于發現 API Server 支持的資源組、資源版本和資源資訊,在 Kubernetes 中,API Server 支持很多資源組、資源版本和資源資訊,我們可以通過使用 DiscoveryClient 來查看這些資訊,此外,kubectl 的 API 版本和 API 資源也是通過 DiscoveryClient 來實作的,我們還可以將這些資訊快取到本地,以減輕 API 訪問的壓力,快取檔案默認存盤在 ./kube/cache./kube/http-cache 目錄下,

package main

import (
	"fmt"
	"path/filepath"

	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

func main() {
	// 使用kubeconfig生成配置 ~/.kube/config
	config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
	if err != nil {
		panic(err)
	}
	// 生成discoverClient
	discoverClient, err := discovery.NewDiscoveryClientForConfig(config)
	if err != nil {
		panic(err)
	}
	_, apiResourceList, err := discoverClient.ServerGroupsAndResources()
	for _, v := range apiResourceList {
		gv, err := schema.ParseGroupVersion(v.GroupVersion)
		if err != nil {
			panic(err)
		}
		for _, resource := range v.APIResources {
			fmt.Printf("name:%v group:%v version:%v\n", resource.Name, gv.Group, gv.Version)
		}
	}
}

/*
name:bindings group: version:v1
name:componentstatuses group: version:v1
name:configmaps group: version:v1
name:endpoints group: version:v1
name:events group: version:v1
name:limitranges group: version:v1
name:namespaces group: version:v1
name:namespaces/finalize group: version:v1
name:namespaces/status group: version:v1
name:nodes group: version:v1
name:nodes/proxy group: version:v1
name:nodes/status group: version:v1
name:persistentvolumeclaims group: version:v1
name:persistentvolumeclaims/status group: version:v1
name:persistentvolumes group: version:v1
name:persistentvolumes/status group: version:v1
name:pods group: version:v1
name:pods/attach group: version:v1
name:pods/binding group: version:v1
name:pods/ephemeralcontainers group: version:v1
name:pods/eviction group: version:v1
name:pods/exec group: version:v1
name:pods/log group: version:v1
name:pods/portforward group: version:v1
name:pods/proxy group: version:v1
name:pods/status group: version:v1
name:podtemplates group: version:v1
name:replicationcontrollers group: version:v1
name:replicationcontrollers/scale group: version:v1
name:replicationcontrollers/status group: version:v1
name:resourcequotas group: version:v1
name:resourcequotas/status group: version:v1
name:secrets group: version:v1
name:serviceaccounts group: version:v1
name:serviceaccounts/token group: version:v1
name:services group: version:v1
name:services/proxy group: version:v1
name:services/status group: version:v1
name:apiservices group:apiregistration.k8s.io version:v1
name:apiservices/status group:apiregistration.k8s.io version:v1
name:controllerrevisions group:apps version:v1
name:daemonsets group:apps version:v1
name:daemonsets/status group:apps version:v1
name:deployments group:apps version:v1
name:deployments/scale group:apps version:v1
name:deployments/status group:apps version:v1
name:replicasets group:apps version:v1
name:replicasets/scale group:apps version:v1
name:replicasets/status group:apps version:v1
name:statefulsets group:apps version:v1
name:statefulsets/scale group:apps version:v1
name:statefulsets/status group:apps version:v1
name:events group:events.k8s.io version:v1
name:tokenreviews group:authentication.k8s.io version:v1
name:localsubjectaccessreviews group:authorization.k8s.io version:v1
name:selfsubjectaccessreviews group:authorization.k8s.io version:v1
name:selfsubjectrulesreviews group:authorization.k8s.io version:v1
name:subjectaccessreviews group:authorization.k8s.io version:v1
name:horizontalpodautoscalers group:autoscaling version:v2
name:horizontalpodautoscalers/status group:autoscaling version:v2
name:horizontalpodautoscalers group:autoscaling version:v1
name:horizontalpodautoscalers/status group:autoscaling version:v1
name:horizontalpodautoscalers group:autoscaling version:v2beta2
name:horizontalpodautoscalers/status group:autoscaling version:v2beta2
name:cronjobs group:batch version:v1
name:cronjobs/status group:batch version:v1
name:jobs group:batch version:v1
name:jobs/status group:batch version:v1
name:certificatesigningrequests group:certificates.k8s.io version:v1
name:certificatesigningrequests/approval group:certificates.k8s.io version:v1
name:certificatesigningrequests/status group:certificates.k8s.io version:v1
name:ingressclasses group:networking.k8s.io version:v1
name:ingresses group:networking.k8s.io version:v1
name:ingresses/status group:networking.k8s.io version:v1
name:networkpolicies group:networking.k8s.io version:v1
name:networkpolicies/status group:networking.k8s.io version:v1
name:poddisruptionbudgets group:policy version:v1
name:poddisruptionbudgets/status group:policy version:v1
name:clusterrolebindings group:rbac.authorization.k8s.io version:v1
name:clusterroles group:rbac.authorization.k8s.io version:v1
name:rolebindings group:rbac.authorization.k8s.io version:v1
name:roles group:rbac.authorization.k8s.io version:v1
name:csidrivers group:storage.k8s.io version:v1
name:csinodes group:storage.k8s.io version:v1
name:csistoragecapacities group:storage.k8s.io version:v1
name:storageclasses group:storage.k8s.io version:v1
name:volumeattachments group:storage.k8s.io version:v1
name:volumeattachments/status group:storage.k8s.io version:v1
name:csistoragecapacities group:storage.k8s.io version:v1beta1
name:mutatingwebhookconfigurations group:admissionregistration.k8s.io version:v1
name:validatingwebhookconfigurations group:admissionregistration.k8s.io version:v1
name:customresourcedefinitions group:apiextensions.k8s.io version:v1
name:customresourcedefinitions/status group:apiextensions.k8s.io version:v1
name:priorityclasses group:scheduling.k8s.io version:v1
name:leases group:coordination.k8s.io version:v1
name:runtimeclasses group:node.k8s.io version:v1
name:endpointslices group:discovery.k8s.io version:v1
name:flowschemas group:flowcontrol.apiserver.k8s.io version:v1beta2
name:flowschemas/status group:flowcontrol.apiserver.k8s.io version:v1beta2
name:prioritylevelconfigurations group:flowcontrol.apiserver.k8s.io version:v1beta2
name:prioritylevelconfigurations/status group:flowcontrol.apiserver.k8s.io version:v1beta2
name:flowschemas group:flowcontrol.apiserver.k8s.io version:v1beta1
name:flowschemas/status group:flowcontrol.apiserver.k8s.io version:v1beta1
name:prioritylevelconfigurations group:flowcontrol.apiserver.k8s.io version:v1beta1
name:prioritylevelconfigurations/status group:flowcontrol.apiserver.k8s.io version:v1beta1
name:nodes group:metrics.k8s.io version:v1beta1
name:pods group:metrics.k8s.io version:v1beta1
*/

informer indexer lister機制

上圖展示了自定義控制器的作業方式,在虛線上方,是client-go包的informer和indexer作業方式,informer負責監聽Kubernetes API資源物件的變化,如創建、更新、洗掉等操作,并將這些變化通知給indexer進行索引和快取,而indexer則是將API物件進行索引,以便在需要時快速地訪問它們,lister則是對indexer的封裝,提供了一種簡單的方式來獲取已經索引的物件串列,以供代碼中的其他部分使用,這種分層結構的設計使得client-go可以高效地處理Kubernetes資源物件的變化,并在應用程式中方便地使用這些資源物件,

informer

Informer是Kubernetes API客戶端中一種重要的機制,它可以實作對資源物件的監視和事件通知,當Kubernetes集群中的資源物件發生變化時,Informer可以及時地獲取到這些變化,并將這些變化以事件的形式通知給相關的監聽器,Informer通過呼叫API Server提供的REST介面,以及Kubernetes中定義的watch機制,實作了對集群資源物件的全面監視,

下面是一個簡單的pod informer示例,用于監控所有pod的變化并將其放入佇列中,worker從佇列中取出pod并列印相關資訊,

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"
)

func main() {
	// 獲取 kubeconfig 檔案路徑
	kubeconfigPath := os.Getenv("KUBECONFIG")
	if kubeconfigPath == "" {
		kubeconfigPath = os.Getenv("HOME") + "/.kube/config"
	}

	// 使用 kubeconfig 檔案創建 kubernetes 客戶端
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	// 創建 informer 工廠
	informerFactory := informers.NewSharedInformerFactory(clientset, time.Minute)

	// 創建 informer 物件
	podInformer := informerFactory.Core().V1().Pods()

	// 創建作業佇列
	queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())

	// 定義處理新增、更新和洗掉事件的回呼函式
	podHandler := cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
		UpdateFunc: func(oldObj, newObj interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(newObj)
			if err == nil {
				queue.Add(key)
			}
		},
		DeleteFunc: func(obj interface{}) {
			key, err := cache.MetaNamespaceKeyFunc(obj)
			if err == nil {
				queue.Add(key)
			}
		},
	}

	// 將回呼函式注冊到 informer 上
	podInformer.Informer().AddEventHandler(podHandler)

	// 啟動 informer
	stopCh := make(chan struct{})
	defer close(stopCh)
	informerFactory.Start(stopCh)

	// 等待 informer 同步完成
	if !cache.WaitForCacheSync(stopCh) {
		panic("同步 informer 快取失敗")
	}

	// 創建信號處理程式,用于捕捉 SIGTERM 和 SIGINT 信號
	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, syscall.SIGTERM, syscall.SIGINT)

	// 創建 worker 函式,用于處理佇列中的事件
	processNextItem := func() {
		obj, shutdown := queue.Get()
		if shutdown {
			return
		}

		// 轉換物件為 Pod
		key := obj.(string)
		podObj, exists, err := podInformer.Informer().GetIndexer().GetByKey(key)
		if err != nil {
			queue.Forget(obj)
			panic(fmt.Sprintf("獲取 Pod 失敗:%v", err))
		}

		if !exists {
			// 如果物件已經被洗掉,就把它從佇列中移除
			queue.Forget(obj)
			return
		}

		// 在這里添加處理 Pod 的邏輯
		pod := podObj.(*v1.Pod)
		fmt.Printf("處理 Pod: namespace:%v,podName:%v\n", pod.Namespace, pod.Name)

		// 處理完事件后,把它從佇列中移除
		queue.Forget(obj)
		return
	}

	// 啟動 worker
	go wait.Until(processNextItem, time.Second, stopCh)

	// 等待信號
	<-signalCh
}

/*
處理 Pod: namespace:kube-system,podName:kindnet-h25kv
處理 Pod: namespace:kube-system,podName:kube-apiserver-minikube
處理 Pod: namespace:kube-system,podName:metrics-server-c9fb666df-zk4tb
處理 Pod: namespace:kubernetes-dashboard,podName:dashboard-metrics-scraper-b74747df5-4pb7w
處理 Pod: namespace:default,podName:nginx-76d6c9b8c-jqv9h
處理 Pod: namespace:default,podName:nginx-76d6c9b8c-m4g5l
處理 Pod: namespace:kube-system,podName:coredns-7f8cbcb969-48nz6
處理 Pod: namespace:kube-system,podName:kube-proxy-t766g
處理 Pod: namespace:kube-system,podName:kube-scheduler-minikube
處理 Pod: namespace:kube-system,podName:kindnet-44zl6
處理 Pod: namespace:kube-system,podName:kube-controller-manager-minikube
處理 Pod: namespace:kube-system,podName:kube-proxy-gq68w
處理 Pod: namespace:kube-system,podName:kube-proxy-l92vg
處理 Pod: namespace:kube-system,podName:storage-provisioner
處理 Pod: namespace:kubernetes-dashboard,podName:kubernetes-dashboard-57bbdc5f89-466rh
處理 Pod: namespace:default,podName:nginx-76d6c9b8c-kr9d2
處理 Pod: namespace:default,podName:nginx-76d6c9b8c-n8st9
處理 Pod: namespace:kube-system,podName:kindnet-w9f7t
處理 Pod: namespace:default,podName:nginx-76d6c9b8c-8ljkt
處理 Pod: namespace:kube-system,podName:etcd-minikube
處理 Pod: namespace:default,podName:nginx
處理 Pod: namespace:default,podName:ubuntu
*/

indexer

Indexer是client-go中用于本地快取資源物件的一種方式,它支持多種索引方式,并且可以使用函式func(obj interface{}) ([]string, error)進行索引,在檢索時,需要使用相同的indexName引數,借助informer,indexer就可以維護一個特定資源的本地快取,例如pod、namespace等,這種方法省去了每次get pod都要訪問api-server的程序,從而減小了api-server的壓力,

// 如何使用索引器來檢索Pod物件
package main

import (
	"fmt"

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

const (
	NamespaceIndexName = "namespace" // 定義一個索引器名稱,用于按照命名空間檢索Pod
	NodeNameIndexName  = "nodeName"  // 定義一個索引器名稱,用于按照節點名稱檢索Pod
)

// NamespaceIndexFunc是一個函式,用于從物件中提取命名空間作為索引鍵
func NamespaceIndexFunc(obj interface{}) ([]string, error) {
	m, err := meta.Accessor(obj) // 獲取物件的元資料
	if err != nil {
		return []string{""}, fmt.Errorf("object has no meta: %v", err)
	}
	return []string{m.GetNamespace()}, nil // 回傳物件的命名空間
}

// NodeNameIndexFunc是一個函式,用于從Pod物件中提取節點名稱作為索引鍵
func NodeNameIndexFunc(obj interface{}) ([]string, error) {
	pod, ok := obj.(*v1.Pod) // 判斷物件是否是Pod型別
	if !ok {
		return []string{}, nil // 如果不是,回傳空切片
	}
	return []string{pod.Spec.NodeName}, nil // 如果是,回傳Pod的節點名稱
}

func main() {
	index := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{
		NamespaceIndexName: NamespaceIndexFunc,
		NodeNameIndexName:  NodeNameIndexFunc,
	}) // 創建一個新的索引器,指定主鍵函式和輔助鍵函式

	pod1 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-1",
			Namespace: "default",
		},
		Spec: v1.PodSpec{NodeName: "node1"},
	} // 創建一個Pod物件,屬于default命名空間和node1節點

	pod2 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-2",
			Namespace: "default",
		},
		Spec: v1.PodSpec{NodeName: "node2"},
	} // 創建另一個Pod物件,屬于default命名空間和node2節點

	pod3 := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "index-pod-3",
			Namespace: "kube-system",
		},
		Spec: v1.PodSpec{NodeName: "node2"},
	} // 創建第三個Pod物件,屬于kube-system命名空間和node2節點

	index.Add(pod1) // 將pod1添加到索引器中
	index.Add(pod2) // 將pod2添加到索引器中
	index.Add(pod3) // 將pod3添加到索引器中

	pods, err := index.ByIndex(NamespaceIndexName, "default") // 按照命名空間為default檢索Pod串列
	if err != nil {
		panic(err)
	}
	for _, pod := range pods {
		fmt.Println(pod.(*v1.Pod).Name)
	} // 遍歷并列印檢索到的Pod名稱

	fmt.Println("*****************")

	pods, err = index.ByIndex(NodeNameIndexName, "node2") // 按照節點名稱為node2檢索Pod串列
	if err != nil {
		panic(err)
	}
	for _, pod := range pods {
		fmt.Println(pod.(*v1.Pod).Name)
	} // 遍歷并列印
}

/*
index-pod-2
index-pod-1
*****************
index-pod-2
index-pod-3
*/

lister

Lister是對Indexer的封裝,提供了一種方便的方式來獲取已經索引的Kubernetes資源物件串列,

具體而言,Lister是一個介面,包含了獲取所有已索引物件的串列以及根據名稱獲取單個物件的方法,這些方法可以幫助開發者在應用程式中快速訪問已經快取的資源物件,而無需直接與Indexer互動,

Lister的主要功能包括:

  1. 提供方便的介面:Lister介面的方法定義清晰簡潔,使用起來非常方便,可以快速地獲取已經索引的資源物件串列,
  2. 提高代碼可讀性:通過使用Lister介面,代碼可讀性得到提高,開發者可以更加專注于業務邏輯,而無需關注底層的Indexer實作細節,
  3. 提高代碼復用性:由于Lister介面已經提供了通用的方法,因此可以更容易地在不同的代碼模塊中重用相同的邏輯,減少代碼重復,

總之,Lister作為client-go包中的一個重要組件,可以幫助開發者更加高效地處理Kubernetes資源物件,提高代碼的可讀性和可重用性,

package main

import (
	"fmt"
	"os"
	"time"

	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 獲取 kubeconfig 檔案路徑
	kubeconfigPath := os.Getenv("KUBECONFIG")
	if kubeconfigPath == "" {
		kubeconfigPath = os.Getenv("HOME") + "/.kube/config"
	}
	// 使用 kubeconfig 檔案創建 kubernetes 客戶端
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
	if err != nil {
		panic(err)
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}

	// 創建Informer
	factory := informers.NewSharedInformerFactory(clientset, time.Minute)
	podInformer := factory.Core().V1().Pods()

	// 創建Lister
	lister := podInformer.Lister()

	// 等待Informer同步完成
	stopCh := make(chan struct{})
	defer close(stopCh)

	factory.Start(stopCh)
	cache.WaitForCacheSync(stopCh, podInformer.Informer().HasSynced)

	// 獲取namespace為"default"的Pod物件
	podList, err := lister.Pods("default").List(labels.Everything())
	if err != nil {
		panic(err.Error())
	}
	// 列印Pod物件
	for _, pod := range podList {
		fmt.Printf("Pod name: %s, Namespace: %s\n", pod.Name, pod.Namespace)
	}
}

/*
Pod name: nginx-76d6c9b8c-m4g5l, Namespace: default
Pod name: nginx, Namespace: default
Pod name: ubuntu, Namespace: default
Pod name: nginx-76d6c9b8c-kr9d2, Namespace: default
Pod name: nginx-76d6c9b8c-n8st9, Namespace: default
Pod name: nginx-76d6c9b8c-8ljkt, Namespace: default
Pod name: nginx-76d6c9b8c-jqv9h, Namespace: default
*/

Reference

  • sample-controller/controller-client-go.md at master · kubernetes/sample-controller (github.com)
  • K8s二開之 client-go 初探 - 掘金 (juejin.cn)

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/545197.html

標籤:其他

上一篇:Django uwsgi問題決議

下一篇:聽說大家很感興趣瑋子的學習心得,采訪來了

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more