Kubernetes 核心数据结构(1)

参考书籍:《Kubernetes源码剖析-郑旭东著》

K8s 是一个完全以资源为中心的系统

Group、Version、Resource 核心数据结构

​ Kuberetes 系统虽然有相当复杂和众多的 功能,但它本质 上是一个资源控制系统——注册、管理、调度资源 并维护资源的状态。

​ Kuberetes 将资源再次分组和版本化,形成 Group(资源组)、Version(资源版本)、Resource(资源)

  • Group: 被称为资源组,在Kubernetes API Server 中也可称其为 APIGroup。
  • Version: 被称为资源版本,在Kubernetes API Server 中也可称其为 APIVersions。
  • Resource: 被称为资源,在Kubernetes API Server 中也可称其为 APIResource。
  • Kind: 资源种类,描述 Resource 的种类,与 Resource 为同一级别。

image-20230410172134645

​ Kubernetes 系统支持多个Group,每个Group 支持多个Version,每个Version 支 持多个Resource,其中部分资源同时会拥有自己的子资源(即SubResource )。例如, Deployment资源拥有Status 子资源。 ​ 资源组、资源版本、资源、子资源的完整表现形式<group>/<version>/<resource>/ <subresource>。以常用的 Deployment 资源为例,其完整表现形式为apps/v1/deployments/status

​ 另外资源对象(Resource Object )在本书中也是 一个常用概念,由“ 资源组+ 资源版本+资源种类” 组成,并在实例化后表达一个资源对象,例如 Deployment 资源实例化后拥有资源组、资源版本及资源种类,其表现形式为<group>/<version>, Kind=<kind>,例如apps/v1, Kind=Deployment.

​ 每一个资源都拥有一定数量的资源操作方法(即 Verbs ),资源操作方法用于 Etcd 集群存储中对资源对象的增、删、改、查操作。目前 Kubemetes 系统支持8 种资源操作方法,分别是 create、delete、delete、collection、get、list、patch、update、watch 操作方法。

​ 每一个资源都至少有两个版本,分别是外部版本(External Version)和内部版本 ( Internal Version )。外部版本用于对外暴露给用户请求的接又所使用的资源对象。内部版本不对外暴露,仅在Kubernetes API Server 内部使用。

​ Kubernetes 资源也可分为两种, 分别是Kubernetes Resource (Kubermetes 内罝资源 ) 和 Custom Resource( 自 定 义 资 源 )。 开 发 者 通 过 C R D ( 即 Custom Resource Definitions )可实现自定义资源,它允许用户将自己定义的资源添加到 Kubernetes 系统中,并像使用 Kubernetes 内置资源 一样使用它们。

ResourceList

​ Kubernetes Group、 Version、Resource 等核心数据结构存放在staging/src/k8s.io/apimachinery/pkg/apis/meta/v1 目录中。它包含了Kubernetes 集群中所有组件使用的通 用核心数据结构,例如APIGroup、APIVersions、APIResource 等。其 中,我们可以 通过 APIResourceList 数据结构描述所有Group、Version、Resource 的结构。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
type APIResourceList struct {
	TypeMeta `json:",inline"`
	// groupVersion is the group and version this APIResourceList is for.
	GroupVersion string `json:"groupVersion"`
	// resources contains the name of the resources and if they are namespaced.
	APIResources []APIResource `json:"resources"`
}


type TypeMeta struct {
	Kind string `json:"kind,omitempty"`

	APIVersion string `json:"apiVersion,omitempty"`
}


type APIResource struct {
	// name is the plural name of the resource.
	Name string `json:"name"`
	// singularName is the singular name of the resource.  This allows clients to handle plural and singular opaquely.
	// The singularName is more correct for reporting status on a single item and both singular and plural are allowed
	// from the kubectl CLI interface.
	SingularName string `json:"singularName"`
	// namespaced indicates if a resource is namespaced or not.
	Namespaced bool `json:"namespaced"`
	// group is the preferred group of the resource.  Empty implies the group of the containing resource list.
	// For subresources, this may have a different value, for example: Scale".
	Group string `json:"group,omitempty"`
	// version is the preferred version of the resource.  Empty implies the version of the containing resource list
	// For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)".
	Version string `json:"version,omitempty"`
	// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
	Kind string `json:"kind"`
	// verbs is a list of supported kube verbs (this includes get, list, watch, create,
	// update, patch, delete, deletecollection, and proxy)
	Verbs Verbs `json:"verbs"`
	// shortNames is a list of suggested short names of the resource.
	ShortNames []string `json:"shortNames,omitempty"`
	// categories is a list of the grouped resources this resource belongs to (e.g. 'all')
	Categories []string `json:"categories,omitempty"`
	
	StorageVersionHash string `json:"storageVersionHash,omitempty"`

}

