本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.26:介绍验证性准入策略

在 Kubernetes 1.26 中,验证性准入策略的第一个 Alpha 版本已可用!

验证性准入策略使用通用表达式语言 (Common Expression Language, CEL) 来为验证性准入 Webhook 提供一种声明式的、进程内的替代方案。

CEL 最初被引入 Kubernetes 是用于CustomResourceDefinitions 的验证规则。此增强功能扩展了 CEL 在 Kubernetes 中的使用,以支持更广泛的准入场景。

准入 Webhook 的开发和运维可能很繁琐。Webhook 开发者必须实现并维护一个 Webhook 二进制文件来处理准入请求。此外,准入 Webhook 的运维也很复杂。每个 Webhook 都必须被部署、监控,并有明确的升级和回滚计划。更糟糕的是,如果 Webhook 超时或不可用,Kubernetes 控制平面可能会变得不可用。此增强功能通过将 CEL 表达式嵌入到 Kubernetes 资源中,而不是调用远程的 Webhook 二进制文件,从而避免了准入 Webhook 的大部分复杂性。

例如,要限制 Deployment 可以拥有的副本数量。首先定义一个验证策略

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

expression 字段包含用于验证准入请求的 CEL 表达式。matchConstraints 声明了此 ValidatingAdmissionPolicy 可能验证的请求类型。

接下来将策略绑定到适当的资源

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "demo-binding-test.example.com"
spec:
  policyName: "demo-policy.example.com"
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: environment
        operator: In
        values:
        - test

ValidatingAdmissionPolicyBinding 资源仅将上述策略绑定到 environment 标签被设置为 test 的名字空间。一旦此绑定被创建,kube-apiserver 将开始强制执行此准入策略。

为了强调这种方法比准入 Webhook 简单多少,如果这个例子改用 Webhook 实现,就需要开发和维护一整个二进制文件,只为了执行一个 <= 检查。在我们对生产环境中使用的各种准入 Webhook 的审查中,绝大多数执行的都是相对简单的检查,所有这些都可以很容易地使用 CEL 来表达。

验证性准入策略是高度可配置的,使策略作者能够定义可被参数化并根据集群管理员的需要限定于特定资源的策略。

例如,可以修改上述准入策略使其可配置

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
  name: "demo-policy.example.com"
spec:
  paramKind:
    apiVersion: rules.example.com/v1 # You also need a CustomResourceDefinition for this API
    kind: ReplicaLimit
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas <= params.maxReplicas"

在这里,paramKind 定义了用于配置策略的资源,并且 expression 使用 params 变量来访问参数资源。

这允许多个绑定被定义,每个绑定的配置都不同。例如

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "demo-binding-production.example.com"
spec:
  policyName: "demo-policy.example.com"
  paramRef:
    name: "demo-params-production.example.com"
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: environment
        operator: In
        values:
        - production
apiVersion: rules.example.com/v1 # defined via a CustomResourceDefinition
kind: ReplicaLimit
metadata:
  name: "demo-params-production.example.com"
maxReplicas: 1000

这个绑定和参数资源对将 environment 标签设置为 production 的名字空间中的 Deployment 副本数限制为最多 1000 个。

然后你可以使用一个单独的绑定和参数对为 test 环境中的名字空间设置不同的限制。

我希望这让你对验证性准入策略的可能性有了一个初步的了解!我们还有很多特性尚未提及。

要了解更多信息,请阅读验证性准入策略

我们正在努力为准入策略添加更多功能,并使该增强功能更易于使用。请试用它,向我们发送你的反馈,并帮助我们构建一个更简单的准入 Webhook 替代方案!

我如何参与?

如果你想参与准入策略的开发,讨论增强功能的路线图,或报告错误,你可以在 SIG API Machinery 与开发者联系。