You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"ClientGo/utils"
"context"
"fmt"
corev1 "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"
"log"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: DynamicClient 是一种动态客户端,通过动态指定资源组、资源版本和资源等信息,来操作任意的 Kubernetes 资源对象的一种客户端。
即不仅仅是操作 Kubernetes 内置的资源对象,还可以操作 CRD。这也是与 ClientSet 最明显的一个区别。
使用 ClientSet 的时候,程序会将所用的版本与类型紧密耦合。
而 DynamicClient 使用嵌套的 map[string]interface{} 结构存储 Kubernetes APIServer 的返回值,使用反射机制,在运行的时候,进行数据绑定,这种方式更加灵活,但是却无法获取强数据类型的检查和验证。
此外,在介绍 DynamicClient 之前还需要了解另外两个重要的知识点Object.runtime 接口和 Unstructured 结构体。
Object.runtimeKubernetes 中的所有资源对象,都实现了这个接口,其中包含 DeepCopyObject 和 GetObjectKind 的方法,分别用于对象深拷贝和获取对象的具体资源类型。
Unstructured包含 map[string]interface{} 类型字段,在处理无法预知结构的数据时,将数据值存入 interface{} 中,待运行时利用反射判断。该结构体提供了大量的工具方法,便于处理非结构化的数据。
**/
func GetDynamicClient() (dynamic.Interface, error) {
config, err := utils.GetConfig()
if err != nil {
log.Println("GetConfig 失败: ", err.Error())
return nil, err
}
// 实例化 DynamicClient
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
log.Println("NewForConfig 失败: ", err.Error())
return nil, err
}
return dynamicClient, nil
}
// GetDynamicClientRes from kubeConfigPath
func GetDynamicClientRes(namespace string) {
dynamicClient, err := GetDynamicClient()
if err != nil {
log.Println("GetDynamicClient 失败: ", err.Error())
return
}
// 设置要请求的 GVR
gvr := schema.GroupVersionResource{
Group: "",
Version: "v1",
Resource: "pods",
}
// 发送请求,并得到返回结果
unStructData, err := dynamicClient.Resource(gvr).Namespace(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
// 使用反射将 unStructData 的数据转成对应的结构体类型,例如这是是转成 v1.PodList 类型
podList := &corev1.PodList{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(
unStructData.UnstructuredContent(),
podList,
)
if err != nil {
panic(err.Error())
}
// 输出 Pods 资源信息
for _, item := range podList.Items {
fmt.Printf("namespace: %v, name: %v\n", item.Namespace, item.Name)
}
}