​ Kubernetes的每个资源可使用metav1.APIResource 结构进行描述,它描述资源的基本信息,例如资源名称 (即 Name 字段)、资源所属的命名空间(即 Namespaced 字段)、资源种类(即 Kind 字段)、资源可操作的方法列表(即 Verbs 字段)。

​ 每一个资源都属于一个或多个资源版本, 资源所属的版本通过 metavl.APIVersions 结构描述,一个或多个资源版本通过Versions []string 字符串数组进行存储。

image-20230411111820480

Group

​ Group ( 资源组),在Kubernetes API Server 中也可称其为 APIGroup。Kubernetes 系统中定义了许多资源组,这些资源组按照不同功能将资源进行了划分,资源组特点如下。

  • 将众多资源按照功能划分成不同的资源组,并允许单独启用/ 禁用资源组。 当然也可以单独启用/禁用资源组中的资源。
  • 支持不同资源组中拥有不同的资源版本。这方便组内的资源根据版本进行迭代升级。
  • 支持同名的资源种类 (即 Kind ) 存在于不同的资源组内 。
  • 资源组与资源版本通过 Kubernetes API Server 对外暴露,允许开发者通过 HTTP 协议进行交互并通过动态客户端( 即 DynamicClient )进行资源发现。
  • 支持CRD 自定 义资源扩展。
  • 用户交互简单,例如在使用kubectl 命令行工具时,可以不填写资源组名称
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type APIGroup struct {
	TypeMeta `json:",inline"`
	// name is the name of the group.
	Name string `json:"name"`
	// 资源组下所支持的资源版本.
	Versions []GroupVersionForDiscovery `json:"versions"`
	// 首选版本。 当一个资源组内存在多个资源版本时, Kubernetes API Server 在使用资源时会选择一 个首选版本作为当前版本
	PreferredVersion GroupVersionForDiscovery `json:"preferredVersion,omitempty"`
	// a map of client CIDR to server address that is serving this group.
	// This is to help clients reach servers in the most network-efficient way possible.
	// Clients can use the app ropriate server address as per the CIDR that they match.
	// In case of multiple matches, clients should use the longest matching CIDR.
	// The server returns only those CIDRs that it thinks that the client can match.
	// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
	// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
	ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs,omitempty"`
}

​ 在当前的Kubernetes 系统中,支持两类资源组,分别是拥有组名的资源组和没有组名的资源组。

  • 拥有组名的资源组: 其表现形式为<group>/<version>/<resource>,例如 apps/v1/deployments

  • 没有组名的资源组: 被称为 Core Groups ( 即核心资源组)或 Legacy Groups , 也可被称为 Group Less ( 即无组 )。 其表现形式为 /<version>/<resource> , 例 如 /v1/pods

    两类资源组表现形式不同, 形成的 HTTP PATH 路径也不同。 拥有组名的资源组的 HTTP PATH 以/apis 为前缀,其表现形式为/apis/<group>/<version>/<resource>,例如 http://localhost:8080/apis/apps/v1/deployments。没有组名的资源组的 HTTP PATH 以 api 为前缀,其表现形式为/api/<version>/<resource>,例如 http://localhost:8080/api/vl/pods.

Version

​ Kubernetes 的资源版本控制可分为了种,分别是 Alpha、Beta、Stable,它们之间的迭代顺序为Alpha -> Beta -> Stable,其通常用来表示软件测试过程中的 了个阶段。 Alpha是第1个阶段,一般用于内部测试; Beta 是第2 个阶段,该版本已经修复了大 部分不完善之处,但仍有可能存在缺陷和漏洞, 一般由特定的用户群来进行测试; Stable 是第了个阶段,此时基本形成了产品并达到了一定的成熟度,可稳定运行。 Kubernetes 资源版本控制详情如下:

  • Alpha 版本

