【K8S内外部版本】一文了解 Kubernetes 资源内部版本internal与外部版本v1等及Schema注册

本文主要是介绍【K8S内外部版本】一文了解 Kubernetes 资源内部版本internal与外部版本v1等及Schema注册,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考

  • 【k8s基础篇】k8s scheme1 之内外部版本_apiserver 外部版本和内部版本-CSDN博客
  • K8s源码分析(3)-Resource Version-CSDN博客
  • k8s 资源外部版本和内部版本_k8s 资源有哪些版本-CSDN博客

理解

内部版本与外部版本

路径信息
  • 内部版本路径
    • pkg/api/<group>/ ,如 Deploy 所在 Group 为 apps,内部版本路径为 pkg/api/apps/
  • 外部版本
    • vendor/k8s.io/api/<group>/<version>/ ,如 Deploy 所在 Group 为 apps,外部 v1 版本路径为 vendor/k8s.io/api/apps/v1/
    • staging/src/k8s.io/api/<group>/<version>/ ,如 Deploy 所在 Group 为 apps,外部 v1 版本路径为 staging/src/k8s.io/api/apps/v1/
    • 上面两个路径对应的文件是【同一份】,因为是【软链接】
区别与作用
  • 内部版本

    • 不对外暴露, 仅在Kubernetes API Server内部使用
    • 用于多资源版本的转换,例如将v1beta1版本转换为v1版本,其过程为v1beta1→internal→v1,即先将v1beta1转换为内部版本(internal),再由内部版本(internal)转换为v1版本
    • 内部版本资源对象通过runtime.APIVersionInternal(即__internal)进行标识
  • 外部版本

    • 用于对外暴露给用户请求的接口所使用的资源对象,例如,用户在通过YAML或JSON格式的描述文件创建资源对象时,所使用的是外部版本的资源对象
    • 外部版本的资源对象通过资源版本 (Alpha、Beta、Stable)进行标识
  • 资源的外部版本与内部版本的代码定义也不太一样

    • 外部版本的资源需要对外暴露给用户请求的接口,所以资源代码定义了JSONTags和ProtoTags,用于请求的序列化和反序列化操作。

    • 内部版本的资源不对外暴露,所以没有任何的JSONTags和ProtoTags定义。

    • 以Pod资源代码定义为例,代码示例如下。

    • // 内部版本 pkg/apis/core/types.go
      // Pod is a collection of containers, used as either input (create, update) or as output (list, get).
      type Pod struct {metav1.TypeMeta// +optionalmetav1.ObjectMeta// Spec defines the behavior of a pod.// +optionalSpec PodSpec// Status represents the current information about a pod. This data may not be up// to date.// +optionalStatus PodStatus
      }// 外部 v1 版本 vendor/k8s.io/api/core/v1/types.go
      // 同样在 staging/src/k8s.io/api/core/v1/types.go 文件中也可以找到此结构体定义// +genclient
      // +genclient:method=UpdateEphemeralContainers,verb=update,subresource=ephemeralcontainers
      // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object// Pod is a collection of containers that can run on a host. This resource is created
      // by clients and scheduled onto hosts.
      type Pod struct {metav1.TypeMeta `json:",inline"`// Standard object's metadata.// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata// +optionalmetav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`// Specification of the desired behavior of the pod.// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status// +optionalSpec PodSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`// Most recently observed status of the pod.// This data may not be up to date.// Populated by the system.// Read-only.// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status// +optionalStatus PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
      }
      

