深入了解 K8s 扩展神器 client-go 的详细用法

1. 简介

当使用 Kubernetes 进行应用程序的开发和部署时,client-go 是一个非常重要的工具。它是 Kubernetes 的官方客户端库,提供了与 Kubernetes ApiServer 进行通信的接口和实现。

client-go 主要提供以下几个功能:

与 Kubernetes ApiServer 进行通信:client-go 提供了与 Kubernetes ApiServer 进行通信的接口和实现,包括基本的 http 请求和更深层次的封装。开发人员可以使用 client-go 创建、更新和删除 Kubernetes 中的资源。 访问 Kubernetes ApiServer 中的资源:client-go 提供了访问 Kubernetes ApiServer 中资源的方法,包括使用 ClientSet 进行基于对象的访问和使用 DynamicClient 进行基于无类型的访问。 处理 Kubernetes 资源的事件:client-go 提供了一种称为 Informer 的机制,它可以监听 Kubernetes ApiServer 中的资源变更事件。开发人员可以使用 Informer 实现资源的快速检索和本地缓存,从而减轻对 ApiServer 的访问压力。 发现 Kubernetes ApiServer 中的资源:client-go 还提供了 DiscoveryClient 接口,该接口可以用于在 Kubernetes ApiServer 中查找特定资源的详细信息。 总的来说,client-go 是 Kubernetes 开发人员不可或缺的工具之一。它提供了丰富的功能和灵活的接口,使开发人员能够更轻松地构建和管理 Kubernetes 应用程序。

2. Client

多种 client 介绍

RESTClient 最基础的客户端,其他的 ClientSet、DyanmicClient、DiscoveryClient 都是基于 RESTClient 实现的

ClientSet 对 k8s 内置资源的客户端集合。如获取 pod 资源对象的 client

clientset.CoreV1().Pods("")

DynamicClient 动态客户端,它可以对任意 k8s 资源进行 RESTful 操作,包括 CRD 资源。与 ClientSet 最大的不同是,ClientSet 仅能访问 k8s 自带的资源,不能直接访问 CRD 资源。

DiscoveryClient 发现客户端,主要用于发现 k8sApiServer 所支持的资源组,资源版本资源信息。

Clientset 和 dynamicClient 都是面向资源对象的(例如创建 deployment 实例、查看 pod 实例),而 DiscoveryClient 则不同,它聚焦的是资源

参考: https://www.cnblogs.com/bolingcavalry/p/15249712.html

加载kubeconfig及各客户端初始化的方法

 1package config
 2
 3import (
 4        "k8s.io/client-go/discovery"
 5        "k8s.io/client-go/dynamic"
 6        "k8s.io/client-go/kubernetes"
 7        "k8s.io/client-go/rest"
 8        "k8s.io/client-go/tools/clientcmd"
 9        "log"
10)
11
12const kubeConfigFilePath = "/Users/ShadowYD/.kube/config"
13
14type K8sConfig struct {
15}
16
17func NewK8sConfig() *K8sConfig {
18   return &K8sConfig{}
19}
20// 读取kubeconfig 配置文件
21func (this *K8sConfig) K8sRestConfig() *rest.Config {
22  config, err := clientcmd.BuildConfigFromFlags("", kubeConfigFilePath)
23  if err != nil {
24          log.Fatal(err)
25  }
26  return config
27}
28// 初始化 clientSet
29func (this *K8sConfig) InitClient() *kubernetes.Clientset {
30        c, err := kubernetes.NewForConfig(this.K8sRestConfig())
31
32        if err != nil {
33                log.Fatal(err)
34        }
35
36        return c
37}
38
39// 初始化 dynamicClient
40func (this *K8sConfig) InitDynamicClient() dynamic.Interface {
41        c, err := dynamic.NewForConfig(this.K8sRestConfig())
42
43        if err != nil {
44                log.Fatal(err)
45        }
46
47        return c
48}
49
50// 初始化 DiscoveryClient
51func (this *K8sConfig) InitDiscoveryClient() *discovery.DiscoveryClient {
52        return discovery.NewDiscoveryClient(this.InitClient().RESTClient())
53}

示例

 1package main
 2
 3import (
 4    "context"
 5    "flag"
 6    "fmt"
 7    "path/filepath"
 8    "time"
 9
10    "k8s.io/apimachinery/pkg/api/errors"
11    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12    "k8s.io/client-go/kubernetes"
13    "k8s.io/client-go/tools/clientcmd"
14    "k8s.io/client-go/util/homedir"
15)
16
17func main() {
18    var kubeconfig *string
19    if home := homedir.HomeDir(); home != "" {
20        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
21    } else {
22        kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
23    }
24    flag.Parse()
25
26    // 获取配置对象
27    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
28    if err != nil {
29        panic(err.Error())
30    }
31
32    // 创建 clientset
33    clientset, err := kubernetes.NewForConfig(config)
34    if err != nil {
35        panic(err.Error())
36    }
37    for {
38        // 调用list方法时才会请求apiserver
39        pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
40        if err != nil {
41            panic(err.Error())
42        }
43        fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
44
45        // 获取pod信息
46        namespace := "default"
47        pod := "soa-test-service-5fd6fd67fd-7ktdg"
48        _, err = clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod, metav1.GetOptions{})
49        if errors.IsNotFound(err) {
50            fmt.Printf("Pod %s in namespace %s not found\n", pod, namespace)
51        } else if statusError, isStatus := err.(*errors.StatusError); isStatus {
52            fmt.Printf("Error getting pod %s in namespace %s: %v\n",
53                pod, namespace, statusError.ErrStatus.Message)
54        } else if err != nil {
55            panic(err.Error())
56        } else {
57            fmt.Printf("Found pod %s in namespace %s\n", pod, namespace)
58        }
59
60        time.Sleep(10 * time.Second)
61    }
62}

3. Informer

关注点:indexer 、 informer 、事件注册机制等,下面这篇文章写的比较详细,这里不多做赘述。

参考:https://www.cnblogs.com/charlieroro/p/10330390.html

发布日期:2023-10-12 20:24 字数:507 用时 3分钟
tags:k8s client-go