​ Alpha 版本为内部测试版本,用于Kubernetes 开发者内部测试,该版本是不稳定的,可能存在很多缺陷和漏洞,官方随时可能会放弃支持该版本。在默认的情况下, 处于Alpha 版本的功能会被禁用。Alpha 版本名称一般为 vlalphal、vlalpha2、v2alphal 等。

  • Beta 版本

​ Beta 版本为相对稳定的版本, Beta 版本经过官方和社区很多次测试 , 当功能迭代时,该版本会有较小的改变,但不会被删除。在默认的情况下,处于Beta 版本的功能是开启状态的。Beta 版本命名一般为 v1betal、v1beta2、v2betal。

  • Stable 版本

​ Stable 版本为正式发布的版本, Stable 版本基本形成了产品 ,该版本不会被删除。 在默认的情况下 ,处于 stable 版本的功能全部处于开启状态 。Stable 版本命名一般为 v1、v2、 v3。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
type APIVersions struct {
	TypeMeta `json:",inline"`
	// 所支持的资源版本列表.
	Versions []string `json:"versions"`
	// a map of client CIDR to server address that is serving this group.
	// This is to help clients reach servers in the most network-efficient way possible.
	// Clients can use the appropriate server address as per the CIDR that they match.
	// In case of multiple matches, clients should use the longest matching CIDR.
	// The server returns only those CIDRs that it thinks that the client can match.
	// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
	// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
	ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs"`
}

CIDR(Classless Inter-Domain Routing)是一个用于给用户分配IP地址以及在互联网上有效地路由IP数据包的对IP地址进行归类的方法。与传统的A类、B类和C类寻址模式相比,CIDR在IP地址分配方面更为高效。CIDR采用斜线记法,表示为:IP地址/网络ID的位数。

  • 示例一:CIDR格式换算为IP地址网段

    例如10.0.0.0/8,换算为32位二进制地址:00001010.00000000.00000000.00000000。其中/8表示8位网络ID,即32位二进制地址中前8位是固定不变的,对应网段为:00001010.00000000.00000000.0000000000001010.11111111.11111111.11111111。则换算为十进制后,10.0.0.0/8表示:子网掩码为255.0.0.0,对应网段为10.0.0.010.255.255.255。

  • 示例二:IP地址网段换算为CIDR格式

    例如192.168.0.0192.168.31.255,后两段IP换算为二进制地址:00000000.0000000000011111.11111111,可以得出前19位(8*2+3)是固定不变的,则换算为CIDR格式后,表示为:192.168.0.0/19

Resource

​ 一 个资源被实例化后会表达为一 个资源对象(即Resource Object )。在 Kuberetes 系统中定义并运行着各式各样的资源对象,Kubernetes 资源对象如图所示。所有资源对象都是 Entity 。 Entity 翻译成中 文为 “ 实 体” ,Kubernetes 使用这些 Entity 来表示当前状态。可以通过 Kubernetes API Server 进行查询和更新每一个资源对象。 Kubernetes 目前支持两种 Entity,分别介绍如下

  • 持久性实体(Persistent Entity): 在资源对象被创建后,Kubernetes 会持久确保该资源对象存在。大部分资源对象属于持久性实体,例如 Deployment 资源对象

  • 短暂性实体(Ephemeral Entity): 也可称其为非持久性实体(Non-Persistent Entity ) 。 在资源对象被创建后,如果出现故障或调度失败 ,不会重新创建该资源对象,例如 Pod 资源对象

  • image-20230411115903185

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
type APIResource struct {
	// name is the plural name of the resource.
	Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
	// 资源的单数名称,它必须由小写字母组成,默认使用资源种类(Kind)的小写形式进行命名。例如,Pod 资源的单数名称为pod, 复数名称为pods
	SingularName string `json:"singularName"`
	// 资源是否拥有所属命名空间
  Namespaced bool `json:"namespaced"`
	// 资源所在的资源组名称
	Group string `json:"group,omitempty"`
	// 资源所在的资源版本
	Version string `json:"version,omitempty"`
	// 资源种类
  Kind string `json:"kind" `
	// 资源可操作的方法列表,例如get 、list、delete、create、update 等
  Verbs Verbs `json:"verbs"`
	// 资源的简称,例如 Pod 资源的简称为 po
  ShortNames []string `json:"shortNames,omitempty"`
  // 该资源所属的分组资源列表(例如“全部”)
	Categories []string `json:"categories,omitempty"`
	...	
}

资源外部版本与内部版本

