声明式 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=trueDeclarativeValidationTakeover=false (开关的默认值),两种验证系统都会运行。
  • **使用手写验证的结果。**声明式验证以不匹配模式运行进行比较。
  • 两种验证系统之间的不匹配将由 API 服务器记录,并增加 declarative_validation_mismatch_total 指标。这有助于开发人员在 Beta 阶段识别并修复不一致之处。
  • 关于此特性的集群升级应该是安全的,默认情况下权威的验证逻辑不会改变。

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

禁用声明式验证

作为集群管理员,在特定情况下,你可能会考虑在声明式验证仍然是测试版时禁用它:

  • 意外的验证行为: 如果启用 DeclarativeValidationTakeover 导致了未预期的验证错误或允许之前无效的对象。
  • 性能回归: 如果监控显示显著的延迟增加(例如,在 apiserver_request_duration_seconds 中), 且与该特性的启用相关联。
  • 不匹配率高: 如果 declarative_validation_mismatch_total 指标显示出频繁的不匹配,这暗示声明式规则中可能存在影响集群工作负载的潜在错误, 即使 DeclarativeValidationTakeover 为 false。

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

降级和回滚的考虑事项

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

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

最后修改 April 24, 2025 at 10:29 AM PST: [zh-cn]sync declarative-validation.md (454ccaca6e)