理清路径信息

  • 以下都以 Deployment 结构体为例说明,所在的 Group 为 apps

  • 内部版本的资源代码结构说明如下:

    • doc.go: GoDoc文件,定义了当前包的注释信息。在Kubernetes资源包中,它还当担了代码生成器的全局Tags描述文件;
    • register.go:定义了资源组、资源版本以及资源的注册信息;
    • type.go: 定义了在当前资源组、资源版本下所支持的资源类型;
    • v1、v1beta1、v1beta2:定义了资源组下拥有的资源版本的资源
    • install:把当前资源之下的所有资源注册到资源注册表中;
    • validation:定义了资源的验证方法;
    • zz_generated.deepcopy.go:定义了资源的深复制操作,该文件由代码生成器自动生成;
    • generated.proto 定义 protobuf 语言,用于生成 generated.pb.go,从而实现 protobuf 的序列化和反序列化
  • 内部版本

    • conversion.go :定义了资源的转换函数(默认转换函数),并将默认转换函数注册到资源注册表中。
    • zz_generated.conversion.go :定义了资源的转换函数(自动生成的转换函数),并将生成的转换函数注册到资源注册表 中。该文件由代码生成器自动生成。
    • zz_generated.defaults.go :定义了资源的默认值函数(自动生成的默认值函数),并将生成的默认值函数注册到资源注册 表中。该文件由代码生成器自动生成。
    • doc.go: GoDoc文件,定义了当前包的注释信息。在Kubernetes资源包中,它还当担了代码生成器的全局Tags描述文件;
    • register.go:定义了资源组、资源版本以及资源的注册信息;
  • 简单总结

    • type.go 定义资源的数据结构(下面进行详解)
    • 内部版本所在的文件夹(pkg/apis/apps/),也包含(v1/v1beta1/v1beta2)文件夹,但其中并没有 type.go 文件,主要包含 conversion.go 文件,用于 内部版本与这些版本的转换(v1/v1beta1/v1beta2)
    • 外部版本所在的文件夹(vendor/k8s.io/api/apps 或 kubernetes/staging/src/k8s.io/api/apps),每个子文件夹(v1/v1beta1/v1beta2)下都包含了 type.go 文件,该文件定义了不同外部版本的资源数据结构
pkg/apis/apps/(资源内部版本目录结构)
pkg/apis/apps/
├── OWNERS
├── doc.go
├── fuzzer
│   └── fuzzer.go
├── install
│   └── install.go            # 把当前资源组之下的所有资源注册到 Schema 中,让 apiserver 了解该资源组 Group 有哪些资源及相应的 go struct 数据结构
├── register.go								# 内部版本的注册
├── types.go                  # 内部版本资源数据结构定义  internal
├── v1
│   ├── conversion.go                  # 资源转换函数
│   ├── conversion_test.go		
│   ├── defaults.go										 # 默认值填充函数
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go										 # 资源组、资源版本及资源注册等信息,可以从此处点击结构体,跳转到外部版本的 type.go 中
│   ├── zz_generated.conversion.go		 # 自动生成的资源转换函数
│   └── zz_generated.defaults.go			 # 自动生成的默认值填充函数
├── v1beta1
│   ├── conversion.go
│   ├── defaults.go
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go
│   ├── zz_generated.conversion.go
│   └── zz_generated.defaults.go
├── v1beta2
│   ├── conversion.go
│   ├── conversion_test.go
│   ├── defaults.go
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go
│   ├── zz_generated.conversion.go
│   └── zz_generated.defaults.go
├── validation
│   ├── validation.go
│   └── validation_test.go
└── zz_generated.deepcopy.go7 directories, 32 files
vendor/k8s.io/api/apps(资源外部版本目录结构)

该目录其实就是 kubernetes/staging/src/k8s.io/api/apps,他们关系就是软链接(可以理解为 快捷方式),其实就是同一份文件,改一个另一个就会变化

vendor/k8s.io/api/apps(kubernetes/staging/src/k8s.io/api/apps)
├── OWNERS
├── v1
│   ├── doc.go
│   ├── generated.pb.go
│   ├── generated.proto												# 序列化
│   ├── register.go
│   ├── types.go															# 外部版本资源数据结构定义,对外暴露 版本号 v1
│   ├── types_swagger_doc_generated.go
│   └── zz_generated.deepcopy.go
├── v1beta1
│   ├── doc.go
│   ├── generated.pb.go                       # 用于进行 protobuf 序列化和反序列化
│   ├── generated.proto												# 用于生成 generated.pb.go
│   ├── register.go
│   ├── types.go															# 外部版本,对外暴露 版本号 v1beta1
│   ├── types_swagger_doc_generated.go				# 猜测 用于生成 swagger api 文档
│   ├── zz_generated.deepcopy.go              # 自动生成的 深拷贝函数
│   └── zz_generated.prerelease-lifecycle.go  # 自动生成的 预处理或生命周期相关的函数 
└── v1beta2├── doc.go├── generated.pb.go├── generated.proto├── register.go├── types.go															# 外部版本,对外暴露 版本号 v1beta2├── types_swagger_doc_generated.go├── zz_generated.deepcopy.go└── zz_generated.prerelease-lifecycle.go4 directories, 24 files

Schema 注册的实现

  • 下面以 Deployment 所在的 apps Group 组为例,分析 apps Group 的 register.go 文件

register.go 文件(资源的数据结构注册)

