本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.27:服务器端字段验证和 OpenAPI V3 进入 GA 阶段
在 Kubernetes v1.8 之前 (!),YAML 文件中的拼写错误、缩进错误或微小错误都可能导致灾难性后果(例如,像在 `replica: 1000` 中忘记结尾的 s 这样的拼写错误可能会导致服务中断,因为该值会被忽略和缺失,从而强制将副本数重置回 1)。这个问题在当时是通过在 kubectl 中获取 OpenAPI v2 并用它来验证字段在应用前是否正确和存在来解决的。不幸的是,那时 Custom Resource Definitions 还不存在,代码是在这个假设下编写的。当后来引入 CRD 时,校验代码的灵活性不足迫使我们在 CRD 暴露其 Schema 的方式上做出一些艰难的决定,使我们陷入了校验不佳导致 OpenAPI 不佳,反之亦然的恶性循环。随着新的 OpenAPI v3 和服务器端字段校验在 1.27 中进入 GA 阶段,我们现在已经解决了这两个问题。
服务器端字段校验为对 apiserver 的创建、更新和补丁请求提供了资源校验功能,该功能在 Kubernetes v1.25 中被添加,v1.26 中进入 Beta 阶段,现在在 v1.27 中已进入 GA 阶段。它在服务器端提供了 kubectl validate 的所有功能。
OpenAPI 是一种标准的、与语言无关的接口,用于发现 Kubernetes 集群支持的操作和类型集。OpenAPI V3 是 OpenAPI 的最新标准,是对 OpenAPI V2 的改进,后者自 Kubernetes 1.5 起就得到支持。Kubernetes 在 v1.23 中添加了对 OpenAPI V3 的支持,在 v1.24 中进入 Beta 阶段,现在在 v1.27 中已进入 GA 阶段。
OpenAPI V3
OpenAPI V3 相较于 V2 提供了什么
内置类型
Kubernetes 为字段提供了一些在 OpenAPI V2 中无法表示的注解,或者有时在 Kubernetes 生成的 OpenAPI v2 中没有表示。最值得注意的是,“default” 字段在 OpenAPI V3 中发布,而在 OpenAPI V2 中被省略了。可以表示多种类型的单一类型在 OpenAPI V3 中也通过 oneOf 字段得到了正确表达。这包括对 IntOrString 和 Quantity 的正确表示。
自定义资源定义(Custom Resource Definitions)
在 Kubernetes 中,自定义资源定义使用一种结构化的 OpenAPI V3 Schema,这种 Schema 无法在不丢失某些字段的情况下表示为 OpenAPI V2。其中一些字段包括 nullable、default、anyOf、oneOf、not 等。OpenAPI V3 是 CustomResourceDefinition 结构化 Schema 的完全无损表示。
我该如何使用它?
OpenAPI V3 的根发现端点位于 Kubernetes API 服务器的 `/openapi/v3` 端点。OpenAPI V3 文档按组版本(group-version)进行分组,以减少传输的数据量,各个文档可以通过 `/openapi/v3/apis/<group>/<version>` 和 `/openapi/v3/api/v1`(代表遗留的组版本)访问。请参阅 Kubernetes API 文档 以获取有关此端点的更多信息。
OpenAPI 的各种消费者已经被更新以使用 V3,包括整个 kubectl 和服务器端应用(Server Side Apply)。在 client-go 中提供了一个 OpenAPI V3 的 Golang 客户端。
服务器端字段校验
查询参数 `fieldValidation` 可用于指示服务器应执行的字段校验级别。如果未传递该参数,服务器端字段校验默认为 `Warn` 模式。
- Strict:严格的字段校验,校验失败时会报错
- Warn:执行字段校验,但错误会作为警告暴露,而不会导致请求失败
- Ignore:不执行服务器端字段校验
kubectl 将跳过客户端校验,并自动使用 `Strict` 模式的服务器端字段校验。控制器默认使用 `Warn` 模式的服务器端字段校验。
对于客户端校验,我们必须格外宽容,因为 OpenAPI V2 中缺少某些字段,我们不希望拒绝可能有效的对象。这一切在服务器端校验中都得到了修复。更多文档可以在这里找到。
接下来是什么?
随着服务器端字段校验和 OpenAPI V3 作为 GA 发布,我们引入了更准确的 Kubernetes 资源表示。建议使用服务器端字段校验而不是客户端校验,但有了 OpenAPI V3,客户端如果需要,可以自由实现自己的校验(以“左移”),我们保证通过 OpenAPI 发布一个完全无损的 Schema。
一些现有的工作将进一步改进通过 OpenAPI 提供的信息,包括 CEL 校验和准入,以及内置类型上的 OpenAPI 注解。
利用 OpenAPI V3 中找到的类型信息,可以构建许多其他用于编写和转换资源的工具。
如何参与?
这两个功能由 SIG API Machinery 社区推动,你可以在 Slack 频道 #sig-api-machinery、通过邮件列表找到我们,我们每隔一个周三上午 11:00(太平洋时间)在 Zoom 上开会。
我们衷心感谢所有帮助设计、实现和审查这两个功能的贡献者。
- Alexander Zielenski
- Antoine Pelisse
- Daniel Smith
- David Eads
- Jeffrey Ying
- Jordan Liggitt
- Kevin Delgado
- Sean Sullivan