验证和变更准入策略(Validating and Mutating Admission Policies)

验证和变更准入策略(Validating and Mutating Admission Policies)

使用声明式准入策略在准入时通过通用表达氏语言(CEL)验证或变更资源。

本页面提供声明式准入策略的概述,此策略允许你使用通用氏表达语言(CEL) 来验证或变更资源。

MutatingAdmissionPolicy(Beta)
在对象被存储之前对其进行修改(例如:添加默认标签)。
ValidatingAdmissionPolicy
根据特定规则配置是否允许或拒绝会修改资源的请求。

准备开始

你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:

你的 Kubernetes 服务器版本必须不低于版本 v1.32.

要获知版本信息,请输入 kubectl version.

对于 ValidatingAdmissionPolicy,请确保你的集群版本为 1.30 或更高。

对于 MutatingAdmissionPolicy,你需要:

  • 运行版本 1.32 或更高的集群。
  • 启用 MutatingAdmissionPolicy 特性门控
  • 启用 admissionregistration.k8s.io/v1beta1 API 组

本地测试

如果你正在使用 kind,请使用此配置来启用必要的特性:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  "MutatingAdmissionPolicy": true
runtimeConfig:
  "admissionregistration.k8s.io/v1beta1": "true"
nodes:
- role: control-plane
  image: kindest/node:v1.32.0

如果你正在使用 minikube,请运行:

minikube start --feature-gates=MutatingAdmissionPolicy=true \
  --runtime-config=admissionregistration.k8s.io/v1beta1=true

什么是声明式准入策略?

声明式准入策略提供了一种声明式的、进程内的准入 Webhook 替代方案。 通过使用通用表达氏语言(CEL)来声明策略规则,这些策略直接在 API 服务器内进行评估。

这些策略高度可配置,使策略作者能够定义可参数化的逻辑,并根据集群管理员的需要限定到特定资源。 它们分为两种类型:

ValidatingAdmissionPolicy
用于强制执行约束条件。
MutatingAdmissionPolicy(Beta)
用于在准入过程中修改资源。

准入策略的 API 类型

声明式策略需要一个 policy 和一个 binding 资源。参数资源是可选的,用于提供运行时配置。

policy 资源
使用通用表达氏语言(CEL)描述策略的抽象逻辑。 例如,ValidatingAdmissionPolicy 可以强制执行副本限制或确保特定标签存在, 而 MutatingAdmissionPolicy 可以修改资源,例如为命名空间添加默认标签。
binding 资源
将策略链接到你的集群并提供作用域。 ValidatingAdmissionPolicyBinding 或 MutatingAdmissionPolicyBinding 将策略连接到特定资源。如果你只想对特定资源子集强制执行策略, binding 就是你使用 matchResources 来缩小策略作用域的地方。
parameter 资源(可选)
允许策略配置与其定义分离。参数资源是指 API 中可用的 Kubernetes 资源。 它们可以是像 ConfigMap 这样的内置类型,也可以是像 CustomResourceDefinition(CRD)这样的扩展。 策略绑定然后使用 spec.paramRef 来引用实际的参数资源。 如果策略不需要参数,则不指定 spec.paramKind

ValidatingAdmissionPolicy

以下是限制 Deployment 副本数的 ValidatingAdmissionPolicy 示例。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "replica-limit-prod.example.com"
spec:
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas <= 5"

spec.validations 包含使用通用表达氏语言(CEL)的 CEL 表达式, 用于验证请求。如果表达式求值为 false,则根据 spec.failurePolicy 字段强制执行验证检查。

说明:

你可以在 CEL Playground 中快速测试 CEL 表达式。

要配置在集群中使用的验证准入策略,需要一个绑定。 以下是 ValidatingAdmissionPolicyBinding 的示例:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "demo-binding-test.example.com"
spec:
  policyName: "replica-limit-prod.example.com"
  validationActions: [Deny]
  matchResources:
    namespaceSelector:
      matchLabels:
        environment: test

