上一篇文章里,我们主要介绍了 kubernetes 中资源 API 的注册过程,包括核心资源组和非核心资源组,以及中间是如何利用 go-restful 这个 web 框架来映射成标准的 restful API。在后面的文章里我们主要介绍 client go 这个组件,该组件主要是会负责和 kubernetes API server 进行通讯,完成对各种资源的增删改查,list and watch 等系列操作。例如负责资源调度的 kube-scheduler 组件,负责资源管理的 controller manager 组件,负责 pod 生命周期管理的 kublet 组件,负责网络管理的 kube-proxy 组件,它们与 API server 的通讯完全依赖于 client go 这个组件,所以该组件是基础中的基础。本篇文章我们主要该组件中的 RESTClient。

接口定义

staging/src/k8s.io/client-go/rest/client.go 源码文件中 Interface 定义了接口, 其相关的图解和源码如下:

3299c729a5e0ad13c5f6f2e7cef27221.png

// staging/src/k8s.io/client-go/rest/client.go
type Interface interface {
  GetRateLimiter() flowcontrol.RateLimiter
  Verb(verb string) *Request
  Post() *Request
  Put() *Request
  Patch(pt types.PatchType) *Request
  Get() *Request
  Delete() *Request
  APIVersion() schema.GroupVersion
}
  • 该接口中定义了 APIVersion() 这个方法,用来表示访问某一组下的某一版本中的资源。

  • 该接口中定义了 Get/Post/Put/Delete 等方法用来生成一个 Request 对象。表示在该 Request 对象中, 我们可以有能力去使用 http 相应的 Get/Post/Put/Delete 等方法访问某一组下的某一版本中的资源。

ClientNegotiator 结构体

该结构体主要封装了资源的序列化和反序列化的功能,其图解和相关源码如下:

5100c745faa1c92847ece6421cf9337f.png

// k8s.io/apimachinery/pkg/runtime/negotiate.go
type clientNegotiator struct {
  serializer     NegotiatedSerializer
  encode, decode GroupVersioner
}


func (n *clientNegotiator) Encoder(contentType string, params map[string]string) (Encoder, error) {
  mediaTypes := n.serializer.SupportedMediaTypes()
  info, ok := SerializerInfoForMediaType(mediaTypes, contentType)
  if !ok {
    if len(contentType) != 0 || len(mediaTypes) == 0 {
      return nil, NegotiateError{ContentType: contentType}
    }
    info = mediaTypes[0]
  }
  return n.serializer.EncoderForVersion(info.Serializer, n.encode), nil
}


func (n *clientNegotiator) Decoder(contentType string, params map[string]string) (Decoder, error) {
  mediaTypes := n.serializer.SupportedMediaTypes()
  info, ok := SerializerInfoForMediaType(mediaTypes, contentType)
  if !ok {
    if len(contentType) != 0 || len(mediaTypes) == 0 {
      return nil, NegotiateError{ContentType: contentType}
    }
    info = mediaTypes[0]
  }
  return n.serializer.DecoderToVersion(info.Serializer, n.decode), nil
}
  • 在该接结构体的源码定义中, 封装了 runtime.NegotiatedSerializer 这个基本接口,根据以前文章,该接口用来完成对不同协议格式(json, yaml, protobuf)资源的序列化和反序列化。以前文章中介绍的 codec factory 对象就是该接口的实现。

  • 该接口中定义的 Encoder 方法,该方法间接调用内部属性 NegotiatedSerializer 接口类型的 EncoderForVersion() 方法,从而来构建合适的 Encoder 对象。

  • 该接口中定义的 Decoder 方法,该方法间接调用内部属性 NegotiatedSerializer 接口类型的 DecoderForVersion() 方法,从而构建合适的 Decoder 对象。

ClientContentConfig 结构体

该结构体主要用来指定对某个组下的某个版本中的资源访问,同时 clientNegotiator 对象也会被封装在其中, 其主要是用来完成对资源的序列化与反序列化操作。图解和源码如下:

4b0a122d3cbc45f772f9c7c8deb3c09b.png

// staging/src/k8s.io/client-go/rest/client.go
type ClientContentConfig struct {
  AcceptContentTypes string
  
  ContentType string
  
  GroupVersion schema.GroupVersion
  
  Negotiator runtime.ClientNegotiator
}
  • 该接结构体封装了 GroupVersion 属性,用来设置访问某一组下某一个版本的资源。

  • 该结构体的详细定义中, 定义封装了上面文章中介绍的 clientNegotiator 对象, 用来完成对不同协议格式资源的序列化与反序列化操作。

RESTClient 结构体

该结构体主要实现了开头介绍的接口,用来生成 Request 对象,图解和源码如下:

34987ed75eef9147154e95300510576d.png

// staging/src/k8s.io/client-go/rest/client.go
type RESTClient struct {
  base *url.URL


  versionedAPIPath string


  content ClientContentConfig


  createBackoffMgr func() BackoffManager


  rateLimiter flowcontrol.RateLimiter


  warningHandler WarningHandler


  Client *http.Client
}


func (c *RESTClient) Verb(verb string) *Request{...}
func (c *RESTClient) Post() *Request{...}
func (c *RESTClient) Put() *Request{...}
func (c *RESTClient) Patch(pt types.PatchType) *Request{...}
func (c *RESTClient) Get() *Request{...}
func (c *RESTClient) Delete() *Request{...}
func (c *RESTClient) APIVersion() schema.GroupVersion{...}
func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter{...}
  • 该结构体封装了上面文章中介绍的 ClientContentConfig 对象作为属性,用来设置访问某一组下某一个版本的资源,以及完成对这些资源序列化和反序列化操作。

  • 该结构体封装 http.Client 对象指针,它是 go 语言中的原生 http 访问组件,底层利用该组件完成 http 请求。

  • 该结构体中也封装了 http 请求中的其它属性,例如 base url 等等,同时也提供了限速 (rateLimiter) 和回退 (BackoffManager) 等高级功能。

  • 该结构体实现了文章开头介绍的接口,生成 Request 对象,提供相应的 http 方法去访问资源。

目前先我们写到这里,在下一篇文章中我们继续来介绍 RESTClient 生成的 Request 对象。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