K8s source code analysis (10) - resource schema

Last In this article, we mainly introduce how codec completes the operations of decode and encode, that is, the process of object serialization and deserialization. In the core process of the decode operation, the object is first deserialized from the request, then converted to the target version (usually the build), and then processed. During the encode operation, first convert the object (usually the build object) into the target version, and then serialize it into the response data stream.

In this article, we mainly introduce schema, which is the core data structure of kubernetes resource management. from Previous articles We know that kubernetes divides the resources it manages into the concept of group/version/kind. We can convert resources between internal versions and other versions. We can identify resource types, create resource objects, set default values, etc. in the process of serialization and deserialization. The corresponding relationship between group/version/kind and resource model, the default value function of resource model, and the mutual conversion functions between different versions are maintained by schema. It can be said that schema is the core of kubernetes resources. Its data structure is as follows:

The core code is defined as follows:

// kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go
type Scheme struct {
  gvkToType map[schema.GroupVersionKind]reflect.Type

  typeToGVK map[reflect.Type][]schema.GroupVersionKind

  unversionedTypes map[reflect.Type]schema.GroupVersionKind

  unversionedKinds map[string]reflect.Type

  fieldLabelConversionFuncs map[schema.GroupVersionKind]FieldLabelConversionFunc

  defaulterFuncs map[reflect.Type]func(interface{})

  converter *conversion.Converter

  versionPriority map[string][]string

  observedVersions []schema.GroupVersion

  schemeName string
}

From the above diagram and source code, the schema structure mainly has the following key points:

  • Contains the gvkToType attribute of map type to maintain the relationship between GVK and model object types.
  • Include the typeToGVK attribute of map type to maintain the relationship between model object type and GVK.
  • The defaulterFuncs attribute containing the map type maintains the relationship between the model object type and the default value function.
  • The converter attribute containing the conversion.Converter pointer type realizes the conversion of different versions of resources.
  • The fieldlabelconversionfunctions attribute of map type maintains the relationship between GVK label conversion functions.
  • The schemaName property containing string type is used to define the name of the schema.

From the data structure of the above schema, it is a struct type. In addition, it also implements some interfaces, so that schema can create resource objects, assign default values to resource objects, identify resource object types, complete the conversion between resource objects in this version, complete the conversion of resource label labels, etc. The interface implementation is shown in the figure below:

The core code of the function implemented by the interface is defined as follows:

// kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go
func (s *Scheme) Convert(in, out interface{}, context interface{}) error{...}
func (s *Scheme) ConvertToVersion(in Object, target GroupVersioner) (Object, error){...}
func (s *Scheme) ConvertFieldLabel(gvk schema.GroupVersionKind, label, value string) (string, string, error){...}

func (s *Scheme) Default(src Object){...}

func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) {...}

func (s *Scheme) ObjectKinds(obj Object) ([]schema.GroupVersionKind, bool, error){...}
func (s *Scheme) Recognizes(gvk schema.GroupVersionKind) bool{...}

From the above diagram and source code, the schema implementation interface mainly has the following key points:

  • Implement the methods defined by the runtime.objectcreator interface to complete the creation of resources.
  • Implement the methods defined by the runtime.ObjectDefaulter interface to assign default values to resources.
  • Implement the methods defined by the runtime.ObjectConvert interface to complete the conversion between different versions of resources.
  • Implement the methods defined by the runtime.ObjecTyper interface to complete the type identification of resources.

Now let's write here. In the next article, we will continue to introduce how the kubernetest resource is registered in the schema.

Posted by scarhand on Wed, 17 Nov 2021 19:52:44 -0800