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 规范,以便启用命令行补全和其他功能。支持的两种机制如下所示:
Discovery API 提供有关 Kubernetes API 的信息:API 名称、资源、版本和支持的操作。这是一个 Kubernetes 特定术语,因为它与 Kubernetes OpenAPI 是一个独立的 API。其目的是对可用资源进行简要总结,不详细说明资源的具体模式。有关资源模式的参考信息,请参阅 OpenAPI 文档。
的Kubernetes OpenAPI 文档为所有 Kubernetes API 端点提供(完整的)OpenAPI v2.0 和 3.0 模式。OpenAPI v3 是访问 OpenAPI 的首选方法,因为它提供了更全面、更准确的 API 视图。它包括所有可用的 API 路径,以及每个端点上每个操作所消耗和产生的资源。它还包括集群支持的任何可扩展性组件。该数据是一个完整的规范,并且比 Discovery API 提供的数据大得多。
Discovery API
Kubernetes 通过 Discovery 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 版本 2 的限制,发布的 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 支持以 OpenAPI v3 形式发布其 API 的描述。
提供了一个发现端点 /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.33 发布 OpenAPI v2.0 和 v3.0;近期没有支持 3.1 的计划。
Protobuf 序列化
Kubernetes 实现了一种替代的基于 Protobuf 的序列化格式,主要用于集群内部通信。有关此格式的更多信息,请参阅 Kubernetes Protobuf 序列化设计提案以及定义 API 对象的 Go 包中每个模式的接口定义语言 (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
。如果你最初使用 v1beta1
版本的 API 创建了一个对象,那么以后可以使用 v1beta1
或 v1
API 版本读取、更新或删除该对象,直到 v1beta1
版本被废弃并移除。届时,你可以继续使用 v1
API 访问和修改该对象。
API 变更
任何成功的系统都需要随着新用例的出现或现有用例的变化而增长和变化。因此,Kubernetes 将 Kubernetes API 设计为持续变化和增长。Kubernetes 项目的目标是 不 破坏与现有客户端的兼容性,并保持这种兼容性一段时间,以便其他项目有机会进行调整。
通常,可以经常添加新的 API 资源和新的资源字段。删除资源或字段需要遵循 API 废弃策略。
一旦官方 Kubernetes API 达到通用可用性 (GA),通常在 API 版本 v1
,Kubernetes 会对其兼容性做出坚定承诺。此外,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。