首页 > 其他分享 >一文带您了解 Client-Go 的四种客户端

一文带您了解 Client-Go 的四种客户端

时间:2022-10-10 22:05:12浏览次数:51  
标签:err Kubernetes default name Client io Go k8s 客户端

Client-Go 简介

Client-Go 是负责与 Kubernetes APIServer 服务进行交互的客户端库,利用 Client-Go 与Kubernetes APIServer 进行的交互访问,来对 Kubernetes 中的各类资源对象进行管理操作,包括内置的资源对象及CRD。

Client-Go 不仅被 Kubernetes 项目本身使用,其它围绕着 Kubernetes 的生态,也被大量的使用,例如:kubectl、ETCD-operator等等。

Client-Go 客户端

Client-Go 共提供了 4 种与 Kubernetes APIServer 交互的客户端。分别是 RESTClient、DiscoveryClient、ClientSet、DynamicClient。

  • RESTClient:最基础的客户端,主要是对 HTTP 请求进行了封装,支持 Json 和 Protobuf 格式的数据。
  • DiscoveryClient:发现客户端,负责发现 APIServer 支持的资源组、资源版本和资源信息的。
  • ClientSet:负责操作 Kubernetes 内置的资源对象,例如:Pod、Service等。
  • DynamicClient:动态客户端,可以对任意的 Kubernetes 资源对象进行通用操作,包括 CRD。

一文带您了解 Client-Go 的四种客户端_kubernetes

RESTClient

RESTClient 是所有客户端的父类,这也是为啥前面说,它是最基础的客户端的原因。

它提供了 RESTful 对应的方法的封装,如:Get()、Put()、Post()、Delete() 等。通过这些封装发方法与 Kubernetes APIServer RESTful API 进行交互。

因为它是所有客户端的父类,所以它可以操作 Kubernetes 内置的所有资源对象以及 CRD。

运行以下代码,将得到 default 下的 Pod 部分相关资源信息。

package main

import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)

/*
@Author : lanyulei
@Desc :
*/

func main() {
// 加载配置文件,生成 config 对象
config, err := clientcmd.BuildConfigFromFlags("", "../../kubeconfig")
if err != nil {
panic(err.Error())
}

// 配置 API 路径
config.APIPath = "api"

// 配置分组版本
config.GroupVersion = &corev1.SchemeGroupVersion

// 配置数据的编解码器
config.NegotiatedSerializer = scheme.Codecs

// 实例化 RESTClient
restClient, err := rest.RESTClientFor(config)
if err != nil {
panic(err.Error())
}

// 定义返回接收值
result := &corev1.PodList{}

err = restClient.Get().
Namespace("default"). // 查询的 Namespace
Resource("pods"). // 查询的资源类型
VersionedParams(&metav1.ListOptions{Limit: 100}, scheme.ParameterCodec). // 参数及序列化工具
Do(context.TODO()). // 发送请求
Into(result) // 写入返回值
if err != nil {
panic(err.Error())
}

// 输出返回结果
for _, d := range result.Items {
fmt.Printf("namespace: %v, name: %v, status: %v\n", d.Namespace, d.Name, d.Status.Phase)
}
}

输出结果

➜  demo1 go run main.go
namespace: default, name: 1231-589c58c8c5-27r94, status: Pending
namespace: default, name: 1231-b6896fd77-7bkgk, status: Pending
namespace: default, name: web-96d5df5c8-rcw6r, status: Running
namespace: default, name: web-96d5df5c8-rdzpr, status: Running

RESTClient 其实就是底层使用 net/http 库,将调用 Kubernetes APIServer 的 API 请求,进行了封装,对参数和返回结果进行了序列化及反序列化,有兴趣的话,可以看下源码,分析一下请求过程。这里就不多介绍了。

ClientSet

