k8s源码学习-资源注册表
kubernetes系统有很多资源,资源需要统一的注册、存储、查询和管理,都注册到schema资源注册表中(内存型的资源注册表),k8s schema有以下几个特点:
- 支持多种资源类型,包括内部版本和外部版本
- 支持版本转换
- 支持多种资源序列化和反序列化
- 支持两种资源类型Type的注册,UnversionedType和KnownType,UnversionedType 无版本资源类型,例如:metav1.Status、metav1.APIVersions、metav1.APIGroupList、metav1.APIGroup、metav1.APIResourceList,KnownType是k8s最常见的一种资源注册方法,通过scheme.AddKnownTypes注册
schema注册表主要由4个map组成,代码和方法说明如下:
代码:vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
type Scheme struct {
// gvkToType allows one to figure out the go type of an object with
// the given version and name.
// 存储gvk与type的映射关系,
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.
//储存type与gvk的映射关系,一个type可以对应多个gvk
typeToGVK map[reflect.Type][]schema.GroupVersionKind
// unversionedTypes are transformed without conversion in ConvertToVersion
// 存储unversionedTypes于gvk映射关系
unversionedTypes map[reflect.Type]schema.GroupVersionKind
//存储kind资源种类与unversionedKinds的对应关系
// 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
//其他的省略.......
}
资源注册方法
scheme.AddKnownTypes 注册KnownTypes对象
scheme.AddUnversionedTypes 注册UnversionedTypes类型对象
scheme.AddKnownTypeWithName 注册KnownTypes对象,需要指定Kind资源种类名称
代码:vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
资源注册的默认Kind
GVK(资源组,资源版本,资源种类)在schema注册表中以<group>/<version>,Kind=<kind>形式展示,如果注册的时候没有指定kind,那么默认使用类型的名称,例如,注册corev1.pod类型,通过reflect机制获取资源类型的名称pod,那么Kind=pod
代码:vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Object) {
s.addObservedVersion(version)
s.AddKnownTypes(version, types...)
for _, obj := range types {
t := reflect.TypeOf(obj).Elem()
gvk := version.WithKind(t.Name())
s.unversionedTypes[t] = gvk
if old, ok := s.unversionedKinds[gvk.Kind]; ok && t != old {
panic(fmt.Sprintf("%v.%v has already been registered as unversioned kind %q - kind name must be unique in scheme %q", old.PkgPath(), old.Name(), gvk, s.schemeName))
}
s.unversionedKinds[gvk.Kind] = t
}
}
给一个例子:
// KnownType external
coreGV : = schema.GroupVersion{Group: "", Version: "v1"}
extensionsGV : = schema.GroupVersion (Group: "extensions", Version "v1beta1"}
// KnownType internal
coreInternalGV : = schema.GroupVersion(Group: "", Version:
runtime.APIVersionInternal}
// UnversionedType
Unversioned: = schema.GroupVersion(Group: "'. Version: "v1"'}
scheme := runtime.NewScheme()
scheme. AddKnownTypes (coreGV, &corev1.Pod(})
scheme. AddKnownTypes (extensionsGV , &appsv1.DaemonSet(})
scheme. AddKnownTypes (coreInternalGV , &corev1.Pod})
scheme. AddUnversionedtypes (Unversioned, &metav1.Status())
通过上面示例的方法注册,能得到什么映射结果呢?
gvkToType map[schema.GroupVersionKind]reflect.Type:
/v1,Kind=Pod: v1.Pod
extension/v1beta1:Kind=DaemonSet: v1.daemonSet
/_internal,Kind=Pod: v1.Pod
/v1,Kind=Status: v1.Status
typeToGVK map[reflect.Type][]schema.GroupVersionKind:
v1.Pod: ["/v1,Kind=Pod","/_internal,Kind=Pod"]
v1.daemonSet: ["extension/v1beta1:Kind=DaemonSet"]
v1.Status:["/v1,Kind=Status"]
unversionedTypes map[reflect.Type]schema.GroupVersionKind:
v1.Status: ["/v1,Kind=Status"]
unversionedKinds map[string]reflect.Type:
Status: ["v1.Status"]