本文主要是介绍【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
函数,该函数主要作用就是【为当前版本的资源数据填充默认值】
- 该函数并没有直接包含资源 go struct 注册函数 addKnownTypes,而是进行了一层封装,通过
// 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
中注册的addKnownTypes
和addDefaultingFuncs
函数,实现将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注册的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!