经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Kubernetes » 查看文章
kubernetes client-go功能介绍
来源:cnblogs  作者:haiyux  时间:2023/2/28 8:51:37  对本文有异议

原味地址

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进行封装,然后再对外提供接口和服务。

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "path/filepath"
  6. corev1 "k8s.io/api/core/v1"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. "k8s.io/client-go/kubernetes/scheme"
  9. "k8s.io/client-go/rest"
  10. "k8s.io/client-go/tools/clientcmd"
  11. "k8s.io/client-go/util/homedir"
  12. )
  13. func main() {
  14. // 使用kubeconfig生成配置
  15. config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
  16. if err != nil {
  17. panic(err)
  18. }
  19. config.APIPath = "api"
  20. config.GroupVersion = &corev1.SchemeGroupVersion
  21. config.NegotiatedSerializer = scheme.Codecs
  22. // 生成restClient
  23. restClient, err := rest.RESTClientFor(config)
  24. if err != nil {
  25. panic(err)
  26. }
  27. rest := &corev1.PodList{}
  28. if err = restClient.Get().Namespace("default").Resource("pods").VersionedParams(&metav1.ListOptions{},
  29. scheme.ParameterCodec).Do(context.TODO()).Into(rest); err != nil {
  30. panic(err)
  31. }
  32. for _, v := range rest.Items {
  33. fmt.Printf("NameSpace: %v Name: %v Status: %v \n", v.Namespace, v.Name, v.Status.Phase)
  34. }
  35. }
  36. /*
  37. 结果
  38. NameSpace: default Name: nginx-76d6c9b8c-8ljkt Status: Running
  39. NameSpace: default Name: nginx-76d6c9b8c-jqv9h Status: Running
  40. NameSpace: default Name: nginx-76d6c9b8c-kr9d2 Status: Running
  41. NameSpace: default Name: nginx-76d6c9b8c-m4g5l Status: Running
  42. NameSpace: default Name: nginx-76d6c9b8c-n8st9 Status: Running
  43. */

ClientSet

ClientSet是在RestClient的基础上封装了对资源和版本的管理方法。资源可以理解为一个客户端,而ClientSet是多个客户端的集合。在操作资源对象时,需要指定Group和Version,然后根据资源获取。然而,ClientSet不支持自定义资源定义(CRDs),但使用kubebuilder生成代码时,会生成相应的ClientSet。

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "path/filepath"
  6. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  7. "k8s.io/client-go/kubernetes"
  8. "k8s.io/client-go/tools/clientcmd"
  9. "k8s.io/client-go/util/homedir"
  10. )
  11. func main() {
  12. ctx := context.Background()
  13. // 使用kubeconfig生成配置 ~/.kube/config
  14. config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
  15. if err != nil {
  16. panic(err)
  17. }
  18. // 生成clientSet
  19. clientSet, err := kubernetes.NewForConfig(config)
  20. if err != nil {
  21. panic(err)
  22. }
  23. nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
  24. if err != nil {
  25. panic(err)
  26. }
  27. for _, node := range nodeList.Items {
  28. fmt.Printf("nodeName: %v, status: %v \n", node.GetName(), node.GetCreationTimestamp())
  29. }
  30. // pod 是有namespace资源所以指定namespace 而node没有
  31. pods, err := clientSet.CoreV1().Pods("default").List(ctx, metav1.ListOptions{})
  32. if err != nil {
  33. panic(err)
  34. }
  35. for _, v := range pods.Items {
  36. fmt.Printf("namespace: %v podName: %v status: %v \n", v.Namespace, v.Name, v.Status.Phase)
  37. }
  38. }
  39. /*
  40. 结果:
  41. nodeName: minikube, status: 2023-01-27 18:45:35 +0800 CST
  42. nodeName: minikube-m02, status: 2023-02-26 21:19:30 +0800 CST
  43. nodeName: minikube-m03, status: 2023-02-26 21:19:38 +0800 CST
  44. namespace: default podName: nginx-76d6c9b8c-8ljkt status: Running
  45. namespace: default podName: nginx-76d6c9b8c-jqv9h status: Running
  46. namespace: default podName: nginx-76d6c9b8c-kr9d2 status: Running
  47. namespace: default podName: nginx-76d6c9b8c-m4g5l status: Running
  48. namespace: default podName: nginx-76d6c9b8c-n8st9 status: Running
  49. */