​ Kubernetes 资源代码定义在 pkg/apis 目录下, 在详解资源代码定义之前, 先来了解一下资源的外部版本(ExternalVersion )与内部版本(Internal Version )。在 Kubernetes 系统中,同 一资源对应着两个版本,分别是外部版本和内部版本。例如,Deployment 资源,它所属的外部版本表现形式为apps/ v1,内部版本表现形式为apps/_internal'

  • ExternalObject: 外部版本资源对象,也称为 Versioned Object ( 即拥有资源版本的资源对象)。外部版本用于对外暴露给用户请求的接又所使用的资源对象,例如,用户在通过 YAML 或 JSON 格式的描述文件创建资源对象时,所使用的是外部版本的资源对象。外部版本的资源对象通过资源版本( Alpha 、Beta 、Stable )进行标识

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

    资源的外部版本代码定义在 pkg/apis/<group>/<version>/目录下,资源的内部版本代码定义在 pkg/apis/<group>/日 录 下。 例 如 , Deployment 资源 ,它的外部版本定义在 pkg/apis/apps/{v1,V1betal, v1beta2}/ 目录下, 它的内部版本定义在pkg/apis/apps/目录下(内部版本一般与资源组在同一级目录下)。资源的外部版本与内部版本如图所示。

image-20230411141133099

资源的外部版本和内部版本是需要相互转换的,而用于转换的函数需要事先初始化到资源注册表 (Scheme) 中 。 多个外部版本 ( External Version ) 之间的资源进行相互转换,都需要通过内部版本 (Internal Version )进行中转。这也是Kubernetes 能实现多资源版本转换的关键.

​ 资源的外部版本与内部版本的代码定义也不太一样,外部版本的资源需要对外暴露给用户请求的接又,所以资源代码定义了 JSONTags Proto Tags,用于请求的序列化和反序列化操作。内部版本的资源不对外暴露,所以没有任何的 JSON Tags 和ProtoTags定义。以Pod 资源代码定义为例,代码示例如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
 // staging/src/k8s.io/api/core/v1/types.go 外部使用

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
	// +optional
	metav1.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
	// +optional
	Spec 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
	// +optional
	Status PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// pkg/apis/core/types.go  内部使用

type Pod struct {
	metav1.TypeMeta
	// +optional
	metav1.ObjectMeta

	// Spec defines the behavior of a pod.
	// +optional
	Spec PodSpec

	// Status represents the current information about a pod. This data may not be up
	// to date.
	// +optional
	Status PodStatus
}

资源代码定义

​ Kubernetes资源代码定义在pkg/apis目录下,同一资源对应着内部版本和外部版本,内部版本和外部版本的资源代码结构并不相同

​ 资源的内部版本定义了所支持的资源类型 ( types.go)、资源验证方法( validation.go )、资源注册至资源注册表的方法 ( install/install.go) 等 。 而资源的外部版本定义了资源的转换方法 (conversion.go )、资源的默认值 (defaults.go) 等。

​ 以 Deployment 资源为例,它的内部版本定义在 pkg/apis/apps/目录下,其资源代码结构为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.
├── OWNERS
├── doc.go 
├── fuzzer
├── install
├── register.go
├── types.go
├── v1
├── v1beta1
├── v1beta2
├── validation
└── zz_generated.deepcopy.go
  • doc.go: GoDoc 文件,定义了当前包的注释信息。在 Kubernetes 资源包中, 它还担当了代码生成器的全局 Tags 描述文件
  • register. go : 定义了资源组、资源版本及资源的注册信息 。
  • types.go: 定义了在当前资源组、资源版本下所支持的资源类型。
  • v1、v1betal 、v1beta2 : 定义了资源组下拥有的资源版本的资源 (即外部版本)。
  • install : 把当前资源组下的所有资源注册到资源注册表中。
  • validation: 定义了资源的验证方法。
  • zz_generated.deepcopy-go: 定义了资源的深复制操作,该文件由代码生成器自动生成

​ 每一个 Kubernetes 资源目录,都通过 register.go 代码文件定义所属的资源组和资源版本,内部版本资源对象通过runtime.APIVersionInternal (即 _internal ) 标识 ,代码示例如下:

1
2
3
4
5
// pkg/apis/apps/types.go

type Deployment struct{ ... }
type DeploymentSpec struct {...}
...

​ 以 Deployment 资源为例,它的外部版本定义在 pkg/apis/apps/{vl,v1betal, v1beta2 } 目录下,其资源代码结构如下:

