0
点赞
收藏
分享

微信扫一扫

k8s源码学习-资源注册表

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"]
举报

相关推荐

0 条评论