DynamicClient

DynamicClient是一种动态客户端,它可以对任何资源进行RESTful操作,包括自定义资源定义(CRD)。与ClientSet不同,DynamicClient返回的对象是一个map[string]interface{}。如果一个控制器需要控制所有的API,可以使用DynamicClient。目前,DynamicClient在垃圾回收器和命名空间控制器中被广泛使用。

DynamicClient的处理过程将Resource(例如PodList)转换为unstructured类型。Kubernetes的所有资源都可以转换为这个结构类型。处理完毕后,再将其转换回PodList。整个转换过程类似于接口转换,即通过interface{}的断言实现。

DynamicClient是一种动态的客户端,它能处理Kubernetes所有的资源,但仅支持JSON

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "path/filepath"
  6. apiv1 "k8s.io/api/core/v1"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. "k8s.io/apimachinery/pkg/runtime"
  9. "k8s.io/apimachinery/pkg/runtime/schema"
  10. "k8s.io/client-go/dynamic"
  11. "k8s.io/client-go/tools/clientcmd"
  12. "k8s.io/client-go/util/homedir"
  13. )
  14. func main() {
  15. ctx := context.Background()
  16. // 使用kubeconfig生成配置 ~/.kube/config
  17. config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
  18. if err != nil {
  19. panic(err)
  20. }
  21. // dynamicClient
  22. dynamicClient, err := dynamic.NewForConfig(config)
  23. if err != nil {
  24. panic(err)
  25. }
  26. // 定义组版本资源
  27. gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
  28. unStructObj, err := dynamicClient.Resource(gvr).Namespace("default").List(ctx, metav1.ListOptions{})
  29. if err != nil {
  30. panic(err)
  31. }
  32. podList := &apiv1.PodList{}
  33. if err = runtime.DefaultUnstructuredConverter.FromUnstructured(unStructObj.UnstructuredContent(), podList); err != nil {
  34. panic(err)
  35. }
  36. for _, v := range podList.Items {
  37. fmt.Printf("namespaces:%v podName:%v status:%v \n", v.Namespace, v.Name, v.Status.Phase)
  38. }
  39. }
  40. /*
  41. namespaces:default podName:nginx-76d6c9b8c-8ljkt status:Running
  42. namespaces:default podName:nginx-76d6c9b8c-jqv9h status:Running
  43. namespaces:default podName:nginx-76d6c9b8c-kr9d2 status:Running
  44. namespaces:default podName:nginx-76d6c9b8c-m4g5l status:Running
  45. namespaces:default podName:nginx-76d6c9b8c-n8st9 status:Running
  46. */

