这篇文章发表已超过一年。较旧的文章可能包含过时内容。请检查页面信息自发布以来是否仍然准确。

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),我们现在已经解决了这两个问题。

服务器端字段验证 (Server Side Field Validation) 在向 apiserver 发送创建、更新和补丁请求时提供资源验证,该功能在 Kubernetes v1.25 中添加,v1.26 中进入 beta 阶段,并在 v1.27 中正式发布 (GA)。它提供了 kubectl validate 在服务器端的所有功能。

OpenAPI 是一种标准、与语言无关的接口,用于发现 Kubernetes 集群支持的操作和类型集合。OpenAPI V3 是 OpenAPI 的最新标准,是自 Kubernetes 1.5 以来一直支持的 OpenAPI V2 的改进版本。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 中被省略。一个可以表示多种类型的单一类型也可以使用 oneOf 字段在 OpenAPI V3 中正确表达。这包括 IntOrString 和 Quantity 的正确表示。

自定义资源定义 (Custom Resource Definitions)

在 Kubernetes 中,自定义资源定义使用结构化的 OpenAPI V3 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> 和代表遗留 group version 的 /openapi/v3/api/v1 进行访问。有关此端点的更多信息,请参阅Kubernetes API 文档

OpenAPI 的各种消费者已经更新以使用 v3,包括整个 kubectl 和服务器端应用。OpenAPI V3 的 Golang 客户端可在 client-go 中获取。

服务器端字段验证 (Server Side Field Validation)

查询参数 fieldValidation 可用于指示服务器应执行的字段验证级别。如果未传递此参数,则服务器端字段验证默认处于 Warn 模式。

  • Strict:严格字段验证,验证失败时报错
  • Warn:执行字段验证,但错误以警告形式暴露,而不是使请求失败
  • Ignore:不执行服务器端字段验证

kubectl 将跳过客户端验证,并自动在 Strict 模式下使用服务器端字段验证。控制器默认在 Warn 模式下使用服务器端字段验证。

在客户端验证时,由于 OpenAPI V2 中缺少某些字段,我们不得不格外宽松,以免拒绝可能有效的对象。这一切都在服务器端验证中得到了修复。更多文档可在此处找到。

下一步是什么?

随着服务器端字段验证和 OpenAPI V3 正式发布,我们引入了对 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