声明式 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 包括:
说明:
对于此特性的 Beta 版,Kubernetes 故意使用一个被取代的 API 作为变更的试验场。 未来的 Kubernetes 版本可能会将此更改推广到更多 API。
DeclarativeValidation:(Beta, 默认值:
true`)当启用时, API 服务器对迁移的类型/字段同时运行新的声明式验证和旧的手写验证。结果在内部进行比较。DeclarativeValidationTakeover
:(Beta, 默认值:false
) 此开关决定哪个验证结果是权威的**(即返回给用户并用于准入决策)。
默认行为(Kubernetes 1.33):
- 当
DeclarativeValidation=true
和DeclarativeValidationTakeover=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 来进行。
有关管理特性门控的详细信息,请参阅特性门控。