Kyverno前置条件

基于变量控制策略规则的执行。

前置条件允许通过基于变量值构建表达式来控制策略规则的执行。

matchexclude 允许基于资源和用户信息过滤请求,preconditions 用于定义自定义过滤器,以便更精细地控制何时应用规则。

preconditions 的主要应用场景是在 mutategenerate 规则中,例如,当需要检查和保证变量(通常是 AdmissionReview 中的数据)不为空时。除了 AdmissionReview 变量,写成 JMESPath 表达式,preconditions 也可用于检查来自 ConfigMap 中的变量。使用 patchJson6902mutate 应该使用 preconditions 作为一个过滤结果的方式。

对于 validate 规则,更推荐使用 patterns,因为可以使用条件语句。

当在 preconditions 声明中指定 JMESPath 表达式时,可能会包含一些特殊字符(例如 Kubernetes annotation 中的 /),需要用双引号括起 annotation 从而作为一个字面值。使用反斜杠字符 () 转义双引号。更多关于在 preconditions 中书写 JMESPath 表达式的细节,请参考这里的 JMESPath 页面。

{{request.object.spec.template.metadata.annotations.\"foo.k8s.corp.net/bar\"}}

您可以在 preconditions 字段中指定多个语句,并通过 any 和 all 来控制它们的操作。

Any 和 All 声明

你可以通过在 any 和/或 all 声明下嵌套表达式来进一步控制如何评估 preconditions。这使您可以进一步构建更精确的规则触发逻辑。anyall 可以在同一规则中同时使用,可以使用多个 any 语句(多个 all 语句将是多余的)。对于任意 any/all 声明,对于要处理的先决条件,每个块必须总体评估为 TRUE。如果任何 any/all 声明块被评估为 FALSEpreconditions 将不满足,这个规则就不会被应用。

例如,考虑一个具有许多不同标签的 Deployment 清单,如下所示。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  labels:
    app: busybox
    color: red
    animal: cow
    food: pizza
    car: jeep
    env: qa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - image: busybox:1.28
        name: busybox
        command: ["sleep", "9999"]

在 preconditions 声明中使用 anyall 块,在评估规则时可以获得更精细的控制。在下面的样本策略中,使用一个 any 块将使 preconditions 以逻辑 OR 的方式工作。如果存在 color=blueapp=busybox 标签,这个策略都会生效。即便上面的 Deployment 中配置的标签是 color=red,它也符合 any 条件需求。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: any-all-preconditions
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: any-all-rule
    match:
      resources:
        kinds:
        - Deployment
    preconditions:
      any:
      - key: "{{ request.object.metadata.labels.color || '' }}"
        operator: Equals
        value: blue
      - key: "{{ request.object.metadata.labels.app || '' }}"
        operator: Equals
        value: busybox
    validate:
      message: "Busybox must be used based on this label combination."
      pattern:
        spec:
          template:
            spec:
              containers:
              - name: "*busybox*"

注意:可以在 preconditions 中使用 JMESPath 语法进行 non-existence 检查,详见这里。

all 块要求其包含的所有声明都必须评估为 TRUE 时,该块才被认为是 TRUE。下面的策略中,除了会检查 any 中的条件,还会检查 animal=cowenv=prod 标签,之后才会验证是否存在名称中包含 foxes 字符串的容器。由于 anyall 块被评估为 TRUE,就会执行验证过程,然而由于容器秉承是 busybox,这个 Deployment 会创建失败。如果 all 块中的一条语句被更改,使得选中标签的值不在 Deployment 中,则不会处理该规则并创建 Deployment。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: any-all-preconditions
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: any-all-rule
    match:
      any:
      - resources:
          kinds:
          - Deployment
    preconditions:
      any:
      - key: "{{ request.object.metadata.labels.color || '' }}"
        operator: Equals
        value: blue
      - key: "{{ request.object.metadata.labels.app || '' }}"
        operator: Equals
        value: busybox
      all:
      - key: "{{ request.object.metadata.labels.animal || '' }}"
        operator: Equals
        value: cow
      - key: "{{ request.object.metadata.labels.env || '' }}"
        operator: Equals
        value: qa
    validate:
      message: "Foxes must be used based on this label combination."
      pattern:
        spec:
          template:
            spec:
              containers:
              - name: "*foxes*"

操作符

当前,在前置条件评估时支持使用以下操作符:

  • Equals

  • NotEquals

  • In (已废弃)

  • AnyIn

  • AllIn

  • NotIn (已废弃)

  • AnyNotIn

  • AllNotIn

  • GreaterThan

  • GreaterThanOrEquals

  • LessThan

  • LessThanOrEquals

  • DurationGreaterThan

  • DurationGreaterThanOrEquals

  • DurationLessThan

  • DurationLessThanOrEquals

集合操作符 In、AnyIn、AllIn、NotIn、AnyNotIn 和 AllNotIn 支持将字符串集合作为值(如 [“str1”, “str2”])。也支持你指定一个字符串集合作为 可以(如 [“str1”, “str2”] AllIn [“str1”, “str2”, “str3”])。在这个示例中,AllIn 检查 key 中所有的字符串片段是否都在 value 中,AnyIn 检查 key 中任意的字符串片段在 value 中,AllNotIn 检查 key 中所有的字符串片段是否都不在 value 中,AnyNotIn 检查 key 中任意的字符串片段不在 value 中。当前不支持其他类型的集合。旧操作符 In 和 NotIn 的作用和 AllIn 及 AnyNotIn 相近,它们已经过期,并且会在未来版本中被移除。

持续时间运算符可用于诸如验证作为持续时间单位的注释之类的事情。持续时间运算符期望数字类型(作为秒)的 key 或 value,或一个有效的 Go 持续时间的字符串,例如"1h"。支持的字符串单位是 s (second)、m (minute) 和 h (hour)。time.ParseDuration 涵盖了有关支持的持续时间字符串的完整详细信息。

GreaterThanGreaterThanOrEqualsLessThanLessThanOrEquals 操作符也可用于 Kubernetes 资源数量。可以使用由 resource.ParseQuantity 处理的任何值,这包括比较具有不同比例的值。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: resource-quantities
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: memory-limit
    match:
      any:
      - resources:
          kinds:
          - Pod
    preconditions:
      any:
      - key: "{{request.object.spec.containers[*].resources.requests.memory}}"
        operator: LessThan
        value: 1Gi

通配符匹配

字符串值支持使用通配符以允许部分匹配。下面的示例会匹配容器镜像名称以 bash 开头的 Pod。

  - name: match-on-image
    match:
      any:
      - resources:
          kinds:
          - Pods
    preconditions:
      any:
      - key: "{{request.object.spec.template.spec.containers.image}}"
        operator: Equals
        value: "bash:*"

匹配没有服务帐户的请求

这个示例,这个规则之后应用于来自 ServiceAccounts(即 {{serviceAccountName}} 不为空)的请求。

  - name: generate-owner-role
    match:
      any:
      - resources:
          kinds:
          - Namespace
    preconditions:
      any:
      - key: "{{serviceAccountName}}"
        operator: NotEquals
        value: ""

匹配来自特定服务帐号的请求

这个示例,规则只会应用于来自 ServiceAccount 名称是 build-default 和 build-base 的请求。

  - name: generate-default-build-role
    match:
      any:
      - resources:
          kinds:
          - Namespace
    preconditions:
      any:
      - key: "{{serviceAccountName}}"
        operator: AnyIn
        value: ["build-default", "build-base"]

你可能感兴趣的:(Kyverno前置条件)