前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8s源码分析(20)-client go组件之request和result

K8s源码分析(20)-client go组件之request和result

作者头像
TA码字
发布2022-10-30 13:22:08
2700
发布2022-10-30 13:22:08
举报
文章被收录于专栏:TA码字TA码字

上一篇文章里,我们主要介绍了 kubernetes 世界中 client go 这个基础组件,它的主要职责是负责与 API server 进行通讯交互。其中负责资源调度的 kube-scheduler 组件,负责资源管理的 controller manager 组件,以及负责 pod 生命周期的 kublet 组件,负责网络管理的 kube-proxy 组件都会依赖于这个组件。而该组件在通讯的时候又依赖于 request 对象,并且得到相应的 result 对象,在本篇文章里我们主要来介绍 request 和 result 对象。

Request 结构体

该结构体主要封装了上一篇文章中介绍的 RESTClient 对象,用以完成和 API server 之间的通讯,其图解和相关源码如下:

代码语言:javascript
复制
type Request struct {
  c *RESTClient  
  warningHandler WarningHandler
  rateLimiter flowcontrol.RateLimiter
  backoff     BackoffManager
  timeout     time.Duration
  maxRetries  int

  verb       string
  pathPrefix string
  subpath    string
  params     url.Values
  headers    http.Header

  namespace    string
  namespaceSet bool
  resource     string
  resourceName string
  subresource  string

  err  error
  body io.Reader
}

func (r *Request) Do(ctx context.Context) Result {
  var result Result
  err := r.request(ctx, func(req *http.Request, resp *http.Response) {
    result = r.transformResponse(resp, req)
  })
  if err != nil {
    return Result{err: err}
  }
  return result
}

func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result {
                ............
  var decoder runtime.Decoder
  contentType := resp.Header.Get("Content-Type")
  if len(contentType) == 0 {
    contentType = r.c.content.ContentType
  }
                ............
  decoder, err = r.c.content.Negotiator.Decoder(mediaType, params)
  ............
  return Result{
    body:        body,
    contentType: contentType,
    statusCode:  resp.StatusCode,
    decoder:     decoder,
    warnings:    handleWarnings(resp.Header, r.warningHandler),
  }
}
  • 在该结构体的源码定义中, 封装了上一篇文章中介绍的 RESTClient 对象。同时也封装对应的 http 请求方法 verb,路径的前缀 pathPrefix ,以及请求参数和请求头等有关必要信息。
  • 在该结构体中还封装了资源的信息,例如是本次操作的资源是否为基于 namespace 的资源,具体资源是属于哪个命名空间的,资源的种类,资源的名字,还有子资源的种类等等。
  • 该结构体中封装了 Do() 方法用以发送请求和处理响应。
  • 封装了 transformResponse() 方法用完成对 API 响应的封装操作,其核心是调用上一篇文章中介绍的 ClientNegotiator 定义的 Decoder 方法来得到相应的 decoder,然后封装到一个 Result 对象中。

Result 结构体

该结构体主要封装了请求对象和 API server 交互的结果,并提供反序列化得到相应资源对象的功能,其图解和相关源码如下:

代码语言:javascript
复制
type Result struct {
  body        []byte
  warnings    []net.WarningHeader
  contentType string
  err         error
  statusCode  int

  decoder runtime.Decoder
}

func (r Result) Into(obj runtime.Object) error {
  if r.err != nil {
    // Check whether the result has a Status object in the body and prefer that.
    return r.Error()
  }
  if r.decoder == nil {
    return fmt.Errorf("serializer for %s doesn't exist", r.contentType)
  }
  if len(r.body) == 0 {
    return fmt.Errorf("0-length response with status code: %d and content type: %s",
      r.statusCode, r.contentType)
  }

  out, _, err := r.decoder.Decode(r.body, nil, obj)
  if err != nil || out == obj {
    return err
  }
  // if a different object is returned, see if it is Status and avoid double decoding
  // the object.
  switch t := out.(type) {
  case *metav1.Status:
    // any status besides StatusSuccess is considered an error.
    if t.Status != metav1.StatusSuccess {
      return errors.FromObject(t)
    }
  }
  return nil
}
  • 在该结构体的源码定义中, 封装了响应返回的二进制结果 body,同时也封装了对应的 decoder 对象用来反序列化。
  • 该接结构体中封装了 Into() 方法用完成对结果的反序列化操作,其核心就是调用内部的 decoder 对象来把结果转化为对应的资源对象。

目前先我们写到这里,在下一篇文章中我们继续来介绍对于不同 group/version 的资源是如何通过发送请求来操作的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TA码字 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档