内部版本的资源结构体注册
  • 内部版本 internal
// 路径 pkg/apis/apps/register.gopackage appsimport ("k8s.io/apimachinery/pkg/runtime""k8s.io/apimachinery/pkg/runtime/schema""k8s.io/kubernetes/pkg/apis/autoscaling"
)var (// SchemeBuilder stores functions to add things to a scheme.// dfy: 可以将 SchemeBuilder 当做一个数组,同时此数组存储的是类型是函数,目前存储的是 addKnownTypes 函数(该函数就是注册该 GVK 对应的资源 go struct)SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)// AddToScheme applies all stored functions t oa scheme.// dfy: 供外部调用,调用方式为 AddToScheme(scheme),用户调用传入参数 scheme 到 AddToScheme 中,便可将该 GVK 对应的资源 go struct 注册到 scheme 中AddToScheme = SchemeBuilder.AddToScheme
)// GroupName is the group name use in this package
const GroupName = "apps"// SchemeGroupVersion is group version used to register these objects
// dfy: runtime.APIVersionInternal 表示内部版本
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {return SchemeGroupVersion.WithKind(kind).GroupKind()
}// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {return SchemeGroupVersion.WithResource(resource).GroupResource()
}// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {// TODO this will get cleaned up with the scheme types are fixedscheme.AddKnownTypes(SchemeGroupVersion,&DaemonSet{},&DaemonSetList{},&Deployment{},&DeploymentList{},&DeploymentRollback{},&autoscaling.Scale{},&StatefulSet{},&StatefulSetList{},&ControllerRevision{},&ControllerRevisionList{},&ReplicaSet{},&ReplicaSetList{},)return nil
}
外部版本的资源结构体注册
  • 以 apps/v1 举例
  • 外部版本有两个 register.go 文件
    • 第一个 register.go 文件( pkg/apis/apps/v1/register.go 其父目录与内部版本 type.go 文件在同一级),其实就相当于封装一层,供外部调用
    • 第二个 register.go 文件(vendor/k8s.io/api/apps/v1/register.go 或 staging/src/k8s.io/api/apps/v1/register.go,和外部版本 type.go 文件在同一级),其才是真正的 Schema 注册函数
  • 首先介绍第一个 register.go 文件
    • 该函数并没有直接包含资源 go struct 注册函数 addKnownTypes,而是进行了一层封装,通过localSchemeBuilder = &appsv1.SchemeBuilder 来调用
    • 同时注意到,相比于内部版本,多了个init 函数,该函数主要作用就是【为当前版本的资源数据填充默认值】
// pkg/apis/apps/v1/register.go
// 该文件父目录与内部版本 type.go 文件,在同一个层级package v1import (appsv1 "k8s.io/api/apps/v1""k8s.io/apimachinery/pkg/runtime/schema"
)// GroupName is the group name use in this package
const GroupName = "apps"// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {return SchemeGroupVersion.WithResource(resource).GroupResource()
}var (// dfy: localSchemeBuilder 就是个数组,存储的是函数,但是奇怪,我们未见到 AddKnownTypes 注册资源 go struct 的函数?// dfy: 跳转便能看到,该函数写在和 外部资源定义 type.go 同文件夹内localSchemeBuilder = &appsv1.SchemeBuilder// dfy: 供外部调用来使用此 Group 的资源,如外部定义变量 scheme,可以如下调用 AddToScheme(scheme),便可以将该 Group 的资源 go struct 注册到外部 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.// dfy: 注册一些默认值填充函数localSchemeBuilder.Register(addDefaultingFuncs)
}
  • 接下来介绍第二个 register.go 文件
    • 主要进行资源 go struct 的注册,对应 addKnownTypes 函数
// 路径 vendor/k8s.io/api/apps/v1/register.go
// 或 staging/src/k8s.io/api/apps/v1/register.go
// 这两个文件时同一份,软链接形成的package v1import (metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/runtime""k8s.io/apimachinery/pkg/runtime/schema"
)// GroupName is the group name use in this package
const GroupName = "apps"// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {return SchemeGroupVersion.WithResource(resource).GroupResource()
}var (// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.// dfy: 可以看到,此处就是数组,保存 Scheme 注册函数SchemeBuilder      = runtime.NewSchemeBuilder(addKnownTypes)// dfy: 小写字母开头,无法被外部调用,因此是供该 package 内部使用localSchemeBuilder = &SchemeBuilder// dfy: 此处可供外部调用,进行 Scheme 注册AddToScheme        = localSchemeBuilder.AddToScheme
)// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {scheme.AddKnownTypes(SchemeGroupVersion,&Deployment{},&DeploymentList{},&StatefulSet{},&StatefulSetList{},&DaemonSet{},&DaemonSetList{},&ReplicaSet{},&ReplicaSetList{},&ControllerRevision{},&ControllerRevisionList{},)metav1.AddToGroupVersion(scheme, SchemeGroupVersion)return nil
}

