【k8s基础篇】k8s scheme3 之序列化

本文深入解析Kubernetes中的Scheme机制,探讨如何通过GVK实现不同版本API数据结构映射,并介绍反序列化过程,包括内容编码、模型构建和版本转换。重点讲解了如何通过Scheme解决多版本API的兼容性问题。
摘要由CSDN通过智能技术生成

参考

利用 Scheme 反序列化的理解

0 | 前置知识 —— restful 访问 k8s 资源

  • 集群作用域的资源:

    • GET /apis/GROUP/VERSION/RESOURCETYPE - 返回指定资源类型的资源的集合
    • GET /apis/GROUP/VERSION/RESOURCETYPE/NAME - 返回指定资源类型下名称为 NAME 的资源
  • 名字空间作用域的资源:

    • GET /apis/GROUP/VERSION/RESOURCETYPE - 返回所有名字空间中指定资源类型的全部实例的集合
    • GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE - 返回名字空间 NAMESPACE 内给定资源类型的全部实例的集合
    • GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME - 返回名字空间 NAMESPACE 中给定资源类型的名称为 NAME 的实例
  • 某些资源类型有一个或多个子资源(Sub-resource),表现为对应资源下面的子路径:

    • 集群作用域的子资源:GET /apis/GROUP/VERSION/RESOURCETYPE/NAME/SUBRESOURCE
    • 名字空间作用域的子资源:`GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME/SUBRESOURCE
  • 例子

    • 列举给定名字空间中的所有 Pods:

    • GET /api/v1/namespaces/test/pods
      ---
      200 OK
      Content-Type: application/json
      {
        "kind": "PodList",
        "apiVersion": "v1",
        "metadata": {"resourceVersion":"10245"},
        "items": [...]
      }
      
    • 从访问的 url GET /api/v1/namespaces/test/pods 即可得知资源的 GVK(core(核心组忽略显示,就是这么规定的),v1,pod)

    • 可以看出发起请求,相应给出了相关 Pod 信息,而其信息的存储是通过相应的数据结构存储的

      • 不难看出,不同资源就会有不同的数据存储结构
      • 那么如何从 url 获取的 GVK 获取到响应的数据信息呢?就是如何将 GVK 与 响应的资源数据结构做对应呢
        • 答:Scheme ,下面将进行详细讲解

1 | 为什么需要 Scheme

  • 因为在web开发中随着版本的更新迭代,通常要在系统中维护多个版本的api,多个版本的api在数据结构上往往也各不相同
  • 为了解决上述问题 —— 出现了 Scheme —— 实现 GVK 与 api数据结构的对应

2 | web 请求的处理流程

使用kubernetes中的Scheme机制进行反序列化的操作

  1. 收到请求后,通常首先是webServer先进行Http协议的处理
    • 解析成基础的webServer内部的一个Http请求对象
    • 该 Http 请求对象持有对应请求的请求头和底层对应的字节序列(从socket流中读取)
  2. 接着根据对应的编码格式来进行反序列化
    • 完成从字节序列到当前接口的业务模型的映射, 然后在交给业务逻辑处理
    • 从而最终进行持久化存储, 本文的重点也就在反序列化部分

3 | 模型映射的实现

3.1 | 描述资源版本信息

/api/{version}/{resource}/{action}
  • 上面是一个基础的web url通常我们都会为每个版本注册一个对应的URL
    • 其中会包含很关键的两个信息即version与resource
    • 通过这两个信息,通常我们就可以知道这可能是某个资源的那个版本
    • 如果我们把后面的action也包裹进来,我们通常就可以知道对应的资源的那个具体操作

3.2 | Group 组信息

使用kubernetes中的Scheme机制进行反序列化的操作

在微服务流行的今天我们通常会为按照业务功能来进行微服务的切分,本质上一个微服务可能就是实现某个具体业务场景的功能集合,比如用户系统通常会包含用户的所有相关操作,在kubernetes中也有类似的概念就是所谓的Group

POST /apis/batch/v1beta1/namespaces/{namespace}/cronjobs
POST /apis/apps/v1/namespaces/{namespace}/daemonsets

我们来看一个实例这是一个创建daemonsets和cronjobs的url, 如果按照Group、resource、version来进行拆分可以拆成如下:batch、v1beta1、cronjobs和apps、v1、daemonsets,也就是大家尝试的GroupVersionKind,其中kind对应的就是resource

3.3 | 模型映射的实现

使用kubernetes中的Scheme机制进行反序列化的操作

  • 我们通过url里面获取到资源的GroupVersionKind信息,如何将其映射为一个具体的类型呢?
    • 这貌似就很简单了结合反射和map来进行就可以了,我们通过url获取到对应想的GVK信息,然后在通过我们的映射表,就知道对应的模型是哪个,接下来就只需要进行转换就行了
gvkToType map[schema.GroupVersionKind]reflect.Type

4 | 反序列化实现

4.1 | 解码机制

  • 那如何将对应的Http里面的数据流反序列化成内部的一个对象呢?
    • 别忘记了是Http协议, 肯定就是header头里面的信息了
    • 通过header头里面的序列化就可以知道对应的编码格式,只需要调用对应格式的解码就可以完成了
Content-Type: "application/json"

4.2 | 默认对象

使用kubernetes中的Scheme机制进行反序列化的操作

  • 如果要将json格式的字节数组进行解码通常要进行如下操作:
    • 需要传入一个目标对象的指针,然后由json将对应的字节数据解析到目标对象中,我们也需要这样一个对象,用于存储反序列化的结果
func Unmarshal(data []byte, v interface{}) error {}
  • 该目标存储对象如何获取呢?
    • 那只要我再提供一个当前版本对应的对象构造函数是不是就可以呢?答案是的
    • 构造函数,通过 GVK 调用相应的构造函数,即可构造出对应版本的目标对象
func() Object{ return 目标对象 },

5 | 总览

使用kubernetes中的Scheme机制进行反序列化的操作

  1. 在 webserver 上注册 url 时,即完成了 url 与 资源的版本信息GroupVersionKind(GVK) 映射关系的构建
  2. 之后收到请求进行处理时
    1. 通过 url 获取到 GVK
    2. 根据 GVK 调用相应构造函数,创建目标资源对象
    3. 根据请求的 Header 得知编码格式,获取对应的解码器
    4. 将Body里面的字节序列进行解码到目标对象
  3. 以上流程就可以实现多版本资源的映射和反序列化操作了

Scheme 的其他作用

  • schema 是 kubernetes 资源管理的核心数据结构。由以前文章我们了解到 kubernetes 会将其管理的资源划分为 group/version/kind 的概念,scheme 可以利用进行 GVK 进行一下操作:
    • 可以将资源在内部版本和其他版本中相互转化
    • 可以序列化和反序列化的过程中识别资源类型,创建资源对象,设置默认值等等
    • 这些 group/version/kind 和资源 model 的对应关系,资源 model 的默认值函数,不同版本之间相互转化的函数等等全部由 schema 维护。可以说 schema 是组织 kubernetes 资源的核心

具体讲解见下一节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值