基于变量控制策略规则的执行。
前置条件允许通过基于变量值构建表达式来控制策略规则的执行。
match
和 exclude
允许基于资源和用户信息过滤请求,preconditions
用于定义自定义过滤器,以便更精细地控制何时应用规则。
preconditions
的主要应用场景是在 mutate
或 generate
规则中,例如,当需要检查和保证变量(通常是 AdmissionReview 中的数据)不为空时。除了 AdmissionReview 变量,写成 JMESPath 表达式,preconditions
也可用于检查来自 ConfigMap 中的变量。使用 patchJson6902
的 mutate
应该使用 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。这使您可以进一步构建更精确的规则触发逻辑。any
和 all
可以在同一规则中同时使用,可以使用多个 any
语句(多个 all
语句将是多余的)。对于任意 any/all
声明,对于要处理的先决条件,每个块必须总体评估为 TRUE。如果任何 any/all 声明块被评估为 FALSE,preconditions
将不满足,这个规则就不会被应用。
例如,考虑一个具有许多不同标签的 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 声明中使用 any
和 all
块,在评估规则时可以获得更精细的控制。在下面的样本策略中,使用一个 any
块将使 preconditions 以逻辑 OR 的方式工作。如果存在 color=blue
或 app=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=cow
和 env=prod
标签,之后才会验证是否存在名称中包含 foxes 字符串的容器。由于 any
和 all
块被评估为 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 涵盖了有关支持的持续时间字符串的完整详细信息。
GreaterThan
、GreaterThanOrEquals
、LessThan
和 LessThanOrEquals
操作符也可用于 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"]