Schema 包的分析

  • 困惑点

    • 总会见到下面两个函数,是什么意思呢?

      • // 函数数组,存储 addKnownTypes 函数
        SchemeBuilder      = runtime.NewSchemeBuilder(addKnownTypes)
        // 供外部调用,使用此 Group 的资源 
        AddToScheme        = localSchemeBuilder.AddToScheme
        
    • 也会见到此函数,常在 init 函数中出现,是什么意思呢?

      • 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.// dfy: 注册一些默认值填充函数localSchemeBuilder.Register(addDefaultingFuncs)
        }
        
  • 答疑

    • 首先分析 Schema package
// 路径 vendor/k8s.io/apimachinery/pkg/runtime/scheme_builder.go
// 调用该包,使用 import "k8s.io/apimachinery/pkg/runtime" 语句package runtime// SchemeBuilder collects functions that add things to a scheme. It's to allow
// code to compile without explicitly referencing generated types. You should
// declare one in each package that will have generated deep copy or conversion
// functions.
// dfy: 可以看出 SchemeBuilder 是个数组,存储的是函数类型,函数类型为 func(*Scheme) error
type SchemeBuilder []func(*Scheme) error// NewSchemeBuilder calls Register for you.
// dfy: 该函数就是创建个 SchemeBuilders 数组,将传来的函数存入到该 SchemeBuilders 数组中,函数需要满足 func(*Scheme) error 形式,可以传入多个
func NewSchemeBuilder(funcs ...func(*Scheme) error) SchemeBuilder {var sb SchemeBuilder// dfy: 将函数 funcs 存入到 sb SchemeBuilders 数组中sb.Register(funcs...)return sb
}// Register adds a scheme setup function to the list.
// dfy: 将函数 funcs 存入到 sb SchemeBuilders 数组中,存入形式是 appends,是递增的,不会影响之前存入的
func (sb *SchemeBuilder) Register(funcs ...func(*Scheme) error) {for _, f := range funcs {*sb = append(*sb, f)}
}// AddToScheme applies all the stored functions to the scheme. A non-nil error
// indicates that one function failed and the attempt was abandoned.
// dfy:逐个取出 SchemeBuilder 存放的函数,对入参 Scheme 执行此函数
// 就相当于取出 SchemeBuilder 中的 addKnowTypes 或 addDefaultingFuncs 函数,对入参 Scheme 变量 s 执行这些函数,实现资源 go struct的注册或默认值填充
func (sb *SchemeBuilder) AddToScheme(s *Scheme) error {for _, f := range *sb {if err := f(s); err != nil {return err}}return nil
}

了解默认值填充函数

  • 内部版本所在的文件夹下,包含外部版本 (v1/v1beta1/v1beta2) 等子文件夹
    • 外部版本子文件夹相比于内部版本多了几个文件,其中涉及默认值的为 zz_generated.defaults.go 和 defaults.go
    • zz_generated.defaults.go文件为【自动生成的】资源对象默认值填充函数
    • defaults.go文件为【人为编写的】资源对象默认值填充函数
pkg/apis/apps/
├── OWNERS
├── doc.go
├── fuzzer
│   └── fuzzer.go
├── install
│   └── install.go            # 把当前资源组之下的所有资源注册到 Schema 中,让 apiserver 了解该资源组 Group 有哪些资源及相应的 go struct 数据结构
├── register.go								# 内部版本的注册
├── types.go                  # 内部版本资源数据结构定义  internal
├── v1
│   ├── conversion.go                  # 资源转换函数
│   ├── conversion_test.go		
│   ├── defaults.go										 # 默认值填充函数
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go										 # 资源组、资源版本及资源注册等信息,可以从此处点击结构体,跳转到外部版本的 type.go 中
│   ├── zz_generated.conversion.go		 # 自动生成的资源转换函数
│   └── zz_generated.defaults.go			 # 自动生成的默认值填充函数
├── v1beta1
│   ├── conversion.go
│   ├── defaults.go
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go
│   ├── zz_generated.conversion.go
│   └── zz_generated.defaults.go
├── v1beta2
│   ├── conversion.go
│   ├── conversion_test.go
│   ├── defaults.go
│   ├── defaults_test.go
│   ├── doc.go
│   ├── register.go
│   ├── zz_generated.conversion.go
│   └── zz_generated.defaults.go
├── validation
│   ├── validation.go
│   └── validation_test.go
└── zz_generated.deepcopy.go7 directories, 32 files
  • 分析调用关系
    • zz_generated.defaults.go文件为【自动生成的】资源对象默认值填充函数
    • defaults.go文件为【人为编写的】资源对象默认值填充函数