1
2
3
4
5
6
7
8
9
.
├── conversion.go
├── conversion_test.go
├── defaults.go
├── defaults_test.go
├── doc.go
├── register.go
├── zz_generated.conversion.go
└── zz_generated.defaults.go
  • conversion.go : 定义了资源的转换函数 (默认转换函数 ),并将默认转换函数注册到资源注册表中。
  • zz_generated.conversion.go: 定义了资源的转换西数(自动生成的转换函 数),并将生成的转换两数注册到资源注册表中。该文件由代码生成器自 动生成。
  • defaults.go: 定义了资源的默认值函 数 ,并将默认值函数注册到资源注册表中
  • zz_generated.defaults.go: 定义了资源的默认值函数(自动生成的默认值函数 ),并将生成的默认值两数注册到资源注册表中。该文件由代码生成器自动生成

​ 外部版本与内部版本资源类型相同,都通过 register.go代码文件定义所属的资源组和资源版本,外部版本资源对象通过资源版本( Alpha、Beta、Stable)标识,代码

示例如下

1
2
3
4
5
// 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"}

将资源注册到资源注册表中

​ 在每一个Kubernetes资源组目录中,都拥有一个instal/install.go 代码文件,它负责将资源信息注册到资源注册表(Scheme)中。以 core 核心资源组为例,代码示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// pkg/apis/core/install/install.go

func init() {
	Install(legacyscheme.Scheme)
}

// Install registers the API group and adds types to a scheme
func Install(scheme *runtime.Scheme) {
	utilruntime.Must(core.AddToScheme(scheme))
	utilruntime.Must(v1.AddToScheme(scheme))
	utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion))
}

legacyscheme.Schemekube-apiserver 组件的全局资源注册表,Kubernetes 的所有资源信息都交给资源注册表统一管理。core. AddToScheme函数注册core资源组内部版本的资源。v1.AddToScheme 函数注册 core 资源组外部版本的资源。 scheme.SetVersionPriority两数注册资源组的版本顺序,如有多个资源版本,排在最前面的为资源首选版本。

资源首选版本

​ 首选版本( Preferred Version ),也称优选版本( Priority Version),一个资源组下拥有多个资源版本,例如,apps资源组拥有v1、v1betal、v1beta2 等资源版本。当我们使用 apps 资源组下的Deployment 资源时,在一些场景下,如不指定资源版本,则使用该资源的首选版本。

​ 以apps 资源组为例,注册资源时会注册多个资源版本,分别是v1、v1beta2、 v1betal ,代码示例如下:

1
2
3
4
5
6
7
8
9
// pkg/apis/apps/install/install.go

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))
}

scheme.SetVersionPriority 注册版本顺序很重要,apps 资源组的注册版本顺序为 v1 、v1beta2 、v1betal ,那么在资源注册表的 version Priority 结构中 ,资源的首选版本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func (s *Scheme) SetVersionPriority(versions ...schema.GroupVersion) error {
	groups := sets.String{}
	order := []string{}
	for _, version := range versions {
		if len(version.Version) == 0 || version.Version == APIVersionInternal {
			return fmt.Errorf("internal versions cannot be prioritized: %v", version)
		}

		groups.Insert(version.Group)
		order = append(order, version.Version)
	}
	if len(groups) != 1 {
		return fmt.Errorf("must register versions for exactly one group: %v", strings.Join(groups.List(), ", "))
	}

	s.versionPriority[groups.List()[0]] = order
	return nil
}

资源操作方法

​ 在 Kubernetes 系统中 ,针对每一个资源都有一定的操作方法 ( 即 Verbs ),例如 ,对于 Pod 资源对象,可以通过kubectl 命令行工具对其执行 create、delete、get 等操 作。Kubernetes 系统所支持的操作方法目前有8 种操作,分别是 create、delete、 deletecollection、get、list、patch、update、watch。这些操作方法可分为四大类,分别属于增、删、改、查,对资源进行创建、删除、更新和查询。资源操作方法如图

image-20230411161222986

​ 资源操作方法可以通过metav1.Verbs 数据结构进行描述,代码示例如下:

1
2
3
4
5
type Verbs []string

func (vs Verbs) String() string {
	return fmt.Sprintf("%v", []string(vs))
}