其中,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 目录下。

  1. package main
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "k8s.io/apimachinery/pkg/runtime/schema"
  6. "k8s.io/client-go/discovery"
  7. "k8s.io/client-go/tools/clientcmd"
  8. "k8s.io/client-go/util/homedir"
  9. )
  10. func main() {
  11. // 使用kubeconfig生成配置 ~/.kube/config
  12. config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(homedir.HomeDir(), ".kube", "config"))
  13. if err != nil {
  14. panic(err)
  15. }
  16. // 生成discoverClient
  17. discoverClient, err := discovery.NewDiscoveryClientForConfig(config)
  18. if err != nil {
  19. panic(err)
  20. }
  21. _, apiResourceList, err := discoverClient.ServerGroupsAndResources()
  22. for _, v := range apiResourceList {
  23. gv, err := schema.ParseGroupVersion(v.GroupVersion)
  24. if err != nil {
  25. panic(err)
  26. }
  27. for _, resource := range v.APIResources {
  28. fmt.Printf("name:%v group:%v version:%v\n", resource.Name, gv.Group, gv.Version)
  29. }
  30. }
  31. }
  32. /*
  33. name:bindings group: version:v1
  34. name:componentstatuses group: version:v1
  35. name:configmaps group: version:v1
  36. name:endpoints group: version:v1
  37. name:events group: version:v1
  38. name:limitranges group: version:v1
  39. name:namespaces group: version:v1
  40. name:namespaces/finalize group: version:v1
  41. name:namespaces/status group: version:v1
  42. name:nodes group: version:v1
  43. name:nodes/proxy group: version:v1
  44. name:nodes/status group: version:v1
  45. name:persistentvolumeclaims group: version:v1
  46. name:persistentvolumeclaims/status group: version:v1
  47. name:persistentvolumes group: version:v1
  48. name:persistentvolumes/status group: version:v1
  49. name:pods group: version:v1
  50. name:pods/attach group: version:v1
  51. name:pods/binding group: version:v1
  52. name:pods/ephemeralcontainers group: version:v1
  53. name:pods/eviction group: version:v1
  54. name:pods/exec group: version:v1
  55. name:pods/log group: version:v1
  56. name:pods/portforward group: version:v1
  57. name:pods/proxy group: version:v1
  58. name:pods/status group: version:v1
  59. name:podtemplates group: version:v1
  60. name:replicationcontrollers group: version:v1
  61. name:replicationcontrollers/scale group: version:v1
  62. name:replicationcontrollers/status group: version:v1
  63. name:resourcequotas group: version:v1
  64. name:resourcequotas/status group: version:v1
  65. name:secrets group: version:v1
  66. name:serviceaccounts group: version:v1
  67. name:serviceaccounts/token group: version:v1
  68. name:services group: version:v1
  69. name:services/proxy group: version:v1
  70. name:services/status group: version:v1
  71. name:apiservices group:apiregistration.k8s.io version:v1
  72. name:apiservices/status group:apiregistration.k8s.io version:v1
  73. name:controllerrevisions group:apps version:v1
  74. name:daemonsets group:apps version:v1
  75. name:daemonsets/status group:apps version:v1
  76. name:deployments group:apps version:v1
  77. name:deployments/scale group:apps version:v1
  78. name:deployments/status group:apps version:v1
  79. name:replicasets group:apps version:v1
  80. name:replicasets/scale group:apps version:v1
  81. name:replicasets/status group:apps version:v1
  82. name:statefulsets group:apps version:v1
  83. name:statefulsets/scale group:apps version:v1
  84. name:statefulsets/status group:apps version:v1
  85. name:events group:events.k8s.io version:v1
  86. name:tokenreviews group:authentication.k8s.io version:v1
  87. name:localsubjectaccessreviews group:authorization.k8s.io version:v1
  88. name:selfsubjectaccessreviews group:authorization.k8s.io version:v1
  89. name:selfsubjectrulesreviews group:authorization.k8s.io version:v1
  90. name:subjectaccessreviews group:authorization.k8s.io version:v1
  91. name:horizontalpodautoscalers group:autoscaling version:v2
  92. name:horizontalpodautoscalers/status group:autoscaling version:v2
  93. name:horizontalpodautoscalers group:autoscaling version:v1
  94. name:horizontalpodautoscalers/status group:autoscaling version:v1
  95. name:horizontalpodautoscalers group:autoscaling version:v2beta2
  96. name:horizontalpodautoscalers/status group:autoscaling version:v2beta2
  97. name:cronjobs group:batch version:v1
  98. name:cronjobs/status group:batch version:v1
  99. name:jobs group:batch version:v1
  100. name:jobs/status group:batch version:v1
  101. name:certificatesigningrequests group:certificates.k8s.io version:v1
  102. name:certificatesigningrequests/approval group:certificates.k8s.io version:v1
  103. name:certificatesigningrequests/status group:certificates.k8s.io version:v1
  104. name:ingressclasses group:networking.k8s.io version:v1
  105. name:ingresses group:networking.k8s.io version:v1
  106. name:ingresses/status group:networking.k8s.io version:v1
  107. name:networkpolicies group:networking.k8s.io version:v1
  108. name:networkpolicies/status group:networking.k8s.io version:v1
  109. name:poddisruptionbudgets group:policy version:v1
  110. name:poddisruptionbudgets/status group:policy version:v1
  111. name:clusterrolebindings group:rbac.authorization.k8s.io version:v1
  112. name:clusterroles group:rbac.authorization.k8s.io version:v1
  113. name:rolebindings group:rbac.authorization.k8s.io version:v1
  114. name:roles group:rbac.authorization.k8s.io version:v1
  115. name:csidrivers group:storage.k8s.io version:v1
  116. name:csinodes group:storage.k8s.io version:v1
  117. name:csistoragecapacities group:storage.k8s.io version:v1
  118. name:storageclasses group:storage.k8s.io version:v1
  119. name:volumeattachments group:storage.k8s.io version:v1
  120. name:volumeattachments/status group:storage.k8s.io version:v1
  121. name:csistoragecapacities group:storage.k8s.io version:v1beta1
  122. name:mutatingwebhookconfigurations group:admissionregistration.k8s.io version:v1
  123. name:validatingwebhookconfigurations group:admissionregistration.k8s.io version:v1
  124. name:customresourcedefinitions group:apiextensions.k8s.io version:v1
  125. name:customresourcedefinitions/status group:apiextensions.k8s.io version:v1
  126. name:priorityclasses group:scheduling.k8s.io version:v1
  127. name:leases group:coordination.k8s.io version:v1
  128. name:runtimeclasses group:node.k8s.io version:v1
  129. name:endpointslices group:discovery.k8s.io version:v1
  130. name:flowschemas group:flowcontrol.apiserver.k8s.io version:v1beta2
  131. name:flowschemas/status group:flowcontrol.apiserver.k8s.io version:v1beta2
  132. name:prioritylevelconfigurations group:flowcontrol.apiserver.k8s.io version:v1beta2
  133. name:prioritylevelconfigurations/status group:flowcontrol.apiserver.k8s.io version:v1beta2
  134. name:flowschemas group:flowcontrol.apiserver.k8s.io version:v1beta1
  135. name:flowschemas/status group:flowcontrol.apiserver.k8s.io version:v1beta1
  136. name:prioritylevelconfigurations group:flowcontrol.apiserver.k8s.io version:v1beta1
  137. name:prioritylevelconfigurations/status group:flowcontrol.apiserver.k8s.io version:v1beta1
  138. name:nodes group:metrics.k8s.io version:v1beta1
  139. name:pods group:metrics.k8s.io version:v1beta1
  140. */

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并打印相关信息。

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/signal"
  6. "syscall"
  7. "time"
  8. v1 "k8s.io/api/core/v1"
  9. "k8s.io/apimachinery/pkg/util/wait"
  10. "k8s.io/client-go/informers"
  11. "k8s.io/client-go/kubernetes"
  12. "k8s.io/client-go/tools/cache"
  13. "k8s.io/client-go/tools/clientcmd"
  14. "k8s.io/client-go/util/workqueue"
  15. )
  16. func main() {
  17. // 获取 kubeconfig 文件路径
  18. kubeconfigPath := os.Getenv("KUBECONFIG")
  19. if kubeconfigPath == "" {
  20. kubeconfigPath = os.Getenv("HOME") + "/.kube/config"
  21. }
  22. // 使用 kubeconfig 文件创建 kubernetes 客户端
  23. config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
  24. if err != nil {
  25. panic(err)
  26. }
  27. clientset, err := kubernetes.NewForConfig(config)
  28. if err != nil {
  29. panic(err)
  30. }
  31. // 创建 informer 工厂
  32. informerFactory := informers.NewSharedInformerFactory(clientset, time.Minute)
  33. // 创建 informer 对象
  34. podInformer := informerFactory.Core().V1().Pods()
  35. // 创建工作队列
  36. queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
  37. // 定义处理新增、更新和删除事件的回调函数
  38. podHandler := cache.ResourceEventHandlerFuncs{
  39. AddFunc: func(obj interface{}) {
  40. key, err := cache.MetaNamespaceKeyFunc(obj)
  41. if err == nil {
  42. queue.Add(key)
  43. }
  44. },
  45. UpdateFunc: func(oldObj, newObj interface{}) {
  46. key, err := cache.MetaNamespaceKeyFunc(newObj)
  47. if err == nil {
  48. queue.Add(key)
  49. }
  50. },
  51. DeleteFunc: func(obj interface{}) {
  52. key, err := cache.MetaNamespaceKeyFunc(obj)
  53. if err == nil {
  54. queue.Add(key)
  55. }
  56. },
  57. }
  58. // 将回调函数注册到 informer 上
  59. podInformer.Informer().AddEventHandler(podHandler)
  60. // 启动 informer
  61. stopCh := make(chan struct{})
  62. defer close(stopCh)
  63. informerFactory.Start(stopCh)
  64. // 等待 informer 同步完成
  65. if !cache.WaitForCacheSync(stopCh) {
  66. panic("同步 informer 缓存失败")
  67. }
  68. // 创建信号处理程序,用于捕捉 SIGTERM 和 SIGINT 信号
  69. signalCh := make(chan os.Signal, 1)
  70. signal.Notify(signalCh, syscall.SIGTERM, syscall.SIGINT)
  71. // 创建 worker 函数,用于处理队列中的事件
  72. processNextItem := func() {
  73. obj, shutdown := queue.Get()
  74. if shutdown {
  75. return
  76. }
  77. // 转换对象为 Pod
  78. key := obj.(string)
  79. podObj, exists, err := podInformer.Informer().GetIndexer().GetByKey(key)
  80. if err != nil {
  81. queue.Forget(obj)
  82. panic(fmt.Sprintf("获取 Pod 失败:%v", err))
  83. }
  84. if !exists {
  85. // 如果对象已经被删除,就把它从队列中移除
  86. queue.Forget(obj)
  87. return
  88. }
  89. // 在这里添加处理 Pod 的逻辑
  90. pod := podObj.(*v1.Pod)
  91. fmt.Printf("处理 Pod: namespace:%v,podName:%v\n", pod.Namespace, pod.Name)
  92. // 处理完事件后,把它从队列中移除
  93. queue.Forget(obj)
  94. return
  95. }
  96. // 启动 worker
  97. go wait.Until(processNextItem, time.Second, stopCh)
  98. // 等待信号
  99. <-signalCh
  100. }
  101. /*
  102. 处理 Pod: namespace:kube-system,podName:kindnet-h25kv
  103. 处理 Pod: namespace:kube-system,podName:kube-apiserver-minikube
  104. 处理 Pod: namespace:kube-system,podName:metrics-server-c9fb666df-zk4tb
  105. 处理 Pod: namespace:kubernetes-dashboard,podName:dashboard-metrics-scraper-b74747df5-4pb7w
  106. 处理 Pod: namespace:default,podName:nginx-76d6c9b8c-jqv9h
  107. 处理 Pod: namespace:default,podName:nginx-76d6c9b8c-m4g5l
  108. 处理 Pod: namespace:kube-system,podName:coredns-7f8cbcb969-48nz6
  109. 处理 Pod: namespace:kube-system,podName:kube-proxy-t766g
  110. 处理 Pod: namespace:kube-system,podName:kube-scheduler-minikube
  111. 处理 Pod: namespace:kube-system,podName:kindnet-44zl6
  112. 处理 Pod: namespace:kube-system,podName:kube-controller-manager-minikube
  113. 处理 Pod: namespace:kube-system,podName:kube-proxy-gq68w
  114. 处理 Pod: namespace:kube-system,podName:kube-proxy-l92vg
  115. 处理 Pod: namespace:kube-system,podName:storage-provisioner
  116. 处理 Pod: namespace:kubernetes-dashboard,podName:kubernetes-dashboard-57bbdc5f89-466rh
  117. 处理 Pod: namespace:default,podName:nginx-76d6c9b8c-kr9d2
  118. 处理 Pod: namespace:default,podName:nginx-76d6c9b8c-n8st9
  119. 处理 Pod: namespace:kube-system,podName:kindnet-w9f7t
  120. 处理 Pod: namespace:default,podName:nginx-76d6c9b8c-8ljkt
  121. 处理 Pod: namespace:kube-system,podName:etcd-minikube
  122. 处理 Pod: namespace:default,podName:nginx
  123. 处理 Pod: namespace:default,podName:ubuntu
  124. */

