上一篇文章里,我们主要介绍了 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 定义了接口, 其相关的图解和源码如下:
// 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 结构体
该结构体主要封装了资源的序列化和反序列化的功能,其图解和相关源码如下:
// 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 对象也会被封装在其中, 其主要是用来完成对资源的序列化与反序列化操作。图解和源码如下:
// 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 对象,图解和源码如下:
// 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 对象。