​ 不同资源拥有不同的操作方法,例如,针对 Pod 资源对象与 pod logs 子资源对象,Pod 资源对象拥有create、delete、deletecollection、get、list、patch、update、watch 等操作方法,pod/logs 子资源对象只拥有get操作方法,因为日志只需要执行查看操作。Pod 资源对象与pod/ logs 子资源对象的操作方法分别通过 metav1. Verbs 进行描述。

​ 资源对象的操作方法与存储 (Storage )相关联,增、删、改、查实际上都是针对存储的操作。如何解 一个资源对象拥有哪些可操作的方法呢 ?

​ 需要查看与存储相关联的源码包 registry ,其定义在 vendor/k8s.io/apiserver/pkg/registry/ 目录下。 每种操作方法对应一个操作方法接又 (Interface),资源对象操作方法接口说明:

image-20230411162803191

资源与命名空间

​ Kubernetes 系统支持命名空间(Namespace),其用来解決Kubernetes 集群中资源对象过多导致管理复杂的问题 。 每个命名空间相当于一个 “ 虚 拟 集 群 ” ,不同命名空间之间可以进行隔离,当然也可以通过某种方式跨命名空间通信。

​ Kubernetes 系统中默认内置了4个命名空间 ,分别介绍如下。

  • default: 所有未指定命名空间的资源对象都会被分配给该命名空间

  • kube-system: 所有由 Kubernetes 系统创建的资源对象都会被分配给该命名空间

  • kube-public: 此命名空间下的资源对象可以被所有人访问 (包括未认证用户)

  • kube-node-lease: 此命名空间下存放来自节点的心跳记录(节点租约信息)

    通过运行 kubectl get namespace 命令查看 Kubernetes 系统上所有的命名空间信息 。另外,在Kubernetes 系统中,大部分资源对象都存在于某些命名空间中(例如Pod 资源对象)。但并不是所有的资源对象都存在于某个命名空间中(例如 Node 资源对象)。决定资源对象属于哪个命名空间,可通过资源对象的 ObjectMeta.Namespace描述

自定义资源

​ Kubenetes 系统拥有强大的高扩展功能 ,其中自定义资源 (CustomResource ) 就是一种常见的扩展方式,即可将自己定义的资源添加到 Kubemetes 系统中。Kubernetes 系统附带了许多内置资源,但是仍有些需求需要使用自定义资源来扩展 Kubernetes 的功能。

​ 开发者通过 CRD 可以实现自定义资源,它允许用户将自己定义的资源添加到 Kubernetes 系统中,并像使用 Kubernetes 内置资源一样使用 这些资源,例如,在 YAML/JSON 文件中带有 Spec 的资源定义都是对 Kubernetes 中的资源对象的定义,所有的自定义资源都可以与 Kubernetes 系统中的内置资源一样使用 kubectl 或 client- go 进行操作

资源对象描述文件定义

​ Kubernetes 资源可分为内置资源(Kubernetes Resources )和自定义资源(Custom Resources),它们都通过资源对象描述文件(Manifest File)进行定义,资源对象描述文件如图

image-20230411171215994

​ 一个资源对象需要用5 个字段来描述它分别是Group/Version、KindMetaData、 Spec、Status。这些字段定义在YAML或JSON 文件中。Kubernetes系统中的所有的 资源对象都可以采用YAML或JSON格式的描述文件来定义,下面是某个Pod 文件的资源对象描述文件 。 YAML Manifest File Example 代码示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • apiversion: 指定创建资源对象的资源组和资源版本, 其表现形式为 <group>/<version>, 若是core资源组 (即核心资源组 ) 下的资源对象 ,其表现形式为<version>
  • kind: 指定创建资源对象的种类
  • metadata: 描述创建资源对象的元数据信息,例如名称、命名空间等
  • spee: 包含有关Deployment 资源对象的核心信息,告诉Kubernetes 期望的资源状态、副本数量、环境变量、 卷等信息
  • status: 包含有关正在运行的 Deployment 资源对象的信息

​ 每一个Kubernetes 资源对象都包含两个嵌套字段,即 spec 字段和 status 字段。 其中spec 字段是必需的,它描述了资源对象的“期望状态”(DesiredState),而status 字段用于描述资源对象的“ 实际状态” (Actual State) ,它是由Kubernetes 系统提供 和更新的。在任何时刻,Kubernetes控制器一直努力地管理着对象的实际状态以与期望状态相匹配。