indexer

Indexer是client-go中用于本地缓存资源对象的一种方式。它支持多种索引方式,并且可以使用函数func(obj interface{}) ([]string, error)进行索引。在检索时,需要使用相同的indexName参数。借助informer,indexer就可以维护一个特定资源的本地缓存,例如pod、namespace等。这种方法省去了每次get pod都要访问api-server的过程,从而减小了api-server的压力。

  1. // 如何使用索引器来检索Pod对象
  2. package main
  3. import (
  4. "fmt"
  5. v1 "k8s.io/api/core/v1"
  6. "k8s.io/apimachinery/pkg/api/meta"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. "k8s.io/client-go/tools/cache"
  9. )
  10. const (
  11. NamespaceIndexName = "namespace" // 定义一个索引器名称,用于按照命名空间检索Pod
  12. NodeNameIndexName = "nodeName" // 定义一个索引器名称,用于按照节点名称检索Pod
  13. )
  14. // NamespaceIndexFunc是一个函数,用于从对象中提取命名空间作为索引键
  15. func NamespaceIndexFunc(obj interface{}) ([]string, error) {
  16. m, err := meta.Accessor(obj) // 获取对象的元数据
  17. if err != nil {
  18. return []string{""}, fmt.Errorf("object has no meta: %v", err)
  19. }
  20. return []string{m.GetNamespace()}, nil // 返回对象的命名空间
  21. }
  22. // NodeNameIndexFunc是一个函数,用于从Pod对象中提取节点名称作为索引键
  23. func NodeNameIndexFunc(obj interface{}) ([]string, error) {
  24. pod, ok := obj.(*v1.Pod) // 判断对象是否是Pod类型
  25. if !ok {
  26. return []string{}, nil // 如果不是,返回空切片
  27. }
  28. return []string{pod.Spec.NodeName}, nil // 如果是,返回Pod的节点名称
  29. }
  30. func main() {
  31. index := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{
  32. NamespaceIndexName: NamespaceIndexFunc,
  33. NodeNameIndexName: NodeNameIndexFunc,
  34. }) // 创建一个新的索引器,指定主键函数和辅助键函数
  35. pod1 := &v1.Pod{
  36. ObjectMeta: metav1.ObjectMeta{
  37. Name: "index-pod-1",
  38. Namespace: "default",
  39. },
  40. Spec: v1.PodSpec{NodeName: "node1"},
  41. } // 创建一个Pod对象,属于default命名空间和node1节点
  42. pod2 := &v1.Pod{
  43. ObjectMeta: metav1.ObjectMeta{
  44. Name: "index-pod-2",
  45. Namespace: "default",
  46. },
  47. Spec: v1.PodSpec{NodeName: "node2"},
  48. } // 创建另一个Pod对象,属于default命名空间和node2节点
  49. pod3 := &v1.Pod{
  50. ObjectMeta: metav1.ObjectMeta{
  51. Name: "index-pod-3",
  52. Namespace: "kube-system",
  53. },
  54. Spec: v1.PodSpec{NodeName: "node2"},
  55. } // 创建第三个Pod对象,属于kube-system命名空间和node2节点
  56. index.Add(pod1) // 将pod1添加到索引器中
  57. index.Add(pod2) // 将pod2添加到索引器中
  58. index.Add(pod3) // 将pod3添加到索引器中
  59. pods, err := index.ByIndex(NamespaceIndexName, "default") // 按照命名空间为default检索Pod列表
  60. if err != nil {
  61. panic(err)
  62. }
  63. for _, pod := range pods {
  64. fmt.Println(pod.(*v1.Pod).Name)
  65. } // 遍历并打印检索到的Pod名称
  66. fmt.Println("*****************")
  67. pods, err = index.ByIndex(NodeNameIndexName, "node2") // 按照节点名称为node2检索Pod列表
  68. if err != nil {
  69. panic(err)
  70. }
  71. for _, pod := range pods {
  72. fmt.Println(pod.(*v1.Pod).Name)
  73. } // 遍历并打印
  74. }
  75. /*
  76. index-pod-2
  77. index-pod-1
  78. *****************
  79. index-pod-2
  80. index-pod-3
  81. */

