基于變量控制策略規則的執行。
前置條件允許通過基于變量值構建表達式來控制策略規則的執行。
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"]