client-go的四种客户端

client-go提供了四种与Kubernetes APIServer交互的客户端:RESTClient、DiscoveryClient、ClientSet、DynamicClient。 经过学习之后,我感觉这个东西还是蛮不复杂的,以下是这四种客户端获取所有Pods的demo,然后感受一下他们的区别。

运行在下面的四个代码时,需要准备好kubeconfig,就是~/.kube/config这个文件,可以从服务器上拷到本地上。或者直接放在服务器上跑这些代码。

RESTClient

RESTClient是一个最基础的client,他是其他三种client的底层,也就是说,其他三种client都是封装的它。所以操作RESTClient会感觉比较原始。我们

go 复制代码
import (
    "context"
    "flag"
    "fmt"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/client-go/kubernetes/scheme"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
)

func main() {
    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", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

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

    config.APIPath = "api"
    // 设置 corev1 groupVersion
    config.GroupVersion = &corev1.SchemeGroupVersion
    // 设置解析器,用于用于解析 scheme
    config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
    // 初始化 RESTClient
    restClient, err := rest.RESTClientFor(config)
    if err != nil {
       panic(err)
    }
    list := &corev1.PodList{}
    // namespace为空,就返回所有namespace中的资源
    err = restClient.Get().Namespace("").Resource("pods").Do(context.TODO()).Into(list)
    if err != nil {
       panic(err)
    }

    for _, item := range list.Items {
       fmt.Printf("ns:%s , pod:%s\n", item.Namespace, item.Name)
    }
}

ClientSet

ClientSet他是用来操作K8s内置资源的,底层给每一种资源封了RESTClient,如果想操作CRD,需要自己定义ClientSet。

go 复制代码
func main() {
    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", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    // 从kubeconfig中获取配置
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
       panic(err.Error())
    }

    // 从配置中获得clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
       panic(err.Error())
    }
    pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
    if err != nil {
       panic(err.Error())
    }
    fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))

    for _, item := range pods.Items {
       fmt.Printf("ns:%s , pod:%s\n", item.Namespace, item.Name)
    }
}

其实最后来时落到了这里,所以他是帮我们把一些操作封了一下。

go 复制代码
func (c *pods) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PodList, err error) {
    var timeout time.Duration
    if opts.TimeoutSeconds != nil {
       timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
    }
    result = &v1.PodList{}
    err = c.client.Get().
       Namespace(c.ns).
       Resource("pods").
       VersionedParams(&opts, scheme.ParameterCodec).
       Timeout(timeout).
       Do(ctx).
       Into(result)
    return
}

DynamicClient

动态client的就是比较动态,然后他可以操作CRD,但是他返回的内容是map

go 复制代码
func main() {
    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", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    // 从kubeconfig中获取配置
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
       panic(err.Error())
    }

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

    // 因为是动态调用,不需要操作哪个资源,所以需要自己提供
    gvr := schema.GroupVersionResource{
       Group:    "",
       Version:  "v1",
       Resource: "pods",
    }

    result, err := dynamicClient.Resource(gvr).Namespace("").List(context.TODO(), meta_v1.ListOptions{})
    podList := &corev1.PodList{}
    // 将结果解析到 podList scheme 中
    err = runtime.DefaultUnstructuredConverter.FromUnstructured(
       result.UnstructuredContent(), podList)

    for _, item := range podList.Items {
       fmt.Printf("ns: %s,pod: %s\n", item.Namespace, item.Name)
    }
}

我们这里把的结构化数据转为了结构化数据。

DiscoveryClient

发现客户端是用来用于发现 Kube-apiserver 支持的资源组、资源版本、资源类型等。 通过DiscoveryClient发现所有gvr

go 复制代码
func main() {
    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", "", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    // 从kubeconfig中获取配置
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
       panic(err.Error())
    }

    // 初始化 DiscoveryClient
    discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
    if err != nil {
       panic(err.Error())
    }
    // 获取集群所有资源
    _, apiResourceList, err := discoveryClient.ServerGroupsAndResources()
    if err != nil {
       panic(err.Error())
    }

    for _, resources := range apiResourceList {
       gv, err := schema.ParseGroupVersion(resources.GroupVersion)
       if err != nil {
          panic(err.Error())
       }
       for _, resource := range resources.APIResources {
          fmt.Printf("group: %s, version: %s, resource: %s\n", gv.Group, gv.Version, resource.Name)
       }

    }
}
相关推荐
Thneonl30 分钟前
照着 CKS 教材做实验,把 apiserver 干瘫了 7 分钟
安全·kubernetes
名字还没想好☜2 小时前
Kubernetes 用 kubectl port-forward 和 proxy 调试集群内服务:两者区别、断连自动重连与为什么别用在生产
运维·docker·kubernetes
武汉唯众智创12 小时前
云计算实训室建设指南(2026版):从技能大赛赛项标准反推架构、课程与落地路径
云原生·kubernetes·云计算·云计算实训室·云计算教学平台·职业技能大赛
名字还没想好☜18 小时前
Docker 网络实战:bridge/host/none/自定义网络、容器互通与端口映射踩坑
运维·docker·kubernetes
探索云原生20 小时前
KubeClipper 1.7.0 发布:Operation 优化与 Kubernetes 1.37 支持
linux·docker·云原生·kubernetes·go
天天喝旺仔1 天前
Prometheus + Grafana 监控告警体系搭建实战:从 Exporter 指标采集、PromQL 查询到 Alertmanager 告警落地
容器·kubernetes·grafana·prometheus·时序数据库
小牛马爱写博客2 天前
K8s 中部署WordPress 博客
云原生·容器·kubernetes
汪碧康2 天前
xkube-v4.3版本的安全性进行了增强
docker·云原生·容器·kubernetes·xkube
AugustSkys2 天前
从 Docker 到 Containerd:Kubernetes 时代容器运行时完全指南
docker·容器·kubernetes·containerd
正仪3 天前
kubernetes中list-watch机制
云原生·容器·kubernetes