lister

Lister是对Indexer的封装,提供了一种方便的方式来获取已经索引的Kubernetes资源对象列表。

具体而言,Lister是一个接口,包含了获取所有已索引对象的列表以及根据名称获取单个对象的方法。这些方法可以帮助开发者在应用程序中快速访问已经缓存的资源对象,而无需直接与Indexer交互。

Lister的主要功能包括:

  1. 提供方便的接口:Lister接口的方法定义清晰简洁,使用起来非常方便,可以快速地获取已经索引的资源对象列表。
  2. 提高代码可读性:通过使用Lister接口,代码可读性得到提高。开发者可以更加专注于业务逻辑,而无需关注底层的Indexer实现细节。
  3. 提高代码复用性:由于Lister接口已经提供了通用的方法,因此可以更容易地在不同的代码模块中重用相同的逻辑,减少代码重复。

总之,Lister作为client-go包中的一个重要组件,可以帮助开发者更加高效地处理Kubernetes资源对象,提高代码的可读性和可重用性。

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. "k8s.io/apimachinery/pkg/labels"
  7. "k8s.io/client-go/informers"
  8. "k8s.io/client-go/kubernetes"
  9. "k8s.io/client-go/tools/cache"
  10. "k8s.io/client-go/tools/clientcmd"
  11. )
  12. func main() {
  13. // 获取 kubeconfig 文件路径
  14. kubeconfigPath := os.Getenv("KUBECONFIG")
  15. if kubeconfigPath == "" {
  16. kubeconfigPath = os.Getenv("HOME") + "/.kube/config"
  17. }
  18. // 使用 kubeconfig 文件创建 kubernetes 客户端
  19. config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
  20. if err != nil {
  21. panic(err)
  22. }
  23. clientset, err := kubernetes.NewForConfig(config)
  24. if err != nil {
  25. panic(err.Error())
  26. }
  27. // 创建Informer
  28. factory := informers.NewSharedInformerFactory(clientset, time.Minute)
  29. podInformer := factory.Core().V1().Pods()
  30. // 创建Lister
  31. lister := podInformer.Lister()
  32. // 等待Informer同步完成
  33. stopCh := make(chan struct{})
  34. defer close(stopCh)
  35. factory.Start(stopCh)
  36. cache.WaitForCacheSync(stopCh, podInformer.Informer().HasSynced)
  37. // 获取namespace为"default"的Pod对象
  38. podList, err := lister.Pods("default").List(labels.Everything())
  39. if err != nil {
  40. panic(err.Error())
  41. }
  42. // 打印Pod对象
  43. for _, pod := range podList {
  44. fmt.Printf("Pod name: %s, Namespace: %s\n", pod.Name, pod.Namespace)
  45. }
  46. }
  47. /*
  48. Pod name: nginx-76d6c9b8c-m4g5l, Namespace: default
  49. Pod name: nginx, Namespace: default
  50. Pod name: ubuntu, Namespace: default
  51. Pod name: nginx-76d6c9b8c-kr9d2, Namespace: default
  52. Pod name: nginx-76d6c9b8c-n8st9, Namespace: default
  53. Pod name: nginx-76d6c9b8c-8ljkt, Namespace: default
  54. Pod name: nginx-76d6c9b8c-jqv9h, Namespace: default
  55. */

Reference

原文链接:https://www.cnblogs.com/haiyux/p/17162339.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号