// 以 pkg/apis/apps/v1 为例,apps 外部版本 v1 文件夹
// 1. 首先查看 pkg/apis/apps/v1/register.go
// 该文件的 init 函数,预先将 addDefaultingFuncs 默认值注册函数,append 到 SchemeBuilder 数组中,之后调用 AddScheme 便会自动执行该 addDefaultingFuncs 函数,实现资源默认值的填充
var (// dfy: localSchemeBuilder 就是个数组,存储的是函数,但是奇怪,我们未见到 AddKnownTypes 注册资源 go struct 的函数?// dfy: 跳转便能看到,该函数写在和 外部资源定义 type.go 同文件夹内localSchemeBuilder = &appsv1.SchemeBuilder// dfy: 供外部调用来使用此 Group 的资源,如外部定义变量 scheme,可以如下调用 AddToScheme(scheme),便可以将该 Group 的资源 go struct 注册到外部 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.// dfy: 注册一些默认值填充函数localSchemeBuilder.Register(addDefaultingFuncs)
}// 2. 点击 addDefaultingFuncs 跳转
// pkg/apis/apps/v1/defaults.go
func addDefaultingFuncs(scheme *runtime.Scheme) error {return RegisterDefaults(scheme)
}// 3. 点击 RegisterDefaults(scheme) 继续跳转
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {scheme.AddTypeDefaultingFunc(&v1.DaemonSet{}, func(obj interface{}) { SetObjectDefaults_DaemonSet(obj.(*v1.DaemonSet)) })scheme.AddTypeDefaultingFunc(&v1.DaemonSetList{}, func(obj interface{}) { SetObjectDefaults_DaemonSetList(obj.(*v1.DaemonSetList)) })scheme.AddTypeDefaultingFunc(&v1.Deployment{}, func(obj interface{}) { SetObjectDefaults_Deployment(obj.(*v1.Deployment)) })scheme.AddTypeDefaultingFunc(&v1.DeploymentList{}, func(obj interface{}) { SetObjectDefaults_DeploymentList(obj.(*v1.DeploymentList)) })scheme.AddTypeDefaultingFunc(&v1.ReplicaSet{}, func(obj interface{}) { SetObjectDefaults_ReplicaSet(obj.(*v1.ReplicaSet)) })scheme.AddTypeDefaultingFunc(&v1.ReplicaSetList{}, func(obj interface{}) { SetObjectDefaults_ReplicaSetList(obj.(*v1.ReplicaSetList)) })scheme.AddTypeDefaultingFunc(&v1.StatefulSet{}, func(obj interface{}) { SetObjectDefaults_StatefulSet(obj.(*v1.StatefulSet)) })scheme.AddTypeDefaultingFunc(&v1.StatefulSetList{}, func(obj interface{}) { SetObjectDefaults_StatefulSetList(obj.(*v1.StatefulSetList)) })return nil
}// 4. 随便点击(如 SetObjectDefaults_DaemonSet)继续跳转,此时点击内部 SetDefaults_XX 函数,即可跳转到 用户自定义的 defaults.go 函数
// pkg/apis/apps/v1/zz_generated.defaults.go
func SetObjectDefaults_DaemonSet(in *v1.DaemonSet) {// dfy: 用户自定义的默认值填充函数// 跳转到 pkg/apis/apps/v1/defaults.goSetDefaults_DaemonSet(in)// dfy: 其他组,用户自定以的默认值填充函数// 跳转到 pkg/apis/core/v1/defaults.gocorev1.SetDefaults_PodSpec(&in.Spec.Template.Spec)for i := range in.Spec.Template.Spec.Volumes {a := &in.Spec.Template.Spec.Volumes[i]corev1.SetDefaults_Volume(a)...}...
}

