上一篇文章中,我们主要去介绍了 codec 是如何完成 decode 和 encode 操作的,即对象的序列化和反序列化的过程。 在 decode 操作的核心过程中, 首先会将对象从请求中反序列化,然后在转化为目标版本(一般是内部版本),然后在进行处理。encode 操作的过程中, 首先将对象(一般为内部版本对象)转化为目标版本,然后再序列化到响应数据流中。

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

9e16267d3b090374aa20bb003da1497e.png

核心代码定义如下:

// kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go
type Scheme struct {
  gvkToType map[schema.GroupVersionKind]reflect.Type


  typeToGVK map[reflect.Type][]schema.GroupVersionKind


  unversionedTypes map[reflect.Type]schema.GroupVersionKind


  unversionedKinds map[string]reflect.Type


  fieldLabelConversionFuncs map[schema.GroupVersionKind]FieldLabelConversionFunc


  defaulterFuncs map[reflect.Type]func(interface{})


  converter *conversion.Converter


  versionPriority map[string][]string


  observedVersions []schema.GroupVersion


  schemeName string
}

从上面的图解以及源码来看 schema 结构主要有以下关键点:

  • 包含 map 类型的 gvkToType 属性来维护 GVK 和 model 对象类型的关系。

  • 包含 map 类型的 typeToGVK 属性来维护 model 对象类型和 GVK 的关系。

  • 包含 map 类型的 defaulterFuncs 属性维护 model 对象类型和默认值函数的关系。

  • 包含 conversion.Converter 指针类型的 converter 属性实现资源不同版本的转化。

  • map 类型的 fieldLabelConversionFuncs 属性维护 GVK label 标签转换函数的关系。

  • 包含 string 类型的 schemaName 属性用来定义 schema 的名称。

由上面的 schema 的数据结构看,它是一个 struct 的类型,另外它还实现了一些接口,使得 schema 可以创建资源对象,给资源对象赋默认值,识别资源对象类型,完成资源对象本版之间的转换,完成资源的 label 标签转化等。其接口实现如下图:

519c1bea9e5d562712038c2e9b70aaa4.png

接口实现的函数核心代码定义如下:

// kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go
func (s *Scheme) Convert(in, out interface{}, context interface{}) error{...}
func (s *Scheme) ConvertToVersion(in Object, target GroupVersioner) (Object, error){...}
func (s *Scheme) ConvertFieldLabel(gvk schema.GroupVersionKind, label, value string) (string, string, error){...}


func (s *Scheme) Default(src Object){...}


func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) {...}


func (s *Scheme) ObjectKinds(obj Object) ([]schema.GroupVersionKind, bool, error){...}
func (s *Scheme) Recognizes(gvk schema.GroupVersionKind) bool{...}

从上面的图解以及源码来看 schema 实现接口主要有以下关键点:

  • 实现 runtime.ObjectCreater 接口定义的方法完成资源的创建。

  • 实现 runtime.ObjectDefaulter 接口定义的方法完成资源的赋默认值。

  • 实现 runtime.ObjectConvert 接口定义的方法完成资源不同版本之间的相互转换。

  • 实现 runtime.ObjecTyper 接口定义的方法完成资源的类型识别。

目前先我们写到这里,在下一篇文章中我们继续来介绍 kubernetest 资源是如何注册到 schema 之中的。 

Logo

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

更多推荐