组、版本和种类,真是让人头大!

在我们开始使用 API 之前,应该先聊聊一些术语。

在讨论 Kubernetes 中的 API 时,我们经常使用四个术语:版本种类_和_资源

组和版本

Kubernetes 中的 API 组 只是相关功能的集合。每个组都有一个或多个 版本,顾名思义,这些版本允许我们随着时间的推移改变 API 的工作方式。

种类和资源

每个 API 组版本包含一个或多个 API 类型,我们称之为 Kinds。虽然一个 Kind 可能在不同版本之间改变形式,但每种形式必须能够以某种方式存储其他形式的所有数据(我们可以将数据存储在字段中或注释中)。这意味着使用旧的 API 版本不会导致较新的数据丢失或损坏。有关更多信息,请参阅 Kubernetes API 指南

您有时还会听到提到 资源。资源只是 API 中对 Kind 的一种使用。通常,Kinds 和资源之间存在一对一的映射关系。例如,pods 资源对应于 Pod Kind。然而,有时候,同一个 Kind 可能会由多个资源返回。例如,Scale Kind 会由所有缩放子资源返回,如 deployments/scalereplicasets/scale。这使得 Kubernetes 的 HorizontalPodAutoscaler 能够与不同的资源进行交互。然而,对于自定义资源定义(CRDs)而言,每个 Kind 将对应一个单一的资源。

请注意,资源始终使用小写字母,并且根据惯例,它们是 Kind 的小写形式。

那么,这与围棋有什么关系呢?

当我们在特定组版本中提到一种类型时,我们将其称为 GroupVersionKind,简称 GVK。资源同样适用 GVR。正如我们稍后将看到的,每个 GVK 对应于一个包中的特定根 Go 类型。

现在我们把术语理顺了,可以_真正_创建我们的 API 了!

那么,我们该如何创建我们的 API 呢?

在下一部分添加新的 API中,我们将检查该工具如何通过命令 kubebuilder create api 帮助我们创建自己的 API。

此命令的目标是为我们的类型创建一个自定义资源(CR)和自定义资源定义(CRD)。要进一步了解,请参见:使用自定义资源定义扩展Kubernetes API

但是,为什么要创建API呢?

新的 API 是我们向 Kubernetes 教授自定义对象的方式。Go 结构体用于生成 CRD,包含我们数据的架构以及跟踪诸如新类型名称等数据。然后,我们可以创建自定义对象的实例,这些实例将由我们的 控制器 进行管理。

我们的 API 和资源代表了我们在集群上的解决方案。基本上,CRD(自定义资源定义)是我们自定义对象的定义,而 CR(自定义资源)是其实例。

啊,你有例子吗?

让我们想一想经典场景,目标是在平台上运行应用程序及其数据库,使用 Kubernetes。在这个场景中,一个 CRD 可以表示应用程序,而另一个 CRD 可以表示数据库。通过为应用程序创建一个 CRD,并为数据库创建另一个 CRD,我们不会损害诸如封装、单一职责原则和内聚性等概念。损害这些概念可能会导致意想不到的副作用,例如在扩展、重用或维护方面遇到困难,仅举几例。

通过这种方式,我们可以创建应用程序的 CRD,它将拥有自己的控制器,负责诸如创建包含应用程序的 Deployment、创建访问该应用程序的 Service 等。类似地,我们可以创建一个 CRD 来表示数据库,并部署一个控制器来管理数据库实例。

呃,但那个Scheme是什么东西?

我们之前看到的 Scheme 只是一个用来跟踪给定 GVK 对应的 Go 类型的方式(不要被它的 godocs 压倒)。

例如,假设我们将 "tutorial.kubebuilder.io/api/v1".CronJob{} 类型标记为属于 batch.tutorial.kubebuilder.io/v1 API 组(隐含地表示它的 Kind 为 CronJob)。

然后,我们可以根据API服务器提供的JSON数据,稍后构建一个新的 &CronJob{}

{
    "kind": "CronJob",
    "apiVersion": "batch.tutorial.kubebuilder.io/v1",
    ...
}

或者在我们提交一个 &CronJob{} 的更新时,正确查找组版本。