声明式 API 验证

特性状态: Kubernetes v1.33 [beta]

Kubernetes 1.33 包含 API 的可选的声明式验证。启用后,Kubernetes API 服务器可以使用此机制,而不是依赖手工编写 Go 代码(`validation.go` 文件)来确保对 API 的请求是有效的遗留方法。Kubernetes 开发者以及扩展 Kubernetes API 的人可以根据 API 类型定义 (`types.go` 文件) 直接定义验证规则。代码作者定义特殊的注释标签(例如,`+k8s:minimum=0`)。然后代码生成器(`validation-gen`)使用这些标签生成用于 API 验证的优化 Go 代码。

虽然主要影响 Kubernetes 贡献者和潜在的扩展 API 服务器的开发者,但集群管理员应该了解其行为,尤其是在其推广阶段。

声明式验证正在逐步推出。在 Kubernetes 1.33 中,使用声明式验证的 API 包括

  • DeclarativeValidation:(Beta,默认:`true`)启用后,API 服务器会为迁移的类型/字段同时运行新的声明式验证和旧的手工编写验证。内部会对结果进行比较。
  • DeclarativeValidationTakeover:(Beta,默认:`false`)此门控确定哪个验证结果具有权威性(即,返回给用户并用于准入决策)。

默认行为 (Kubernetes 1.33)

  • 当 `DeclarativeValidation=true` 和 `DeclarativeValidationTakeover=false`(门控的默认值)时,两个验证系统都会运行。
  • 将使用手工编写的验证结果。 声明式验证在不匹配模式下运行以进行比较。
  • API 服务器会记录两个验证系统之间的不匹配,并增加 `declarative_validation_mismatch_total` 度量。这有助于开发者在 Beta 阶段识别和修复差异。
  • 关于此功能,集群升级应该是安全的,因为默认情况下权威的验证逻辑不会改变。

管理员可以选择明确启用 `DeclarativeValidationTakeover=true`,使声明式验证对已迁移的字段具有权威性,通常是在验证其环境中的稳定性后(例如,通过监控不匹配度量)。

禁用声明式验证

作为集群管理员,在特定情况下,你可能考虑在声明式验证仍处于 Beta 阶段时将其禁用

  • 意外的验证行为: 如果启用 `DeclarativeValidationTakeover` 导致意外的验证错误或允许之前无效的对象。
  • 性能下降: 如果监控显示显著的延迟增加(例如,在 `apiserver_request_duration_seconds` 中)与该功能的启用相关。
  • 高不匹配率: 如果 `declarative_validation_mismatch_total` 度量显示频繁的不匹配,即使 `DeclarativeValidationTakeover` 为 false,也表明影响集群工作负载的声明式规则可能存在 Bug。

要恢复到仅使用手工编写的验证(如 Kubernetes v1.33 之前所用),请禁用 `DeclarativeValidation` 特性门控,例如通过命令行参数:(`--feature-gates=DeclarativeValidation=false`)。这也会隐含地禁用 `DeclarativeValidationTakeover` 的效果。

降级和回滚的考量

禁用此功能是一种安全机制。但是,请注意一个潜在的边缘情况(由于进行了广泛测试,这种情况被认为是不可能的):如果声明式验证中的一个 Bug(当 `DeclarativeValidationTakeover=true` 时)错误地允许无效对象被持久化,那么禁用特性门控可能会导致后续对该特定对象的更新被现在具有权威性(且正确)的手工编写验证阻止。解决此问题可能需要手动更正存储的对象,在极少数情况下可能需要直接修改 etcd。

有关管理特性门控的详细信息,请参阅特性门控