原味地址
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的主要功能包括:
- 連接Kubernetes API服務器:client-go提供了一個API客戶端,用于連接Kubernetes API服務器,
- 物件管理:client-go提供了一組API,用于創建、讀取、更新和洗掉Kubernetes物件,如Pod、Deployment、Service等,
- Watch API:client-go提供了一個Watch API,可以用于監視Kubernetes物件的變化,
- 命名空間支持:client-go支持多個命名空間,并提供了一組API,用于管理命名空間,
- 認證和授權:client-go提供了一組API,用于執行身份驗證和授權,以確保只有授權的用戶才能對Kubernetes物件進行操作,
client-go是使用Kubernetes API的標準方式,是Kubernetes生態系統中的重要組成部分,
api client
client-go 中包含四種client,RestClient, ClientSet,DynamicClient和DiscoveryClient,

ClientSet,DynamicClient,DiscoveryClient都是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的主要功能包括:
- 提供方便的介面:Lister介面的方法定義清晰簡潔,使用起來非常方便,可以快速地獲取已經索引的資源物件串列,
- 提高代碼可讀性:通過使用Lister介面,代碼可讀性得到提高,開發者可以更加專注于業務邏輯,而無需關注底層的Indexer實作細節,
- 提高代碼復用性:由于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問題決議
