上一篇文章,主要以 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 的生成。