上面介绍了 RESTClient,它虽然可以操作 Kubernetes 的所有资源对象,但是使用起来确实比较复杂,需要配置的参数过于繁琐,因此,为了更优雅的更方便的与 Kubernetes APIServer 进行交互,则需要进一步的封装。

前面有过介绍,ClientSet 是基于 RESTClient 的封装,同时 ClientSet 是使用预生成的 API 对象与 APIServer 进行交互的,这样做更方便进行二次开发。

ClientSet 是一组资源对象客户端的集合,例如负责操作 Pods、Services 等资源的 CoreV1Client,负责操作 Deployments、DaemonSets 等资源的 AppsV1Client 等。通过这些资源对象客户端提供的操作方法,即可对 Kubernetes 内置的资源对象进行 Create、Update、Get、List、Delete 等操作。

运行以下代码,将得到 default 下的 Pod 部分相关资源信息。

package main

import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)

/*
@Author : lanyulei
@Desc :
*/

func main() {
// 加载配置文件,生成 config 对象
config, err := clientcmd.BuildConfigFromFlags("", "../../kubeconfig")
if err != nil {
panic(err.Error())
}

// 实例化 ClientSet
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}

// 查询 default 下的 pods 部门资源信息
pods, err := clientset.
CoreV1(). // 实例化资源客户端,这里标识实例化 CoreV1Client
Pods("default"). // 选择 namespace,为空则表示所有 Namespace
List(context.TODO(), metav1.ListOptions{}) // 查询 pods 列表
if err != nil {
panic(err.Error())
}

// 输出 Pods 资源信息
for _, item := range pods.Items {
fmt.Printf("namespace: %v, name: %v\n", item.Namespace, item.Name)
}
}

输出结果

➜  demo1 go run main.go 
namespace: default, name: 1231-589c58c8c5-27r94
namespace: default, name: 1231-b6896fd77-7bkgk
namespace: default, name: web-96d5df5c8-rcw6r
namespace: default, name: web-96d5df5c8-rdzpr

DynamicClient

DynamicClient 是一种动态客户端,通过动态指定资源组、资源版本和资源等信息,来操作任意的 Kubernetes 资源对象的一种客户端。即不仅仅是操作 Kubernetes 内置的资源对象,还可以操作 CRD。这也是与 ClientSet 最明显的一个区别。

使用 ClientSet 的时候,程序会将所用的版本与类型紧密耦合。而 DynamicClient 使用嵌套的 map[string]interface{} 结构存储 Kubernetes APIServer 的返回值,使用反射机制,在运行的时候,进行数据绑定,这种方式更加灵活,但是却无法获取强数据类型的检查和验证。

此外,在介绍 DynamicClient 之前,还需要了解另外两个重要的知识点,Object.runtime 接口和 Unstructured 结构体。

  • Object.runtime:Kubernetes 中的所有资源对象,都实现了这个接口,其中包含 DeepCopyObject 和 GetObjectKind 的方法,分别用于对象深拷贝和获取对象的具体资源类型。
  • Unstructured:包含 map[string]interface{} 类型字段,在处理无法预知结构的数据时,将数据值存入 interface{} 中,待运行时利用反射判断。该结构体提供了大量的工具方法,便于处理非结构化的数据。

运行以下代码,将得到 default 下的 Pod 部分相关资源信息。

package main

import (
"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"
"k8s.io/client-go/tools/clientcmd"
)

/*
@Author : lanyulei
@Desc :
*/

func main() {
// 加载配置文件,生成 config 对象
config, err := clientcmd.BuildConfigFromFlags("", "../../kubeconfig")
if err != nil {
panic(err.Error())
}

// 实例化 DynamicClient
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
panic(err.Error())
}

// 设置要请求的 GVR
gvr := schema.GroupVersionResource{
Group: "",
Version: "v1",
Resource: "pods",
}

// 发送请求,并得到返回结果
unStructData, err := dynamicClient.Resource(gvr).Namespace("default").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)
}
}

输出结果

