暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

K8s源码分析(7)-序列化的codec和codec factory

TA码字 2021-10-09
976

上一篇文章,主要以 serializer.json.Serializer 组件做为例子,介绍了对于 json 协议格式资源的序列化。其中包括了该组件是如何利用 decode 操作去从请求中来提取相关的 resource, 以及如何去利用 encode 操作来把相关 resource 写入到响应中去。


根据以前文章,kubernetes resource 是有内部版本和其它版本之间的转化的,上篇文章介绍的只是资源正常版本的序列化和反序列化操作,例如 apps/deployment/v1 资源的序列化和反序列化。如果涉及到内部版本和其它版本之间相互转化的序列化以及反序列化,就会用到 codec 组件和 codec factory 组件了。


codec 组件

codec 组件主要通过 decode 方法实现了 resource 从正常的版本转化为内部版本,通过 encode 方法实现了 resource 内部版本转化为正常版本。如果从形象的角度来看, codec 可以用以下图片描述。

  • codec 组件实现了 runtime.Serializer 接口,会由 Encode 和 Decode 方法来实现正常版本和内部版本相互转化的序列化以及反序列化。

  • codec 内部有 Encoder 和 Decoder 成员,主要完成正常版本下资源某种格式序列化和反序列化,例如我们上一篇文章介绍的 json 格式。

  • codec 内部有 ObjectConveror 关键成员主要完成资源的正常版本内部版本之间的相互转化

  • codec 内部 ObjectCreater 关键成员和 ObjectDefaulter 关键成员主要用于资源完成在 decode 操作中正常版本的创建和赋默认值。

  • codec 内部有 ObjectTyper 关键成员, 以用来确定资源的类型,即 GVK。
  • codec 内部 encodeVersion 关键成员和 decodeVersion 关键成员主要用于定义资源转化的版本,正常版本或者内部版本。
  • 从源代码的角度看, codec 相关定义如下

// staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go
type Encoder interface {
Encode(obj Object, w io.Writer) error


Identifier() Identifier
}


type Decoder interface {


Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error)
}


type Serializer interface {
Encoder
Decoder
}


type Codec Serializer


// k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
type codec struct {
encoder runtime.Encoder
decoder runtime.Decoder
convertor runtime.ObjectConvertor
creater runtime.ObjectCreater
typer runtime.ObjectTyper
  defaulter runtime.ObjectDefaulter
  
encodeVersion runtime.GroupVersioner
  decodeVersion runtime.GroupVersioner
  
  identifier runtime.Identifier
originalSchemeName string
}
复制



codec factory 组件

codec factory 主要作用是生成 codec 组件用来完成 decode 和 encode 操作,如果从形象的角度来看, codec factory 可以用以下图片描述。

  • 实现了 runtime.NegatiatedSerializer 这个核心接口,在该接口中定义 SupportedMediaTypes 方法实现对不同数据格式资源的支持,例如常见的 json,ymal,protobuf 等协议。

  • 在该接口之中有定义 EncoderForVersion 和 DecoderForVersion 方法来得到相应的 Encoder 和 Decoder 来进行序列化和反序列化,这里面得到的 Encoder 和 Decoder 一般就是我们上面介绍的 codec 对象。

  • codec factory 内部有 Serializerinfo 数组成员,用以支持同数据格式的资源。

  • serializerinfo 内部有关键成员 MediaType 来定义所支持的数据格式

  • serializerinfo 内部有关键成员 Serializer (别名为 Codec)来支持序列化和反序列化操作,同时 Serializer 也是 Encoder 和 Decoder 接口的组合,这个由上面 codec 相关源码可以看到。

  • 从源代码角度, codec factory 相关定义如下
// k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
type CodecFactory struct {
scheme *runtime.Scheme
universal runtime.Decoder
accepts []runtime.SerializerInfo
legacySerializer runtime.Serializer
}


// staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go
type NegotiatedSerializer interface {
SupportedMediaTypes() []SerializerInfo


EncoderForVersion(serializer Encoder, gv GroupVersioner) Encoder


DecoderToVersion(serializer Decoder, gv GroupVersioner) Decoder
}


type SerializerInfo struct {
// MediaType is the value that represents this serializer over the wire.
MediaType string
// MediaTypeType is the first part of the MediaType ("application" in "application/json").
MediaTypeType string
// MediaTypeSubType is the second part of the MediaType ("json" in "application/json").
MediaTypeSubType string


EncodesAsText bool


Serializer Serializer
.
PrettySerializer Serializer


StreamSerializer *StreamSerializerInfo
}
复制



目前先我们写到这里,在下一篇文章中我们继续来介绍 kubernates resource 序列化中 codec 和 codec factory 的生成。

文章转载自TA码字,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论