MutatingAdmissionPolicy(Beta)

与验证类似,你可以创建一个 MutatingAdmissionPolicy,它可以在准入过程中修改资源。 以下示例对新创建的、不是系统命名空间且未设置 Pod 安全准入标签的命名空间强制执行基线 Pod 安全标准。

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingAdmissionPolicy
metadata:
  name: "set-baseline-pod-security"
spec:
  reinvocationPolicy: Never
  matchConstraints:
    resourceRules:
    - apiGroups:   [""]
      apiVersions: ["v1"]
      operations:  ["CREATE"]
      resources:   ["namespaces"]
  matchConditions:                                              
    - name: "exclude-system-namespaces"
      expression: "!object.metadata.name.startsWith('kube-')"
    - name: "no-existing-pod-security-label"
      expression: "!('pod-security.kubernetes.io/enforce' in object.metadata.labels)"
  mutations:
    - patchType: "ApplyConfiguration"
      applyConfiguration:
        expression: "Object{metadata: Object.metadata{labels: {'pod-security.kubernetes.io/enforce': 'baseline'}}}"

需要一个 MutatingAdmissionPolicyBinding 来激活此策略:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingAdmissionPolicyBinding
metadata:
  name: "set-baseline-pod-security-binding"
spec:
  policyName: "set-baseline-pod-security"

策略操作

每个准入策略绑定必须指定一个或多个操作来声明策略的执行方式。

对于 ValidatingAdmissionPolicyBinding,支持的 validationActions 包括:

Audit
验证失败被包含在 API 请求的审计事件中。
Warn
验证失败作为警告报告给请求客户端。
Deny
验证失败导致请求被拒绝。

DenyWarn 不能一起使用,因为这种组合会在 API 响应体和 HTTP 警告头中重复验证失败信息。

对于 MutatingAdmissionPolicyBinding,支持的 mutationActions 包括:

Apply
将基于 CEL 的变更应用到资源。

失败的策略检查或发生的错误将根据这些操作执行。 只有当 failurePolicy 设置为 Fail(或未指定)时,failurePolicy 定义的失败才会根据这些操作执行。

有关策略审计日志的更多详情, 请参见审计注解:验证失败

参数资源

参数资源允许策略配置与其定义分离。策略可以定义 paramKind, 它概述了参数资源的 Group、Version 和 Kind(GVK), 然后策略绑定通过名称(通过 policyName)将策略与特定的参数资源通过 paramRef 关联起来。

参数资源将策略逻辑与其配置解耦。要使用它们,请定义一个带有 paramKind 的 ValidatingAdmissionPolicy, 此 paramKind 引用你的配置资源:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "replica-limit-prod.example.com"
spec:
  paramKind:
    apiVersion: rules.example.com/v1
    kind: ReplicaLimit
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas <= params.maxReplicas"
      messageExpression: "'object.spec.replicas must be no greater than ' + string(params.maxReplicas)"

spec.paramKind 字段指定用于参数化策略的资源类型。 在此示例中,它由 ReplicaLimit 自定义资源配置。

注意 CEL 表达式如何通过 CEL params 变量引用参数(例如 params.maxReplicas)。 spec.matchConstraints 指定此策略旨在评估哪些资源。 像 ConfigMap 这样的原生类型也可以用作参数引用。

对于每个准入请求,API 服务器评估与请求匹配的每个(policybindingparam)组合的 CEL 表达式。 要使请求被准入,它必须通过所有评估。

清理

要删除创建的资源,请运行以下命令:

kubectl delete validatingadmissionpolicy replica-limit-prod.example.com
kubectl delete validatingadmissionpolicybinding demo-binding-test.example.com
kubectl delete mutatingadmissionpolicy set-baseline-pod-security
kubectl delete mutatingadmissionpolicybinding set-baseline-pod-security-binding
最后修改 July 07, 2026 at 10:44 AM PST: [zh-cn]Add admission-policy-tutorial (19e1f2bbe3)