9. apiserver(六、scheme)
9.1 scheme设计
apiserver从设计上分为api和server两部分,将资源处理解耦出来,其中api包含资源相关的信息,如:资源定义、gvk映射、版本转换等,而server主要负责通用的请求处理流程,如路由、鉴权、超时处理等。
9.2 scheme字段
type Scheme struct {
// gvkToType allows one to figure out the go type of an object with
// the given version and name.
gvkToType map[schema.GroupVersionKind]reflect.Type
// typeToGVK allows one to find metadata for a given go object.
// The reflect.Type we index by should *not* be a pointer.
typeToGVK map[reflect.Type][]schema.GroupVersionKind
// unversionedTypes are transformed without conversion in ConvertToVersion.
unversionedTypes map[reflect.Type]schema.GroupVersionKind
// unversionedKinds are the names of kinds that can be created in the context of any group
// or version
// TODO: resolve the status of unversioned types.
unversionedKinds map[string]reflect.Type
// Map from version and resource to the corresponding func to convert
// resource field labels in that version to internal version.
fieldLabelConversionFuncs map[schema.GroupVersionKind]FieldLabelConversionFunc
// defaulterFuncs is a map to funcs to be called with an object to provide defaulting
// the provided object must be a pointer.
defaulterFuncs map[reflect.Type]func(interface{})
// converter stores all registered conversion functions. It also has
// default converting behavior.
converter *conversion.Converter
// versionPriority is a map of groups to ordered lists of versions for those groups indicating the
// default priorities of these versions as registered in the scheme
versionPriority map[string][]string
// observedVersions keeps track of the order we've seen versions during type registration
observedVersions []schema.GroupVersion
// schemeName is the name of this scheme. If you don't specify a name, the stack of the NewScheme caller will be used.
// This is useful for error reporting to indicate the origin of the scheme.
schemeName string
}
以下是对重要字段的解释:
| 字段 | 用途 |
|---|---|
| gvkToType | 利用gvk信息构建实例 |
| typeToGvk | 提取实例的gvk信息 |
| converter | 版本转换函数,在内外版本进行转换 |
| defaulterFuncs | 默认值设置函数,对用户没有设置的字段进行赋值 |
| versionPriority | 存储版本优先级 |
9.3 导入流程
apiserver导入scheme使用了go的init机制,同时采用了解耦的思想将具体的包与apiserver解除绑定,引入import_known_versions和intsall避免增加版本时修改apiserver。
具体的导入代码:
var (
localSchemeBuilder = &admissionv1beta1.SchemeBuilder
// AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(RegisterDefaults)
}
实际导入的时候用了builder模式,使用SchemeBuilder组装需要应用的函数,调用AddToScheme最终完成注册:
NewSchemeBuilder -> Register -> Register -> ... -> AddToScheme
实际用的时候,也有将需要应用的函数在NewSchemeBuilder就传入了,不再Register的情况。