➜  demo1 go run main.go
namespace: default, name: 1231-589c58c8c5-27r94
namespace: default, name: 1231-b6896fd77-7bkgk
namespace: default, name: web-96d5df5c8-rcw6r
namespace: default, name: web-96d5df5c8-rdzpr

DiscoveryClient

前面咱们介绍了 3 种客户端,都是针对与资源对象管理的。而 DiscoveryClient 则是针对于资源的。用于查看当前 Kubernetes 集群支持那些资源组、资源版本、资源信息。

运行以下代码,将得到 Kubernetes 集群的资源列表。

package main

import (
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
)

/*
@Author : lanyulei
@Desc :
*/

func main() {
// 加载配置文件,生成 config 对象
config, err := clientcmd.BuildConfigFromFlags("", "../../kubeconfig")
if err != nil {
panic(err.Error())
}

// 实例化 DiscoveryClient
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
panic(err.Error())
}

_, apiResources, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
panic(err.Error())
}

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

输出结果

➜  demo1 go run main.go
name: bindings, group: , version: v1
name: componentstatuses, group: , version: v1
name: configmaps, group: , version: v1
name: endpoints, group: , version: v1
name: events, group: , version: v1
...

标签:err,Kubernetes,default,name,Client,io,Go,k8s,客户端
From: https://blog.51cto.com/u_11293981/5742220

相关文章

  • MongoDB 数据导入和导出、备份和恢复
    注:mongoexport和mongoimport针对库中的表,用于数据导入和导出,mongodump和mongorestore针对于库,用于备份和恢复。一、mongodb导出1、导出/导入数据时,连接mongodb服务器参数......
  • Django简介和安装
    目录​​Django​​​​MVC模型​​​​Django的MTV模型​​​​Django的安装​​​​虚拟环境​​DjangoDjango是一个开放源代码的Web应用框架,由Python写成,其网站的特点是......
  • go rpc
     server.gopackagemainimport("encoding/json""fmt""net""net/rpc""net/rpc/jsonrpc")typeRpcTeststruct{}typeResultstruct{Codeint......
  • (转)如何在Category类中定义成员变量
    OC是不能直接修改对象的结构体的成员变量属性,一般做法是先取出对象的结构体变量,修改该取出来的结构体变量里面的成员,再把结构体对象赋值给原来的结构体变量,在UI中为了简......
  • Go Micro介绍与入门
    一什么是Micro?Micro是一个微服务生态系统,致力于提供产品,服务和解决方案,以实现现代软件驱动型企业的创新。我们计划成为任何与微服务相关的事实资源,并期待公司能够利用这......
  • Go语言的接口和Rust的Trait的对比
    go语言的接口是鸭子的方式,即struct本身拥有的方法如果包含某个接口里定义的所有方法声明,则认为这个struct实现了该接口,举例子:typeAstruct{Faceint}//A结构体......
  • 浅谈Go1.18版本新特性——泛型
    泛型Generics:引入了对使用参数化类型的泛型代码的新支持,达到了算法可复用的目的。两数求和,泛型函数的使用假设我们要计算两个数的和,函数可以这样子写funcAdd(a......
  • 玩转Go反射
    反射反射常用于各种框架类当中,它可以做到十分优雅的帮我们读取值、设置值Go语言当中感觉很多反射的工具类,比如Java中的hutool,并没有很好的支持我总结下来反射可以分为两......
  • SIT221 Data Structures and Algorithms课程辅导task1.1
    文章目录​​1.如何使用vector​​​​2.代码结构分析​​​​2.1类和对象​​​​2.2和原版本对比查看差距​​实现一个vector。1.如何使用vector2.代码结构分析总体......
  • Navicat客户端因为版本问题连接不上mysql解决办法
    原因:新旧版本的密码加密方式不同解决办法:登录mysql中mysql-uroot-p1234usemysqlALTERUSER'root'@'localhost'IDENTIFIEDWITHmysq......