图解kubernetes中的api多版本中反序列化与转换
在之前的文章中分析过kubernetes是如何进行多版本管理中提到了一个关键的设计解码器, 负责将请求对象反序列化成一个具体的数据模型,今天一起来了解下其内部是如何实现多版本管理、转换的设计要点
1.版本化管理的关键设计
1.1 从拓扑转换到星状转换
在通常的web开发中更多的时候,大家都是断代向前兼容更新,大多数情况下当版本更新之后会独立演进,如果要在多版本之间转换通常则会出现如下的情况 
1.2 兼容设计之转换

1.3 转换的最终之反射

2. 关键设计的实现
为了实现上面的方案,kubernetes中设计了如下组件:Scheme(负责各个版本的注册和管理)、Convert(转换实现)、Serializer(实现对应版本的反序列化),让我们依次看下其关键设计
2.1 Convert
Convert实现从一个目标对象到另外一个目标对象的转换, 为了实现这种转换,kubernetes里面主要是借助反射和不同版本的转换函数来共同完成
1.首先我们通过目标函数来获取对应的属性字段,然后针对该字段进行计算赋值操作 2.如果发现对应的字段需要来转换,则会调用对应的转换函数来进行赋值操作,如果不需要转换则会直接通过反射来进行赋值
2.2 外部版本到内部版本的转换

2.3 Scheme

Scheme对象是一个复合的数据结构,其实现了多种结果,诸如typer、defaulter、creater等,很多地方都是通过直接传递scheme来进行对应的参数的填充, 其内部关键数据结构如下
GVK与资源类型的映射,以及当前资源类型支持哪些GVK
gvkToType map[schema.GroupVersionKind]reflect.Type
typeToGVK map[reflect.Type][]schema.GroupVersionKind
则创建对象的时候可以直接通过New来实例化对应的对象
func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) {
if t, exists := s.gvkToType[kind]; exists {
// 利用反射来创建对象
return reflect.New(t).Interface().(Object), nil
}
// 省略相关代码
}
默认初始化函数
defaulterFuncs map[reflect.Type]func(interface{})
根据对应的类型来完成初始化操作
func (s *Scheme) Default(src Object) {
if fn, ok := s.defaulterFuncs[reflect.TypeOf(src)]; ok {
fn(src)
}
}
提供转换函数注册接口, 注册到convert中
func (s *Scheme) AddConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error {
return s.converter.RegisterUntypedConversionFunc(a, b, fn)
}
3.学习总结

> 关注公告号阅读更多源码分析文章
> 更多文章关注 www.sreguide.com > 本文由博客一文多发平台 OpenWrite 发布
