You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes CRD Schema中禁止额外属性并触发校验错误?

问题背景

现有如下CRD定义:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: examples.tomasaschan.com
spec:
  group: tomasaschan.com
  names:
    kind: Example
    listKind: Examples
    plural: examples
    singular: example
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          properties:
            spec:
              properties:
                foo:
                  type: string
              type: object
          type: object

合法的Example资源示例:

apiVersion: tomasaschan.com/v1
kind: Example
metadata:
  name: example1
spec:
  foo: bar

由于foo不是必填项,当拼写错误(如写成boo)时,API服务器仍会接受该资源:

apiVersion: tomasaschan.com/v1
kind: Example
metadata:
  name: example1
spec:
  boo: far

需求:让此类包含未知字段的请求触发Schema校验错误,返回400响应并提示未知属性。

此前尝试的问题:

  • 在JSON Schema中使用additionalProperties: false会触发API服务器报错:Forbidden: additionalProperties and properties are mutual exclusive
  • 设置spec.preserveUnknownFields: false或x-kubernetes-preserve-unknown-fields: false仅会丢弃未知字段,不会拒绝请求。

解决方案

方案1:使用x-kubernetes-validations(Kubernetes 1.25+)

从Kubernetes 1.25开始,CRD支持通过x-kubernetes-validations扩展添加自定义校验规则,直接在schema中实现未知字段的拦截。修改后的CRD如下:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: examples.tomasaschan.com
spec:
  group: tomasaschan.com
  names:
    kind: Example
    listKind: Examples
    plural: examples
    singular: example
  scope: Namespaced
  preserveUnknownFields: false  # 必须关闭未知字段保留,确保校验生效
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          properties:
            spec:
              type: object
              properties:
                foo:
                  type: string
              # 添加自定义校验规则,限制spec仅允许foo属性
              x-kubernetes-validations:
                - rule: "self.keys().all(key, key in ['foo'])"
                  message: "spec仅允许包含'foo'属性,未知属性: {{key}}"
          type: object

当提交包含boo的Example资源时,API服务器会返回400错误,示例响应如下:

Error from server: error when creating "example.yaml": admission webhook "validation.examples.tomasaschan.com" denied the request: spec仅允许包含'foo'属性,未知属性: boo

方案2:使用Validating Admission Webhook(全版本兼容)

如果你的Kubernetes版本低于1.25,或需要更复杂的校验逻辑,可通过Validating Admission Webhook实现:

  1. 开发一个Webhook服务,接收Kubernetes的AdmissionReview请求,解析请求中的Example资源spec字段。
  2. 对比spec的属性列表与CRD定义的允许字段,若存在未知字段,返回allowed: false的AdmissionResponse,并携带错误信息。
  3. 将Webhook注册到Kubernetes集群,配置为针对examples.tomasaschan.com资源的CREATE、UPDATE操作触发校验。

这种方式完全自定义校验逻辑,可灵活控制错误提示和校验范围。


内容的提问来源于stack exchange,提问作者Tomas Aschan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:15:33