This is a stable feature in Kubernetes, and has been since version v1.36. It was first available in the v1.33 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate DeclarativeValidation, Kubernetes ignores it but does not report any error.
Kubernetes 1.37 对越来越多的 API 使用声明式验证(declarative validation)。
API 作者不再编写手写的 Go 代码(validation.go),
而是在类型定义(types.go)上以注释标签的形式声明验证规则,例如 +k8s:minimum=0。
代码生成器 validation-gen 会将这些标签转换为验证代码。
这主要影响 Kubernetes 贡献者和扩展 API 服务器的作者, 但在现有手写验证的迁移期间,集群管理员也应了解其行为。
对于新增的 API 字段,直接使用标签即可,例如 +k8s:minimum=1。这类标签始终生效。
迁移现有的手写验证风险更高,因为生成的代码必须与其所替代的代码行为完全一致。
此类迁移会将标签包装在生命周期前缀(lifecycle prefix,即 +k8s:alpha 或 +k8s:beta)中,
由前缀控制声明式验证的结果是否具有权威性。
| 标签形式 | 行为 |
|---|---|
+k8s:minimum=1(无前缀) | 生效。声明式验证的结果具有权威性。 |
+k8s:beta(since:"1.37")=+k8s:minimum=1 | 在 DeclarativeValidationBeta 特性门控启用时(默认)生效,否则处于影子模式。 |
+k8s:alpha(since:"1.36")=+k8s:minimum=1 | 始终处于影子模式。手写验证仍具有权威性。 |
在影子模式(shadow mode)下,声明式验证仍然运行,但 API 服务器不会返回其错误。 API 服务器会将这些错误与手写验证的错误进行比较,并记录和统计所有差异, 这样迁移后的规则可以先在真实集群上得到评估,然后再开始拒绝请求。
DeclarativeValidation:
使 API 服务器
针对 +k8s:alpha 和 +k8s:beta 规则比较声明式验证与手写验证的结果,并报告不匹配之处。
无论此门控是否启用,声明式验证都会运行;此门控仅控制是否报告。
DeclarativeValidationBeta:
+k8s:beta 规则的全局安全开关。启用时,这些规则生效;禁用时,它们回退到影子模式。
DeclarativeValidationTakeover:
已被 DeclarativeValidationBeta 取代,不再生效。设置此门控仍然会被接受。
没有任何门控会影响无前缀的标签。这些标签在 API 服务器中始终生效, 因为与之对应的手写验证已经被移除。
关于如何设置特性门控,请参阅特性门控。
API 服务器暴露以下指标:
| 指标 | 描述 |
|---|---|
declarative_validation_mismatch_total | 声明式验证结果与手写验证结果不一致的次数。 |
declarative_validation_parity_discrepancies_total | 同样的不一致,但带有 validation_identifier 标签,记录组、版本、类别、子资源和操作。 |
declarative_validation_panic_total | 声明式验证发生 panic 的次数。 |
declarative_validation_panics_total | 同样的 panic,但带有 validation_identifier 标签。 |
不匹配的情况也会被记录到日志中。对于已生效的(+k8s:beta)规则,
日志条目会建议禁用 DeclarativeValidationBeta,
以使 etcd 中的数据与早期版本的 Kubernetes 保持一致。
如果你观察到以下情况,可以考虑设置 DeclarativeValidationBeta=false:
意外的验证行为:本应有效的请求被拒绝,或者之前被拒绝的对象被接受。
性能下降:与此特性相关的延迟增加(例如 apiserver_request_duration_seconds 的增加)。
不匹配率高:declarative_validation_mismatch_total 频繁增加并影响你的工作负载。
要将 +k8s:beta 规则恢复为影子模式,请传递 --feature-gates=DeclarativeValidationBeta=false。
禁用该门控是一种安全机制,但请注意一种不太可能出现的极端情况: 如果某个缺陷导致声明式验证持久化了一个无效对象,那么禁用该门控后, 正确的手写验证会重新成为权威验证,进而可能阻止对该对象的后续更新。 修复此问题可能需要直接编辑所存储的对象。
每个标签都有一个稳定性级别(Alpha、Beta 或 Stable),用于描述标签本身的成熟度。
这与 +k8s:alpha 和 +k8s:beta 生命周期前缀不同,
后者描述的是标签的某一次使用的成熟度。
生成器的代码检查器(linter)根据稳定性级别决定标签可以出现的位置:
在 GA 包(例如 v1)中,无前缀的标签必须是 Stable 级别。
在 beta 包中,还允许使用无前缀的 Beta 标签。
在 alpha 包中,还允许使用无前缀的 Alpha 和 Beta 标签。
在 +k8s:alpha=... 内部允许使用 Alpha 标签;在 +k8s:beta=... 内部允许使用 Beta 标签。
在 +k8s:ifEnabled(...) 或 +k8s:ifDisabled(...) 内部,即使在 GA 包中也允许使用 Beta 标签,
因为已经有一个选项对该验证进行了门控。
每个条目还列出了标签可以出现的作用域:结构体字段、类型定义、列表值、映射键、映射值或常量值。
生成器还注册了一些仅用于测试其自身的标签(+k8s:validateTrue、+k8s:validateFalse、
+k8s:validateError、+k8s:validateTrueAlpha、+k8s:validateTrueBeta)。
不要在 API 定义中使用它们。要获取特定版本的权威标签列表,
请在 k8s.io/code-generator 中运行 validation-gen --docs。
| 标签 | 描述 | 稳定性 |
|---|---|---|
+k8s:alpha | 将验证标签置于影子模式(仅记录指标)。 | Beta |
+k8s:beta | 将验证标签置于生效模式(可通过 DeclarativeValidationBeta 禁用)。 | Beta |
+k8s:customUnique | 表示由手写验证负责检查列表的唯一性。 | Stable |
+k8s:customValidation | 从生成的遍历代码中调用手写验证函数。 | Stable |
+k8s:dependentForbidden | 表示设置此字段时,指定的同级字段不得被设置。 | Alpha |
+k8s:dependentRequired | 表示设置此字段时,指定的同级字段也必须被设置。 | Alpha |
+k8s:eachKey | 为映射中的每个键声明一个验证。 | Stable |
+k8s:eachVal | 为映射或列表中的每个值声明一个验证。 | Stable |
+k8s:enum | 表示某个字符串类型是枚举。 | Stable |
+k8s:enumExclude | 将某个常量从其类型的枚举值中排除。 | Alpha |
+k8s:forbidden | 表示某个字段不可被指定。 | Beta |
+k8s:format | 表示某个字符串字段具有特定格式。 | Stable |
+k8s:ifDisabled | 声明一个仅在某选项被禁用时才适用的验证。 | Stable |
+k8s:ifEnabled | 声明一个仅在某选项被启用时才适用的验证。 | Stable |
+k8s:ifMode | 声明一个仅在模式判别器取特定值时才适用的验证。 | Stable |
+k8s:immutable | 表示某个字段不可被更新。 | Stable |
+k8s:isSubresource | 指定某个包中的验证仅适用于特定的子资源。 | Stable |
+k8s:item | 为声明为 +k8s:listType=map 的切片中的某一项声明一个验证。 | Stable |
+k8s:listMapKey | 声明列表值类型中的某个命名子字段是列表映射键的一部分。 | Stable |
+k8s:listType | 声明列表字段的语义类型。 | Stable |
+k8s:maxBytes | 表示某个字符串字段的长度有字节数上限。 | Stable |
+k8s:maxItems | 表示某个列表的大小有上限。 | Stable |
+k8s:maxLength | 表示某个字符串字段的长度有字符数上限。 | Stable |
+k8s:maxProperties | 表示某个映射的条目数量有上限。 | Stable |
+k8s:maximum | 表示某个数值字段有最大值。 | Stable |
+k8s:minItems | 表示某个列表有最小大小。 | Stable |
+k8s:minLength | 表示某个字符串字段有最小字符数长度。 | Stable |
+k8s:minProperties | 表示某个映射有最少条目数量。 | Stable |
+k8s:minimum | 表示某个数值字段有最小值。 | Stable |
+k8s:modeDiscriminator | 表示此字段是基于状态的验证的判别器。 | Stable |
+k8s:monotonic | 确保字段的值在更新时永不减小。 | Alpha |
+k8s:neq | 验证字段的值不等于某个特定的不允许值。 | Alpha |
+k8s:opaqueType | 表示生成器忽略所引用类型上声明的所有验证。 | Stable |
+k8s:optional | 表示某个字段对客户端而言是可选的。 | Stable |
+k8s:required | 表示某个字段必须由客户端指定。 | Stable |
+k8s:subfield | 为结构体的某个子字段声明一个验证。 | Stable |
+k8s:supportsSubresource | 为包内的类型声明一个受支持的子资源。 | Stable |
+k8s:unionDiscriminator | 表示此字段是某个联合的判别器。 | Beta |
+k8s:unionMember | 表示此字段是某个联合组的成员。 | Stable |
+k8s:unique | 声明列表字段的元素是唯一的。 | Stable |
+k8s:update | 约束字段允许的更新转换。 | Stable |
+k8s:zeroOrOneOfMember | 表示此字段是某个“零或一”组的成员。 | Stable |
+k8s:alpha描述:
将验证规则置于影子模式,这是验证生命周期的第一个阶段。 仅在迁移现有手写验证时使用它,不要用于新字段。
手写验证仍然是权威的;声明式规则与其并行运行,不匹配和 panic 会被记录为指标。 这样可以在将规则提升到 Beta 之前,确认二者的行为完全一致。
无论特性门控如何设置,API 服务器都不会让 +k8s:alpha 规则生效。
稳定性级别:Beta
作用域:结构体字段、类型定义、列表值、映射键、映射值
参数:
since(字符串,可选):此验证首次进入影子模式时的 Kubernetes 版本。载荷:
<validation-tag>(必需):要置于影子模式的声明式验证标签。用法示例:
type MyStruct struct {
// +k8s:alpha(since:"1.36")=+k8s:minimum=1
MyField int `json:"myField"`
}
+k8s:beta描述:
将已迁移的验证规则置于生效模式,这是验证生命周期的第二个阶段。 仅在迁移现有手写验证时使用它,不要用于新字段。
当 DeclarativeValidationBeta 启用时(默认),该规则具有权威性,
API 服务器会丢弃其所覆盖的手写验证错误。禁用该门控会使规则恢复为影子模式。
稳定性级别:Beta
作用域:结构体字段、类型定义、列表值、映射键、映射值
参数:
since(字符串,可选):此验证被提升到 Beta 时的 Kubernetes 版本。载荷:
<validation-tag>(必需):要使其生效的声明式验证标签。用法示例:
type MyStruct struct {
// +k8s:beta(since:"1.37")=+k8s:minimum=1
MyField int `json:"myField"`
}
+k8s:customUnique描述:
表示由自定义的手写验证为此列表实现唯一性验证。这会禁止为该列表生成唯一性验证,
而 +k8s:listType=set、+k8s:listType=map 和 +k8s:unique
原本都隐含此类验证。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
用法示例:
type MyStruct struct {
// +k8s:listType=map
// +k8s:listMapKey=key
// +k8s:customUnique
MyList []Item `json:"myList"`
}
在此示例中,生成器记录 MyList 是一个列表映射,但不会为其生成唯一性检查;
该检查由手写代码负责。
+k8s:customValidation描述:
从生成的遍历代码中调用手写验证函数。当其他标签无法表达某些逻辑时,使用此标签。
该函数必须位于所生成代码的包中,并具有以下签名:
func(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue <ValueType>) field.ErrorList
<ValueType> 是值类型的可为 nil 形式:例如 *string 这样的指针,
或者当类型本身已经可为 nil(切片、映射、指针)时就是该类型本身。
每个生成的包都需要有自己的定义,因为每份生成的代码都会调用其所在包中的函数。
在函数名中,<Type> 和 <Field> 是 Go 标识符(Replicas,而不是 replicas):
字段作用域:ValidateCustom_<Type>_<Field> 验证单个字段。
更新时,如果该字段未发生变化,则跳过此函数。
类型作用域:ValidateCustom_<Type> 执行跨字段检查。更新时不会跳过此函数,
因此开销较大的检查应在 value 与 oldValue 相等时尽早返回。
对于逐元素的检查,请为元素类型添加标签,或者使用字段作用域并在函数内部循环处理。
稳定性级别:Stable
作用域:结构体字段、类型定义
用法示例:
// +k8s:customValidation
type MyStruct struct {
// +k8s:customValidation
StringField string `json:"stringField"`
// 此字段上的两个验证都会运行。
// +k8s:maxLength=3
// +k8s:customValidation
MaxLengthField string `json:"maxLengthField"`
}
+k8s:dependentForbidden描述:
表示当设置此字段时,指定的同级字段不得被设置。 当字段是非 nil 指针、非空切片或映射,或者非零值的内置类型时,即视为“已设置”。 依赖关系是单向的。重复使用此标签可以禁止多个同级字段。
稳定性级别:Alpha
作用域:结构体字段
参数:
<sibling-field-json-name>(字符串,必需):同级字段的 JSON 名称。用法示例:
type MyStruct struct {
// +k8s:optional
// +k8s:dependentForbidden("dependentA")
// +k8s:dependentForbidden("dependentB")
Trigger *string `json:"trigger"`
// +k8s:optional
DependentA *string `json:"dependentA"`
// +k8s:optional
DependentB *string `json:"dependentB"`
}
在此示例中,如果设置了 trigger,则 dependentA 和 dependentB 都不得被设置。
+k8s:dependentRequired描述:
表示当设置此字段时,指定的同级字段也必须被设置。 当字段是非 nil 指针、非空切片或映射,或者非零值的内置类型时,即视为“已设置”。 依赖关系是单向的。重复使用此标签可以要求多个同级字段。
稳定性级别:Alpha
作用域:结构体字段
参数:
<sibling-field-json-name>(字符串,必需):同级字段的 JSON 名称。用法示例:
type MyStruct struct {
// +k8s:optional
// +k8s:dependentRequired("dependent")
Trigger *string `json:"trigger"`
// +k8s:optional
Dependent *string `json:"dependent"`
}
在此示例中,如果设置了 trigger,则也必须设置 dependent。单独设置 dependent 是允许的。
+k8s:eachKey描述:
为映射中的每个键声明一个验证。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<validation-tag>(必需):要对每个键求值的标签。用法示例:
type MyStruct struct {
// +k8s:eachKey=+k8s:minimum=1
MyMap map[int]string `json:"myMap"`
}
+k8s:eachVal描述:
为映射或列表中的每个值声明一个验证。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<validation-tag>(必需):要对每个值求值的标签。用法示例:
type MyStruct struct {
// +k8s:eachVal=+k8s:minimum=1
MyMap map[string]int `json:"myMap"`
// +k8s:eachVal=+k8s:maxLength=10
MyList []string `json:"myList"`
}
+k8s:enum描述:
表示某个字符串类型是枚举。该类型的所有常量值都是枚举中的值,
除非你使用 +k8s:enumExclude 将其排除。
稳定性级别:Stable
作用域:类型定义
用法示例:
首先,定义一个新的字符串类型以及该类型的一些常量:
// +k8s:enum
type MyEnum string
const (
MyEnumA MyEnum = "A"
MyEnumB MyEnum = "B"
)
然后,在另一个结构体中使用此类型:
type MyStruct struct {
MyField MyEnum `json:"myField"`
}
验证逻辑确保 MyField 是所定义的枚举值之一("A" 或 "B")。
+k8s:enumExclude描述:
表示某个常量值不属于枚举,即使该常量的类型带有 +k8s:enum 标签。
你可以将此标签嵌套在 +k8s:ifEnabled 或
+k8s:ifDisabled 内部,使排除成为有条件的。
如果你使用了多个条件标签,只要任一条件满足,生成器就会排除该值。
稳定性级别:Alpha
作用域:常量值
用法示例:
// +k8s:enum
type MyEnum string
const (
MyEnumA MyEnum = "A"
// 永远不是有效值。
// +k8s:enumExclude
MyEnumB MyEnum = "B"
// 仅在 "MyFeature" 被禁用时才是有效值。
// +k8s:ifEnabled(MyFeature)=+k8s:enumExclude
MyEnumC MyEnum = "C"
)
+k8s:forbidden描述:
表示某个字段不可被指定。
稳定性级别:Beta
作用域:结构体字段
用法示例:
type MyStruct struct {
// +k8s:forbidden
MyField string `json:"myField"`
}
+k8s:format描述:
表示某个字符串字段具有特定格式。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
| 载荷 | 含义 |
|---|---|
k8s-extended-resource-name | Kubernetes 扩展资源名称:带域名前缀的名称,且不得带有 kubernetes.io 或 requests. 前缀。在其前面加上 requests. 后,结果必须是有效的标签键(配额中使用的形式)。 |
k8s-label-key | Kubernetes 标签键。 |
k8s-label-value | Kubernetes 标签值。 |
k8s-long-name | Kubernetes “长名称”,也称为“DNS 子域名”值。 |
k8s-long-name-caseless | 已弃用:不区分大小写的 Kubernetes “长名称”。 |
k8s-path-segment-name | Kubernetes “路径段名称”值。 |
k8s-prefixed-label-key | Kubernetes 标签键,且必须带有前缀。 |
k8s-resource-fully-qualified-name | 由斜杠分隔的非空前缀和名称(例如 prefix/name)。前缀必须是 DNS 子域名,名称必须是不超过 32 个字符的 C 标识符。 |
k8s-resource-pool-name | 一个或多个由 / 分隔的 Kubernetes “长名称”部分,总长度不超过 253 个字符。 |
k8s-short-name | Kubernetes “短名称”,也称为“DNS 标签”值。 |
k8s-uuid | 符合 RFC 4122 的 UUID。 |
用法示例:
type MyStruct struct {
// +k8s:format=k8s-long-name
Subdomain string `json:"subdomain"`
// +k8s:format=k8s-short-name
Label string `json:"label"`
// +k8s:format=k8s-uuid
ID string `json:"id"`
}
+k8s:ifDisabled描述:
声明一个仅在某选项被禁用时才适用的验证。选项对应于 API 服务器从特性门控派生出的验证选项。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值、常量值
参数:
<option>(字符串,必需):选项的名称。载荷:
<validation-tag>(必需):仅在该选项被禁用时才求值的验证标签。用法示例:
type MyStruct struct {
// +k8s:ifDisabled(MyFeature)=+k8s:required
MyField string `json:"myField"`
}
+k8s:ifEnabled描述:
声明一个仅在某选项被启用时才适用的验证。选项对应于 API 服务器从特性门控派生出的验证选项。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值、常量值
参数:
<option>(字符串,必需):选项的名称。载荷:
<validation-tag>(必需):仅在该选项被启用时才求值的验证标签。用法示例:
type MyStruct struct {
// +k8s:ifEnabled(MyFeature)=+k8s:required
MyField string `json:"myField"`
}
+k8s:ifMode描述:
声明一个仅在结构体的模式判别器取特定值时才适用的验证。 这用于表达基于状态的验证,即对象的形态取决于某个模式字段。
带有至少一个 +k8s:ifMode 标签的字段,在其所有标签都未提及的每种模式下都被隐式禁止。
稳定性级别:Stable
作用域:结构体字段
参数:
<mode>(字符串,位置参数):此验证所适用的判别器取值。modality(字符串,可选):当结构体有多个判别器组时,判别器组的名称。mode(字符串,可选):判别器取值,作为位置参数的具名替代形式。载荷:
<validation-tag>(必需):模式匹配时要求值的标签。用法示例:
type MyStruct struct {
// +k8s:modeDiscriminator
Mode string `json:"mode"`
// 在模式 "A" 下必需,并且额外限制长度。
// +k8s:ifMode("A")=+k8s:required
// +k8s:ifMode("A")=+k8s:maxLength=5
FieldA *string `json:"fieldA,omitempty"`
// 在模式 "B" 下可选,在其他所有模式下被隐式禁止。
// +k8s:ifMode("B")=+k8s:optional
FieldB *string `json:"fieldB,omitempty"`
}
+k8s:immutable描述:
表示某个字段不可被更新。与提供更细粒度转换控制的 +k8s:update 不同,
+k8s:immutable 禁止在创建之后对值做任何更改。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射值
用法示例:
type MyStruct struct {
// +k8s:immutable
StringField string `json:"stringField"`
// +k8s:immutable
SliceField []string `json:"sliceField"`
}
// +k8s:immutable
type ImmutableType string
+k8s:isSubresource描述:
一个包级别的标签,将包中的验证规则限定于某一个子资源, 使其不适用于根对象或任何其他子资源。 这让你可以将特定于子资源的验证放在独立的包中,与 API 类型分离。
稳定性级别:Stable
作用域:包
载荷:
<subresource-path>:此包中的验证所适用的子资源路径(例如 "/status" 或 "/scale")。此标签要求在定义 API 类型的包中有与之匹配的
+k8s:supportsSubresource。
如果没有,生成器仍会生成验证代码,但分发器无法识别该子资源路径,
因此不会有任何请求到达这些验证。
用法示例:
在 staging/src/k8s.io/api/apps/v1/doc.go 中,声明该类型支持 /scale:
// +k8s:supportsSubresource="/scale"
package v1
在 staging/src/k8s.io/api/apps/v1/validations/scale/doc.go 中,
定义仅针对 /scale 运行的规则:
// +k8s:isSubresource="/scale"
package scale
+k8s:item描述:
为声明为 +k8s:listType=map 的切片中的某一项声明一个验证。
你通过提供字段-值对参数来声明要匹配的项,其中字段是 listMapKey。
你必须指定所有的 listMapKey 字段。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
用法:
+k8s:item(<listMapKey-JSON-field-name>: <value>,...)=<validation-tag>
+k8s:item(stringKey: "value", intKey: 42, boolKey: true)=<validation-tag>
参数名使用列表映射键字段的 JSON 名称。值可以是字符串、整数或布尔值。
载荷:
<validation-tag>(必需):要对匹配的列表项求值的标签。用法示例:
type MyStruct struct {
// +k8s:listType=map
// +k8s:listMapKey=type
// +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember
// +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember
MyConditions []MyCondition `json:"conditions"`
}
type MyCondition struct {
Type string `json:"type"`
Status string `json:"status"`
}
在此示例中,type 为 "Approved" 和 "Denied" 的状况属于同一个“零或一”组,
因此二者最多只能出现一个。
+k8s:listMapKey描述:
声明列表值类型中的某个命名子字段是列表映射键的一部分。
使用 +k8s:listType=map 或 +k8s:unique=map 时必须使用此标签。
你可以使用多个 +k8s:listMapKey 标签来指定列表以多个字段为键。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<field-json-name>(必需):用作键的字段的 JSON 名称。用法示例:
// +k8s:listType=map
// +k8s:listMapKey=keyFieldOne
// +k8s:listMapKey=keyFieldTwo
type MyList []MyItem
type MyItem struct {
KeyFieldOne string `json:"keyFieldOne"`
KeyFieldTwo string `json:"keyFieldTwo"`
ValueField string `json:"valueField"`
}
键是 keyFieldOne 和 keyFieldTwo 的组合。
+k8s:listType描述:
声明列表字段的语义类型和属主行为:
atomic:单一属主;列表被视为单个值。set:共享属主且要求唯一;每个元素必须唯一。map:共享属主且基于键要求唯一;需要 +k8s:listMapKey。稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
atomic | map | set(必需)用法示例:
// +k8s:listType=map
// +k8s:listMapKey=keyField
type MyList []MyItem
type MyItem struct {
KeyField string `json:"keyField"`
ValueField string `json:"valueField"`
}
MyList 的每个元素都必须有唯一的 keyField。
+k8s:maxBytes描述:
表示某个字符串字段的长度有字节数上限。这可能只允许最少 N/4 个多字节字符。
如需改为限制字符数,请使用 +k8s:maxLength。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<non-negative integer>(必需):此字段的长度不得超过 X 字节。用法示例:
type MyStruct struct {
// +k8s:maxBytes=1024
MyString string `json:"myString"`
}
+k8s:maxItems描述:
表示某个列表的大小有上限。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射值
载荷:
<non-negative integer>(必需):此列表的项数不得超过 X。用法示例:
type MyStruct struct {
// +k8s:maxItems=5
MyList []string `json:"myList"`
}
+k8s:maxLength描述:
表示某个字符串字段的长度有字符数上限。如果值使用多字节字符,可能允许多达 4*N 字节。
如需改为限制字节数,请使用 +k8s:maxBytes。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<non-negative integer>(必需):此字段的长度不得超过 X 个字符。用法示例:
type MyStruct struct {
// +k8s:maxLength=10
MyString string `json:"myString"`
}
+k8s:maxProperties描述:
按 JSON Schema 的定义,对对象的属性数量设置上限。 在 Kubernetes 中,你只能用它来约束定义为 Go map 的字段中的条目数量。
稳定性级别:Stable
作用域:结构体字段、类型定义
载荷:
<non-negative integer>(必需):此映射的属性数量不得超过 X(其中 X <= 100000)。用法示例:
type MyStruct struct {
// +k8s:maxProperties=32
MyMap map[string]string `json:"myMap"`
}
+k8s:maximum描述:
表示某个数值字段有最大值。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<integer>(必需):此字段必须小于或等于 X。用法示例:
type MyStruct struct {
// +k8s:maximum=100
MyInt int `json:"myInt"`
}
+k8s:minItems描述:
表示某个列表有最小大小。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射值
载荷:
<non-negative integer>(必需):此列表至少要有 X 项。用法示例:
type MyStruct struct {
// +k8s:minItems=1
MyList []string `json:"myList"`
}
+k8s:minLength描述:
表示某个字符串字段有最小字符数长度。如果值使用多字节字符,则最小字节数介于 X 到 4X 之间。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<integer>(必需):此字段的长度至少为 X 个字符。用法示例:
type MyStruct struct {
// +k8s:minLength=3
MyString string `json:"myString"`
}
+k8s:minProperties描述:
按 JSON Schema 的定义,对对象的属性数量设置下限。 在 Kubernetes 中,你只能用它来约束定义为 Go map 的字段中的条目数量。
稳定性级别:Stable
作用域:结构体字段、类型定义
载荷:
<non-negative integer>(必需):此映射至少要有 X 个属性(其中 X <= 100000)。用法示例:
type MyStruct struct {
// +k8s:minProperties=1
MyMap map[string]string `json:"myMap"`
}
+k8s:minimum描述:
表示某个数值字段有最小值。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<integer>(必需):此字段必须大于或等于 X。用法示例:
type MyStruct struct {
// +k8s:minimum=0
MyInt int `json:"myInt"`
}
+k8s:modeDiscriminator描述:
表示此字段是基于状态的验证的判别器(discriminator):
其取值决定哪些 +k8s:ifMode 规则适用于同一结构体中的同级字段。
判别器必须是非指针的 string 或 bool。一个结构体可以有多个判别器组;
使用 modality 参数为额外的组命名。组名 default 是保留的,
且组名必须匹配 ^[a-zA-Z][a-zA-Z0-9_]*$。
稳定性级别:Stable
作用域:结构体字段
参数:
modality(字符串,可选):当存在多个判别器组时,判别器组的名称。用法示例:
type MyStruct struct {
// +k8s:modeDiscriminator
Mode string `json:"mode"`
// +k8s:modeDiscriminator(modality:"Legacy")
Legacy bool `json:"legacy"`
// +k8s:ifMode("A")=+k8s:required
FieldA *string `json:"fieldA,omitempty"`
// +k8s:ifMode(modality:"Legacy", mode:"true")=+k8s:required
FieldB *string `json:"fieldB,omitempty"`
}
+k8s:monotonic描述:
确保数值字段的值在更新时永不减小。
稳定性级别:Alpha
作用域:结构体字段、类型定义
用法示例:
type MyStruct struct {
// +k8s:minimum=0
// +k8s:monotonic
Generation int64 `json:"generation"`
}
+k8s:neq描述:
验证字段的值不等于某个特定的不允许值。支持字符串、整数和布尔类型。
稳定性级别:Alpha
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
<value>(必需):不允许的值。解析器会推断其类型(字符串、整数、布尔值)。用法示例:
type MyStruct struct {
// +k8s:neq="disallowed"
MyString string `json:"myString"`
// +k8s:neq=0
MyInt int `json:"myInt"`
// +k8s:neq=true
MyBool bool `json:"myBool"`
}
+k8s:opaqueType描述:
表示生成器忽略所引用类型上声明的所有验证。
如果生成器当前的标志未包含所引用类型的包,你必须设置此标签,
否则代码生成会失败(这样可以避免无声的错误)。
如果生成器不应忽略这些验证,请使用 --readonly-pkg 标志将该类型的包添加到生成器中。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
用法示例:
import "some/external/package"
type MyStruct struct {
// +k8s:opaqueType
ExternalField package.ExternalType `json:"externalField"`
}
+k8s:optional描述:
表示某个字段对客户端而言是可选的。
稳定性级别:Stable
作用域:结构体字段
用法示例:
type MyStruct struct {
// +k8s:optional
MyField string `json:"myField"`
}
+k8s:required描述:
表示某个字段必须由客户端指定。
稳定性级别:Stable
作用域:结构体字段
用法示例:
type MyStruct struct {
// +k8s:required
MyField string `json:"myField"`
}
+k8s:subfield描述:
为结构体的某个子字段声明一个验证。所指定的子字段必须是该结构体或其内嵌结构体的直接字段。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
参数:
<field-json-name>(字符串,必需):子字段的 JSON 名称。载荷:
<validation-tag>(必需):要对该子字段求值的标签。用法示例:
type MyStruct struct {
// +k8s:subfield(mySubfield)=+k8s:required
Inner MyInnerStruct `json:"inner"`
}
type MyInnerStruct struct {
MySubfield string `json:"mySubfield"`
}
+k8s:supportsSubresource描述:
一个包级别的标签,在分发函数中注册一个子资源路径, 使得发往该子资源的请求可以被路由到某个验证实现。对多个子资源可重复使用此标签。
如果没有任何 +k8s:supportsSubresource 标签,则只验证根资源,
子资源请求会因 "no validation found" 错误而失败。
如果有此标签但没有匹配的 +k8s:isSubresource,
则该子资源使用根对象的规则。
稳定性级别:Stable
作用域:包
载荷:
<subresource-path>:要支持的子资源路径(例如 "/status" 或 "/scale")。用法示例:
在 staging/src/k8s.io/api/core/v1/doc.go 中,为包 v1 中的类型处理 /status 和 /scale:
// +k8s:supportsSubresource="/status"
// +k8s:supportsSubresource="/scale"
package v1
+k8s:unionDiscriminator描述:
表示此字段是某个联合(union)的判别器。判别器的取值决定哪个联合成员必须存在。
稳定性级别:Beta
作用域:结构体字段、列表值
参数:
union(字符串,可选):当存在多个联合时,联合的名称。用法示例:
type MyStruct struct {
TypeMeta int
// +k8s:unionDiscriminator
D D `json:"d"`
// +k8s:unionMember
// +k8s:optional
M1 *M1 `json:"m1"`
// +k8s:unionMember
// +k8s:optional
M2 *M2 `json:"m2"`
}
type D string
const (
DM1 D = "M1"
DM2 D = "M2"
)
type M1 struct{}
type M2 struct{}
D 的值决定 M1 和 M2 中哪个成员必须存在。
+k8s:unionMember描述:
表示此字段是某个联合的成员。联合中必须恰好设置一个成员。
稳定性级别:Stable
作用域:结构体字段、列表值
参数:
union(字符串,可选):当存在多个联合时,联合的名称。memberName(字符串,可选):此成员对应的判别器取值。默认为字段名。用法示例:
type MyStruct struct {
// +k8s:unionMember(union: "union1")
// +k8s:optional
M1 *M1 `json:"u1m1"`
// +k8s:unionMember(union: "union1")
// +k8s:optional
M2 *M2 `json:"u1m2"`
}
type M1 struct{}
type M2 struct{}
+k8s:unique描述:
声明列表字段的元素是唯一的。你可以将此标签与 +k8s:listType=atomic 一起使用,
在不改变列表合并语义的情况下添加唯一性约束;也可以单独使用它来指定唯一性语义。
稳定性级别:Stable
作用域:结构体字段、类型定义、列表值、映射键、映射值
载荷:
map | set(必需)。使用 map 时,元素的标识来自 +k8s:listMapKey 字段;
使用 set 时,来自整个元素值。用法示例:
type MyStruct struct {
// +k8s:listType=atomic
// +k8s:unique=set
Names []string `json:"names"`
// +k8s:listType=atomic
// +k8s:unique=map
// +k8s:listMapKey=key
Items []Item `json:"items"`
}
+k8s:update描述:
对字段允许的更新操作施加约束。你可以使用多个标签来指定多个约束。
| 约束 | 效果 |
|---|---|
NoSet | 禁止从未设置到已设置的转换。 |
NoUnset | 禁止从已设置到未设置的转换。 |
NoModify | 禁止更改值,但允许设置和取消设置的转换。 |
NoAddItem | 禁止向切片或映射中添加项。 |
NoRemoveItem | 禁止从切片或映射中移除项。 |
对于非指针的结构体,NoSet 和 NoUnset 没有效果,因为你无法取消设置这些字段。
对于切片和映射字段,“未设置”指 len == 0。
NoAddItem 和 NoRemoveItem 的切片项标识来自 +k8s:listType、
+k8s:listMapKey 和 +k8s:unique;
对于映射,键就是项的标识。
NoModify 不支持直接用于切片或映射;要实现逐项的不可变性,
请使用 +k8s:eachVal=+k8s:update=NoModify。在列表上,
+k8s:eachVal=+k8s:update=NoModify 需要 listType=map 或 unique=map,
否则无法检测内容的变化。
稳定性级别:Stable
作用域:结构体字段、列表值、映射值
载荷:
NoSet | NoUnset | NoModify | NoAddItem | NoRemoveItem用法示例:
type MyStruct struct {
// 一次性设置:可以随时设置,但设置后不能更改或清除。
// +k8s:update=NoModify
// +k8s:update=NoUnset
SetOnce *string `json:"setOnce,omitempty"`
// 必须在创建时设置,否则永远不能设置。
// +k8s:update=NoSet
AtCreationOnly *string `json:"atCreationOnly,omitempty"`
// 冻结列表的形态;各个项仍然可以更改。
// +k8s:listType=map
// +k8s:listMapKey=key
// +k8s:update=NoAddItem
// +k8s:update=NoRemoveItem
FrozenShape []Item `json:"frozenShape"`
}
+k8s:zeroOrOneOfMember描述:
表示此字段是某个“零或一”(zero-or-one-of)联合的成员。 “零或一”联合最多允许设置一个成员。与常规联合不同,不设置任何成员也是有效的。
稳定性级别:Stable
作用域:结构体字段、列表值
此标签旨在通过 +k8s:item 应用于列表项的集合,而不是直接用于结构体字段。
参数:
union(字符串,可选):当存在多个联合时,联合的名称。memberName(字符串,可选):此成员的自定义成员名。默认为字段名。用法示例:
type MyStruct struct {
// +k8s:listType=map
// +k8s:listMapKey=type
// +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember
// +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember
Conditions []MyCondition `json:"conditions"`
}
type MyCondition struct {
Type string `json:"type"`
Status string `json:"status"`
}
在此示例中,"Approved" 和 "Denied" 状况最多只能出现一个。二者都不出现也是有效的。