Kubernetes版本:v1.18.4
一、介绍
在kubernetes中,一切皆资源。
在kubernetes中,对资源进行了分组以及版本化,它们分为Group(资源组)、Version(资源版本)、Resource(资源)、Kind(种类)。其中:
- Group:资源组,在Kubernetes API Server中也称为APIGroup
- Version:资源版本,在Kubernetes API Server中也成为APIVersions
- Resource:资源,在Kubernetes API Server中也成为APIResource
- Kind:种类,描述Resource的种类
整体的数据结构关系如图所示:
Kubernetes系统支持多个Group,每个Group支持多个Version,每个Version支持多个Resource,其中部分资源同时会拥有自己的子资源(即SubResource)。
资源组、资源版本、资源、子资源的完整表现形式为
每一个资源都拥有一定数量的资源操作方法(即Verbs),资源操作方法用于Etcd集群存储中对资源对象的增、删、改、查操作。目前Kubernetes系统支持8种资源操作方法,分别是create、delete、deletecollection、get、list、patch、update、watch操作方法。
每一个资源都至少有两个版本,分别是外部版本(External Version)和内部版本(Internal Version)。外部版本用于对外暴露给用户请求的接口所使用的资源对象。内部版本不对外暴露,仅在Kubernetes API Server内部使用。
Kubernetes资源也可分为两种,分别是Kubernetes Resource(Kubernetes内置资源)和Custom Resource(自定义资源)。开发者通过CRD(即CustomResource Definitions)可实现自定义资源,它允许用户将自己定义的资源添加到Kubernetes系统中,并像使用Kubernetes内置资源一样使用它们。
源码位置:staging\src\k8s.io\apimachinery\pkg\runtime\schema\group_version.go
type GroupVersionResource struct {
Group string
Version string
Resource string
}
常用的资源数据结构都定义在这个文件中。
结构名称 | 说明 |
---|---|
GroupVersionResource | 定义资源组、资源版本、资源 |
GroupResource | 定义资源组、资源 |
GroupKind | 定义资源组、资源种类 |
GroupVersionKind | 定义资源组、资源版本、资源种类 |
GroupVersion | 定义资源组、资源版本 |
GroupVersions | 定义多个资源版本 |
二、Group 资源组
Group叫做资源组,在Kubernetes API Server中也可称其为APIGroup。Kubernetes系统中定义了许多资源组,这些资源组按照不同功能将资源进行了划分,资源组特点如下。
- 将众多资源按照功能划分成不同的资源组,并允许单独启用/禁用资源组。当然也可以单独启用/禁用资源组中的资源。
- 支持不同资源组中拥有不同的资源版本。这方便组内的资源根据版本进行迭代升级。
- 支持同名的资源种类(即Kind)存在于不同的资源组内。
- 资源组与资源版本通过Kubernetes API Server对外暴露,允许开发者通过HTTP协议进行交互并通过动态客户端(即DynamicClient)进行资源发现。
- 支持CRD自定义资源扩展。
- 用户交互简单,例如在使用kubectl命令行工具时,可以不填写资源组名称。
其代码路径:staging\src\k8s.io\apimachinery\pkg\apis\meta\v1\types.go
定义如下:
type APIGroup struct {
TypeMeta `json:",inline"`
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Versions []GroupVersionForDiscovery `json:"versions" protobuf:"bytes,2,rep,name=versions"`
PreferredVersion GroupVersionForDiscovery `json:"preferredVersion,omitempty" protobuf:"bytes,3,opt,name=preferredVersion"`
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs,omitempty" protobuf:"bytes,4,rep,name=serverAddressByClientCIDRs"`
}
其中:
- Name:资源组的名称
- Versions:资源组的版本,一个资源组可以有多个版本
- PreferredVersion:首选版本,如果有多个资源版本,则指定一个版本为首选版本
- ServerAddressByClientCIDRs:客户端和服务端的映射,方便客户端找服务端地址
在当前的Kubernetes系统中,支持两类资源组,分别是拥有组名的资源组和没有组名的资源组。
- 拥有组名:
/ / ,例如apps/v1/deployments,通过http访问的路径为:http://localhost:6443/apis/ / / - 没有组名:
/ ,例如/v1/pods,通过http访问的路径为:http://localhost:6443/api/ / 没有组名的资源组,表示资源组名称为空。用来表示核心资源组下的v1资源版本。
三、Version 版本
Kubernetes的资源版本控制可分为3种,分别是Alpha、Beta、Stable,它们之间的迭代顺序为Alpha→Beta→Stable,其通常用来表示软件测试过程中的3个阶段。Alpha是第1个阶段,一般用于内部测试;Beta是第2个阶段,该版本已经修复了大部分不完善之处,但仍有可能存在缺陷和漏洞,一般由特定的用户群来进行测试;Stable是第3个阶段,此时基本形成了产品并达到了一定的成熟度,可稳定运行。
代码路径:staging\src\k8s.io\apimachinery\pkg\apis\meta\v1\types.go
type APIVersions struct {
TypeMeta `json:",inline"`
Versions []string `json:"versions" protobuf:"bytes,1,rep,name=versions"`
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,2,rep,name=serverAddressByClientCIDRs"`
}
其中:
- Versions:资源版本列表,可以有多个版本
- ServerAddressByClientCIDRs:客户端和服务端的映射关系,方便客户端查找服务端地址
四、Resource 资源
在Kubernetes中,一切皆资源,资源被实例化后称为资源对象,所有资源对象都是Entity(实体),Kubernetes使用Entity来表示当前的状态,用户可以使用Kubernetes API Server进行查询和更新资源对象。
在Kubernetes中Entity分为两类:
- 持久性实体:kubernetes会确保该实体持久存在,比如deployment资源对象
- 短暂性实体:该实体是一次性的,比如pod资源对象
资源数据结构代码路径:staging\src\k8s.io\apimachinery\pkg\apis\meta\v1\types.go
type APIResource struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
SingularName string `json:"singularName" protobuf:"bytes,6,opt,name=singularName"`
Namespaced bool `json:"namespaced" protobuf:"varint,2,opt,name=namespaced"`
Group string `json:"group,omitempty" protobuf:"bytes,8,opt,name=group"`
Version string `json:"version,omitempty" protobuf:"bytes,9,opt,name=version"`
Kind string `json:"kind" protobuf:"bytes,3,opt,name=kind"`
Verbs Verbs `json:"verbs" protobuf:"bytes,4,opt,name=verbs"`
ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,5,rep,name=shortNames"`
Categories []string `json:"categories,omitempty" protobuf:"bytes,7,rep,name=categories"`
StorageVersionHash string `json:"storageVersionHash,omitempty" protobuf:"bytes,10,opt,name=storageVersionHash"`
}
其中:
- Name:资源名称
- SingularName:资源的单数名称,它必须由小写字母组成,默认使用资源种类(Kind)的小写形式进行命名。例如,Pod资源的单数名称为pod,复数名称为pods。
- Namespaced:资源是否有命名空间
- Group:资源所属组
- Version:资源所属的资源版本
- Kind:资源种类
- Verbs:资源的操作列表
- ShortNames:资源简称,比如deployment简称为deploy
- Categories:组资源的类别
- StorageVersionHash:存储版本的hash值
4.1、资源版本
资源版本分为外部版本和内部版本。外部版本用于对外暴露给用户请求的接口所使用的资源对象,内部版本不对外暴露,仅在Kubernetes API Server内部使用。内部版本用于多资源版本的转换,例如将v1beta1版本转换为v1版本,其过程为v1beta1→internal→v1,即先将v1beta1转换为内部版本(internal),再由内部版本(internal)转换为v1版本。内部版本资源对象通过runtime.APIVersionInternal(即__internal)进行标识。
资源版本(如v1beta1、v1等)与外部版本/内部版本概念不同。拥有资源版本的资源属于外部版本,拥有runtime.APIVersionInternal标识的资源属于内部版本。
内部版本定义的代码路径为:pkg\apis\<GROUP>\types.go
下,外部版本定义的代码路径为:pkg\apis\<GROUP>\<VERSION>\
,例如,Deployment资源,它的外部版本定义在pkg/apis/apps/{v1,v1beta1,v1beta2}/目录下,它的内部版本定义在pkg/apis/apps/目录下(内部版本一般与资源组在同一级目录下)。
外部版本的资源类型定义在staging\src\k8s.io\api\<GROUP>\<VERSION>\types.go
,内部版本的资源类型定义在pkg\apis\<GROUP>\types.go
。
资源的外部版本与内部版本的代码定义不太一样,外部版本的资源需要对外暴露给用户请求的接口,所以资源代码定义了JSON Tags和Proto Tags,用于请求的序列化和反序列化操作。内部版本的资源不对外暴露,所以没有任何的JSON Tags和Proto Tags定义。
以Deployment为例。
外部版本:staging\src\k8s.io\api\apps\v1\types.go
type Deployment struct {
metav1.TypeMeta `json:",inline"`
// Standard object metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Specification of the desired behavior of the Deployment.
// +optional
Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Most recently observed status of the Deployment.
// +optional
Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
内部版本:pkg\apis\apps\types.go
type DeploymentList struct {
metav1.TypeMeta
// +optional
metav1.ListMeta
// Items is the list of deployments.
Items []Deployment
}
4.2、资源代码定义
Kubernetes资源代码定义在pkg/apis目录下,同一资源对应着内部版本和外部版本,内部版本和外部版本的资源代码结构并不相同。
以Deployment为例,其目录结构如下:
文件说明:
- fuzzer:api组
- install:把资源组下的所有资源注册到注册表中
- v1/v1beta1/v1beta2:资源的外部版本
- validation:定义资源的验证方法
- doc.go:GoDoc文件,定义了当前包的注释信息
- register.go:定义了资源组、资源版本及资源的注册信息
- type.go:定义了在当前资源组、资源版本下所支持的资源类型
- zz_generated.deepcopy.go:定义了资源的深复制操作,该文件由代码生成器自动生成
每一个Kubernetes资源目录,都通过register.go代码文件定义所属的资源组和资源版本,内部版本资源对象通过runtime.APIVersionInternal(即__internal)标识,代码示例如下:
代码路径:pkg\apis\apps\register.go
// 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: runtime.APIVersionInternal}
外部版本直接通过版本号标识,代码如下:
代码路径:pkg\apis\apps\v1\register.go
// 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"}
组下面的资源定义在pkg\apis\apps\types.go目录下。它的外部版本定义在pkg/apis/apps/{v1,v1beta1,v1beta2}目录下。
4.3、资源注册
资源是需要注册导注册表中的,其代码目录为pkg\apis\
func init() {
Install(legacyscheme.Scheme)
}
// Install registers the API group and adds types to a scheme
func Install(scheme *runtime.Scheme) {
utilruntime.Must(apps.AddToScheme(scheme))
utilruntime.Must(v1beta1.AddToScheme(scheme))
utilruntime.Must(v1beta2.AddToScheme(scheme))
utilruntime.Must(v1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1beta1.SchemeGroupVersion))
}
legacyscheme.Scheme是kube-apiserver组件的全局资源注册表,Kubernetes的所有资源信息都交给资源注册表统一管理。apps.AddToScheme是注册apps组下面的内部版本,{v1beta1,v1beta2,v1}.AddToScheme注册外部版本,scheme.SetVersionPriority设置版本优先级,最前面的优先级最高。优先级最高的版本就是首选版本,即在我们没有指定版本的时候就使用首选版本。
4.4、资源操作方法
在Kubernetes系统中,针对每一个资源都有一定的操作方法(即Verbs),例如,对于Pod资源对象,可以通过kubectl命令行工具对其执行create、delete、get等操作。Kubernetes系统所支持的操作方法目前有8种操作,分别是create、delete、deletecollection、get、list、patch、update、watch。这些操作方法可分为四大类,分别属于增、删、改、查,对资源进行创建、删除、更新和查询。
资源操作方法的数据结构定义在:staging\src\k8s.io\apimachinery\pkg\apis\meta\v1\types.go
// Verbs masks the value so protobuf can generate
//
// +protobuf.nullable=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
type Verbs []string
func (vs Verbs) String() string {
return fmt.Sprintf("%v", []string(vs))
}
操作方法的接口定义在:staging\src\k8s.io\apiserver\pkg\registry\rest\rest.go,资源对象以及操作接口对象说明如下:
操作方法 | 操作方法接口 | 说明 |
---|---|---|
create | rest.Creater | 创建接口 |
delete | rest.GracefulDeleter | 删除接口(单个资源) |
deletecollection | rest.CollectionDeleter | 删除接口(多个资源) |
update | rest.Updater | 更新接口(完整资源) |
patch | rest.Patcher | 补丁接口(局部资源) |
get | rest.Getter | 获取接口(单个资源) |
list | rest.Lister | 获取接口(多个资源) |
watch | rest.Watcher | 监听接口 |