Kubernetes API
Kubernetes 控制平面的核心是 API 服务器。API 服务器公开了一个 HTTP API,允许终端用户、集群的不同部分和外部组件相互通信。
Kubernetes API 允许你查询和操作 Kubernetes 中 API 对象的状态(例如:Pod、Namespace、ConfigMap 和 Event)。
大多数操作都可以通过 kubectl 命令行界面或其他命令行工具(例如 kubeadm)执行,这些工具反过来又使用 API。但是,你也可以使用 REST 调用直接访问 API。Kubernetes 为希望使用 Kubernetes API 编写应用程序的用户提供了一组客户端库。
每个 Kubernetes 集群都会发布集群提供的 API 规范。Kubernetes 使用两种机制来发布这些 API 规范;这两种机制都用于实现自动互操作性。例如,`kubectl` 工具会获取并缓存 API 规范,以启用命令行补全和其他功能。这两种受支持的机制如下:
发现 API 提供有关 Kubernetes API 的信息:API 名称、资源、版本和支持的操作。这是一个 Kubernetes 特有的术语,因为它是一个独立于 Kubernetes OpenAPI 的 API。它的目的是简要概述可用资源,并且不详细说明资源的特定模式。有关资源模式的参考,请参阅 OpenAPI 文档。
Kubernetes OpenAPI 文档 为所有 Kubernetes API 端点提供(完整的)OpenAPI v2.0 和 3.0 模式。OpenAPI v3 是访问 OpenAPI 的首选方法,因为它提供了更全面、更准确的 API 视图。它包括所有可用的 API 路径,以及每个端点上每个操作所使用的和生成的资源。它还包括集群支持的任何可扩展性组件。该数据是一个完整的规范,并且比发现 API 的数据大得多。
发现 API
Kubernetes 通过发现 API 发布所有组版本和支持的资源列表。这包括每个资源的以下内容:
- 名称
- 集群或命名空间范围
- 端点 URL 和支持的动词
- 替代名称
- 组、版本、种类
API 以聚合和非聚合形式提供。聚合发现提供两个端点,而非聚合发现为每个组版本提供一个单独的端点。
聚合发现
Kubernetes v1.30 [stable]
(默认启用:true)Kubernetes 为**聚合发现**提供稳定支持,通过两个端点(`/api` 和 `/apis`)发布集群支持的所有资源。请求此端点可大大减少获取集群发现数据所发送的请求数量。你可以通过使用 `Accept` 头(指示聚合发现资源:`Accept: application/json;v=v2;g=apidiscovery.k8s.io;as=APIGroupDiscoveryList`)请求相应的端点来访问数据。
如果不使用 `Accept` 头指示资源类型,则 `/api` 和 `/apis` 端点的默认响应是非聚合发现文档。
内置资源的发现文档可在 Kubernetes GitHub 仓库中找到。如果 Kubernetes 集群不可用以查询,则此 Github 文档可用作可用资源基本集的参考。
此端点还支持 ETag 和 protobuf 编码。
非聚合发现
在没有发现聚合的情况下,发现以分层方式发布,根端点发布下游文档的发现信息。
集群支持的所有组版本列表在 `/api` 和 `/apis` 端点发布。例如:
{
"kind": "APIGroupList",
"apiVersion": "v1",
"groups": [
{
"name": "apiregistration.k8s.io",
"versions": [
{
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
},
{
"name": "apps",
"versions": [
{
"groupVersion": "apps/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apps/v1",
"version": "v1"
}
},
...
}
需要额外的请求才能在 `/apis/<group>/<version>`(例如:`/apis/rbac.authorization.k8s.io/v1alpha1`)获取每个组版本的发现文档,该文档通告特定组版本下提供的资源列表。这些端点由 kubectl 用于获取集群支持的资源列表。
OpenAPI 接口定义
有关 OpenAPI 规范的详细信息,请参阅OpenAPI 文档。
Kubernetes 提供 OpenAPI v2.0 和 OpenAPI v3.0。OpenAPI v3 是访问 OpenAPI 的首选方法,因为它提供了 Kubernetes 资源的更全面(无损)表示。由于 OpenAPI v2 的限制,某些字段已从发布的 OpenAPI 中删除,包括但不限于 `default`、`nullable`、`oneOf`。
OpenAPI V2
Kubernetes API 服务器通过 `/openapi/v2` 端点提供聚合的 OpenAPI v2 规范。你可以使用请求头请求响应格式,如下所示:
头 | 可能的值 | 备注 |
---|---|---|
Accept-Encoding | gzip | 不提供此头也是可以的 |
Accept | application/com.github.proto-openapi.spec.v2@v1.0+protobuf | 主要用于集群内部使用 |
application/json | 默认 | |
* | 提供 `application/json` |
警告
作为 OpenAPI 模式一部分发布的验证规则可能不完整,通常也是如此。API 服务器内部会进行额外的验证。如果你需要精确和完整的验证,`kubectl apply --dry-run=server` 会运行所有适用的验证(并激活准入时检查)。OpenAPI V3
Kubernetes v1.27 [stable]
(默认启用:true)Kubernetes 支持将其 API 描述发布为 OpenAPI v3。
提供了一个发现端点 `/openapi/v3`,用于查看所有可用组/版本列表。此端点仅返回 JSON。这些组/版本以以下格式提供:
{
"paths": {
...,
"api/v1": {
"serverRelativeURL": "/openapi/v3/api/v1?hash=CC0E9BFD992D8C59AEC98A1E2336F899E8318D3CF4C68944C3DEC640AF5AB52D864AC50DAA8D145B3494F75FA3CFF939FCBDDA431DAD3CA79738B297795818CF"
},
"apis/admissionregistration.k8s.io/v1": {
"serverRelativeURL": "/openapi/v3/apis/admissionregistration.k8s.io/v1?hash=E19CC93A116982CE5422FC42B590A8AFAD92CDE9AE4D59B5CAAD568F083AD07946E6CB5817531680BCE6E215C16973CD39003B0425F3477CFD854E89A9DB6597"
},
....
}
}
相对 URL 指向不可变的 OpenAPI 描述,以改善客户端缓存。API 服务器也为此目的设置了适当的 HTTP 缓存头(`Expires` 设置为未来 1 年,`Cache-Control` 设置为 `immutable`)。当使用过时的 URL 时,API 服务器会返回重定向到最新的 URL。
Kubernetes API 服务器在 `/openapi/v3/apis/<group>/<version>?hash=<hash>` 端点发布每个 Kubernetes 组版本的 OpenAPI v3 规范。
请参阅下表以了解接受的请求头。
头 | 可能的值 | 备注 |
---|---|---|
Accept-Encoding | gzip | 不提供此头也是可以的 |
Accept | application/com.github.proto-openapi.spec.v3@v1.0+protobuf | 主要用于集群内部使用 |
application/json | 默认 | |
* | 提供 `application/json` |
在 `k8s.io/client-go/openapi3` 包中提供了获取 OpenAPI V3 的 Golang 实现。
Kubernetes 1.34 发布 OpenAPI v2.0 和 v3.0;目前没有在不久的将来支持 3.1 的计划。
Protobuf 序列化
Kubernetes 实现了一种基于 Protobuf 的替代序列化格式,主要用于集群内部通信。有关此格式的更多信息,请参阅 Kubernetes Protobuf 序列化设计提案以及 Go 包中定义 API 对象的每个模式的接口定义语言 (IDL) 文件。
持久性
Kubernetes 通过将对象的序列化状态写入 etcd 来存储。
API 组和版本控制
为了更容易地消除字段或重构资源表示,Kubernetes 支持多个 API 版本,每个版本都在不同的 API 路径下,例如 `api/v1` 或 `/apis/rbac.authorization.k8s.io/v1alpha1`。
版本控制是在 API 级别而非资源或字段级别完成的,以确保 API 提供清晰、一致的系统资源和行为视图,并能够控制对生命周期结束和/或实验性 API 的访问。
为了更容易地发展和扩展其 API,Kubernetes 实现了可以启用或禁用的API 组。
API 资源通过其 API 组、资源类型、命名空间(对于命名空间资源)和名称来区分。API 服务器透明地处理 API 版本之间的转换:所有不同的版本实际上是相同持久化数据的表示。API 服务器可以通过多个 API 版本提供相同的底层数据。
例如,假设同一资源有两个 API 版本:`v1` 和 `v1beta1`。如果你最初使用 API 的 `v1beta1` 版本创建了一个对象,那么你可以在 `v1beta1` 版本被弃用和移除之前,使用 `v1beta1` 或 `v1` API 版本来读取、更新或删除该对象。届时,你可以继续使用 `v1` API 访问和修改该对象。
API 变更
任何成功的系统都需要随着新用例的出现或现有用例的变化而发展和改变。因此,Kubernetes 设计的 Kubernetes API 将不断变化和发展。Kubernetes 项目的目标是**不**破坏与现有客户端的兼容性,并长时间保持这种兼容性,以便其他项目有机会适应。
一般来说,新的 API 资源和新的资源字段可以经常添加。资源的消除或字段的消除需要遵循API 弃用策略。
Kubernetes 强烈承诺,一旦官方 Kubernetes API 达到普遍可用(GA)(通常是 API 版本 `v1`),就会保持其兼容性。此外,Kubernetes 维护与通过官方 Kubernetes API 的*Beta* API 版本持久化的数据兼容性,并确保当功能稳定时,数据可以通过 GA API 版本进行转换和访问。
如果你采用 Beta API 版本,一旦 API 升级,你需要转换为后续的 Beta 或稳定 API 版本。最佳时间是在 Beta API 处于其弃用期时进行,因为对象可以通过两个 API 版本同时访问。一旦 Beta API 完成其弃用期并且不再提供,则必须使用替代 API 版本。
注意
尽管 Kubernetes 也旨在保持 *Alpha* API 版本的兼容性,但在某些情况下这可能无法实现。如果你使用任何 Alpha API 版本,请在升级集群时检查 Kubernetes 的发行说明,以防 API 以不兼容的方式发生变化,这需要你在升级前删除所有现有的 Alpha 对象。有关 API 版本级别定义的更多详细信息,请参阅API 版本参考。
API 扩展
Kubernetes API 可以通过以下两种方式之一进行扩展:
下一步
- 通过添加你自己的CustomResourceDefinition来了解如何扩展 Kubernetes API。
- 控制对 Kubernetes API 的访问描述了集群如何管理 API 访问的身份验证和授权。
- 通过阅读API 参考了解 API 端点、资源类型和示例。
- 从API 变更中了解什么是兼容性变更以及如何更改 API。