3. k8sAPI设计规范
Kubernetes API 是集群系统中的重要组成部分,Kubernetes 中各种资源(对象)的数据通过该 API 被传送到后端的持久化存储(ETCD)中。Kubernetes 集群中的各部件之间通过该 API实现解耦合,KubernetesAPI中的资源对象都拥有通用的元数据,资源对象也可能存在嵌套现象,比如在一个 Pod中嵌套多个 Container。创建一个API 对象是指通过 API 调用创建一条有意义的记录,该记录一旦被创建,Kubernetes 将确保对应的资源对象会被自动创建并托管维护。在Kubernetes系统中,大多数情况下, API定义和实现都符合标准的 HTTPREST格式,如通过标准的 HTTP动作(POST、PUT、GET、DELETE)来完成对相关资源对象的查询、修改、删除等操作。但同时Kubernetes也为某些非标准的REST行为提供了附加的 API,例如,监听某个资源变化的 Watch接口等。另外,某些 API可能违背严格的REST模式,因为接口不是返回单一的 JSON对象,而是返回其他类型的数据,如 JSON对象流(Stream)或非结构化的文本日志数据等。 从上面的 CRD定义中可以发现,在 Kubernetes中要想完成一个 CRD,需要指定 Group、Version和 Kind,这在 Kubernetes的 APIServer中简称为 GVK。当我们在 Kubernetes中谈论API时,经常会提起 4个术语:Groups、Versions、Kinds和 Resources。
(1) Groups/Versions
Kubernetes中的 API 组简单来说就是相关功能的集合。每个组都有一个或多个版本,它允许我们随着时间的推移改变 API的职责。
(2) Kinds/Resources
每个 API组 - 版本包含一个或多个API类型,我们称之为 Kinds。虽然一个Kind可以在不同版本之间改变表单内容,但每个表单必须能够以某种方式存储其他表单的所有数据(我们可以将数据存储在字段或者注释中)。 这意味着,使用旧的API版本不会导致新的数据丢失或损坏。
Resources只是 API中的一个 Kind 的使用方式。通常情况下,Kind和 Resources之间是一对一的映射。 例如,Pods资源对应于 Pod 种类。但是有时同一类型可能由多个资源返回。例如,ScaleKind是由所有 Scale子资源返回的,它由 Deployments/Scale或Replicasets/Scale组成。这就是允许 KubernetesHPA(HorizontalPodAutoscaler)与不同资源交互的原因。然而,使用 CRD每个 Kind 都将对应一个 Resource。
GVK 是定义一种类型的方式。例如,Daemonsets就是 Kubernetes中的一种资源,当我们要求 Kubernetes创建一个 Daemonsets的时候,Kubectl是如何知道该怎么向APIServer发送这个信息呢?是所有的不同资源都发向同一个URL,还是每种资源都是不同的?例如Daemonsets资源内容(见代码清单2-5)。
apiVersion:apps/v1kind:DaemonSetmetadata:
name:node-exporter
这里声明了 apiVersion是 apps/v1,其实就是隐含了 Group是 apps,Version是v1,Kind就是定义的 DaemonSet,而 Kubectl 接收到这个声明之后,就可以根据这个声明去调用 APIServer对应的 URL来获取信息。例如,/api/apps/v1/daemonset这样的 API 就是由上面的设计规则实现的。Kubernetes 以符合 REST规范的 URI来组织资源。
前面介绍了 GVK(Group、Version、Kind),接下来介绍APIServer的第二个概念GVR(Group、Version、Resource)。其实理解了GVK 之后再理解GVR 就很容易了,这就是面向对象编程中的类和对象的概念是一样的。Kind 相当于一个类,Resource是具体的 Kind,可以理解为一个类的对象资源。那么 GVR资源如何对应到GVK?这就是RESTMapping 的功能:RESTMapping 可以将指定的一个GVR(如 Daemonset资源)通过转换映射返回对应的GVK 以及支持的操作等。
(3) API版本
为了在兼容旧版本的同时不断升级 API,Kubernetes提供了多版本 API 的支持能力,每个版本的API通过一个版本号路径前缀加以区分,例如 /api/v1beta3。通常情况下,新旧几个不同的 API版本都能涵盖所有的 Kubernetes资源对象,在不同的版本之间这些 API存在一些细微差别。Kubernetes开发团队基于 API级别选择版本而不是基于资源和域级别来选择版本,是为了确保API能够描述一个清晰、连续的系统资源和行为的视图,能够控制访问的整个过程和实验性API的访问 。
API 详细说明如下。
① GET/<资源名的复数格式>:获得某一类型的资源列表,例如GET/Pods返回一个 Pod资源列表。
② POST/<资源名的复数格式>:创建一个资源,该资源来自用户提供的JSON 对象。
③ GET/<资源名复数格式 >/<名字 >:通过给出的名称(Name)获得单个资源,例如 GET /pods/podname返回一个名称为“podname”的 Pod。
④ DELETE/< 资源名复数格式 >/< 名字 >:通过给出的名字删除单个资源。删除选项(DeleteOptions)中可以指定的优雅删除(GraceDeletion)的时间(GracePeriodSeconds),该可选项表明了从服务端接收删除请求到资源被删除的时间间隔(单位为s)。不同的类别(Kind)可能为优雅删除时间(Grace Period)申明默认值。用户提交的优雅删除时间将覆盖该默认值,包括值为0 的优雅删除时间。
⑤ PUT/<资源名复数格式 >/<名字>:通过给出的资源名和客户端提供的 JSON对象来更新或创建资源。
⑥ PATCH/<资源名复数格式 >/<名字>:选择修改资源详细指定的域。此外,KubernetesAPI 添加了资源变动的“观察者”模式的API。
① GET/watch/<资源名复数格式>:随时间变化,不断接收一连串的JSON对象,这些JSON 对象记录了给定资源类别内所有资源对象的变化情况。
② GET/watch/<资源名复数格式 >/:随时间变化,不断接收一连串的JSON对象,这些JSON 对象记录了某个给定资源对象的变化情况。