K8s批量获取大量数据资源解决方案

背景

当使用kubelet已经无法获取到资源的级别,比如万级别

可以先直接采用client-go,去获取,这会更快,因为当我们使用kubelet get nodes|wc -l计算的时候,要先打印到出来再遍历

:star:最后最大数据可以采用NewSharedInformerFactory来获取,使用informer,former 提供了基于事件通知的只读缓存机制,可以注册资源变化的回调函数,并可以极大减少 API 的调用。

官方exampleURL

代码实例

package main

import (
"flag"
"fmt"
"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"
"k8s.io/client-go/util/homedir"
"path/filepath"
"time"
)

func GetClientOutside() (*kubernetes.Clientset, error) {
// 支持以 Pod 形式或者在宿主机上运行代码的形式获取 kubeconfig 配置
var kubeconfig *string
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "./kube/config", "absolute path to the kubeconfig file")
}
flag.Parse()

config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
return nil, err

}
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}

return clientSet, nil
}

func main() {
start := time.Now()

// 在这里执行您的代码或函数

clientset, err := GetClientOutside()
if err != nil {
fmt.Println(err)
return
}
//var timeout int64
//timeout = 6000
// 创建本地缓存
informerFactory := informers.NewSharedInformerFactory(clientset, 0)
nodeInformer := informerFactory.Core().V1().Nodes().Informer()
nodeLister := informerFactory.Core().V1().Nodes().Lister()

// 启动本地缓存的同步
stopCh := make(chan struct{})
defer close(stopCh)
informerFactory.Start(stopCh)
cache.WaitForCacheSync(stopCh, nodeInformer.HasSynced)

// 在这里执行您的代码或函数,可以从缓存中获取资源对象

// 示例:从缓存中获取所有 Pod 资源对象并打印它们的名称
nodes, _ := nodeLister.List(labels.Everything())
fmt.Printf("集群节点数%d\n", len(nodes))
//for _, node := range nodes {
// fmt.Println(node.Name)
// for _, statu := range node.Status.Conditions {
// if statu.Status == corev1.ConditionTrue && statu.Type == corev1.NodeReady {
// fmt.Println(node.Name)
// }
// }
//}

//items, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{Limit: 5000, ResourceVersion: "0", TimeoutSeconds: &timeout})
//for _, item := range items.Items {
// for _, statu := range item.Status.Conditions {
// if statu.Status == corev1.ConditionTrue && statu.Type == corev1.NodeReady {
// fmt.Println(item.Name)
// }
// }
//}
//if err != nil {
// fmt.Println(err)
// return
//}
//fmt.Println(len(items.Items))

elapsed := time.Since(start)
fmt.Printf("代码执行时间:%s\n", elapsed)
}