install.go 将类型注册到 apiserver

  • 内部版本所在的目录有个子目录 install,其中包含着 install.go 文件,该文件实现将该 Group 的【所有版本的资源数据结构】注册到【apiserver全局scheme】中

    • 以 apps Group 为例
  • 该文件也串起了整个流程

    • legacyscheme.Scheme 是kube-apiserver组件的全局资源注册表
    • 调用 Install 函数,legacyscheme.Scheme作为scheme变量传入
    • 之后调用utilruntime.Must(v1beta1.AddToScheme(scheme)) 等类似函数
      • AddToScheme 会调用 SchemeBuilder中注册的addKnownTypesaddDefaultingFuncs函数,实现将 apps Group 的资源数据结构注册和资源默认值填充等映射关系写入到 legacyscheme.Scheme
  • 首选版本(PreferredVersion),也称优选版本(PriorityVersion),一个资源组下拥有多个资源版本,例如,apps资源组拥有v1、v1beta1、v1beta2等资源版本。当我们使用apps资源组下的Deployment资源时,在一些场景下,如不指定资源版本,则使用该资源的首选版本。

    • scheme.SetVersionPriority注册版本顺序很重要,apps资源组的注册版本顺序为v1、v1beta2、v1beta1

    • 当通过资源注册表scheme.PreferredVersionAllGroups函数获取所有资源组下的首选版本时,将位于最前面的资源版本作为首选版本

    • utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1beta1.SchemeGroupVersion))
      
// 路径 pkg/apis/apps/install/install.gopackage installimport ("k8s.io/apimachinery/pkg/runtime"utilruntime "k8s.io/apimachinery/pkg/util/runtime""k8s.io/kubernetes/pkg/api/legacyscheme""k8s.io/kubernetes/pkg/apis/apps""k8s.io/kubernetes/pkg/apis/apps/v1""k8s.io/kubernetes/pkg/apis/apps/v1beta1""k8s.io/kubernetes/pkg/apis/apps/v1beta2"
)func init() {// dfy: legacyscheme.Scheme是kube-apiserver组件的全局资源注册表,// dfy: Kubernetes的所有资源信息都交给资源注册表统一管理。Install(legacyscheme.Scheme)
}// Install registers the API group and adds types to a scheme
// dfy:
// - 将资源信息注册到资源注册表 Scheme 中
// - Scheme 是 apiserver 的全局资源注册表,记录资源版本与对应结构体的信息
func Install(scheme *runtime.Scheme) {// dfy: apps group 资源的[internal 内部版本]信息  apps/internal//  utilruntime.Must 函数通常用于简化错误处理过程。//  它的作用是接收一个函数调用,并检查该函数调用是否返回了错误。//  如果函数调用返回了错误,utilruntime.Must 会抛出 panic,并输出错误信息,导致程序终止。utilruntime.Must(apps.AddToScheme(scheme))// dfy: apps group 资源的 v1beta1 版本信息 apps/v1beta1utilruntime.Must(v1beta1.AddToScheme(scheme))// dfy: apps group 资源的 v1beta2 版本信息 apps/v1beta2utilruntime.Must(v1beta2.AddToScheme(scheme))// dfy: apps group 资源的 v1 版本信息  apps/v1utilruntime.Must(v1.AddToScheme(scheme))// dfy: 资源版本使用顺序,v1,v1betea2,v1beta1, 此处不包含内部版本// 当通过资源注册表scheme.PreferredVersionAllGroups函数获取所有资源组下的首选版本时,将位于最前面的资源版本作为首选版本utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1beta1.SchemeGroupVersion))
}

这篇关于【K8S内外部版本】一文了解 Kubernetes 资源内部版本internal与外部版本v1等及Schema注册的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/776532

相关文章

centos7基于keepalived+nginx部署k8s1.26.0高可用集群

《centos7基于keepalived+nginx部署k8s1.26.0高可用集群》Kubernetes是一个开源的容器编排平台,用于自动化地部署、扩展和管理容器化应用程序,在生产环境中,为了确保集... 目录一、初始化(所有节点都执行)二、安装containerd(所有节点都执行)三、安装docker-

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

一文带你搞懂Nginx中的配置文件

《一文带你搞懂Nginx中的配置文件》Nginx(发音为“engine-x”)是一款高性能的Web服务器、反向代理服务器和负载均衡器,广泛应用于全球各类网站和应用中,下面就跟随小编一起来了解下如何... 目录摘要一、Nginx 配置文件结构概述二、全局配置(Global Configuration)1. w

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se