變更性准入政策
Kubernetes v1.32 [alpha]
本頁面概述 MutatingAdmissionPolicies。
什麼是 MutatingAdmissionPolicies?
變更性准入政策提供了一種宣告式、程序內的方式,來替代變更性准入 Webhook。
變更性准入政策使用通用表達式語言 (CEL) 來宣告對資源的變更。變更可以使用套用組態來定義,該組態使用伺服器端套用合併策略合併,或者使用 JSON 補丁。
可變更的准入政策具有高度可配置性,使政策作者能夠定義可參數化並根據叢集管理員的需求將範圍限定於資源的政策。
構成政策的資源有哪些
一個政策通常由三個資源組成
MutatingAdmissionPolicy 描述了政策的抽象邏輯(可以這樣理解:「此政策將特定標籤設定為特定值」)。
參數資源 向 MutatingAdmissionPolicy 提供資訊,使其成為具體的陳述(可以這樣理解:「將
owner
標籤設定為類似company.example.com
的內容」)。參數資源參照 Kubernetes 資源,這些資源在 Kubernetes API 中可用。它們可以是內建類型或擴充功能,例如 CustomResourceDefinition (CRD)。例如,你可以使用 ConfigMap 作為參數。MutatingAdmissionPolicyBinding 將上述資源(MutatingAdmissionPolicy 和參數)連結在一起,並提供範圍界定。如果你只想為
Pods
設定owner
標籤,而不是其他 API 種類,則可以在繫結中指定此變更。
至少必須定義一個 MutatingAdmissionPolicy 和一個對應的 MutatingAdmissionPolicyBinding,政策才能生效。
如果 MutatingAdmissionPolicy 不需要透過參數進行配置,只需將 MutatingAdmissionPolicy 中的 spec.paramKind
留空即可。
MutatingAdmissionPolicies 入門
可變更的准入政策是叢集控制平面的組成部分。你在編寫和部署它們時應格外謹慎。以下說明如何快速試驗可變更的准入政策。
建立 MutatingAdmissionPolicy
以下是 MutatingAdmissionPolicy 的範例。此政策會變更新建立的 Pod,使其在不存在 sidecar 容器的情況下新增一個。
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: MutatingAdmissionPolicy
metadata:
name: "sidecar-policy.example.com"
spec:
paramKind:
kind: Sidecar
apiVersion: mutations.example.com/v1
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
matchConditions:
- name: does-not-already-have-sidecar
expression: "!object.spec.initContainers.exists(ic, ic.name == \"mesh-proxy\")"
failurePolicy: Fail
reinvocationPolicy: IfNeeded
mutations:
- patchType: "ApplyConfiguration"
applyConfiguration:
expression: >
Object{
spec: Object.spec{
initContainers: [
Object.spec.initContainers{
name: "mesh-proxy",
image: "mesh/proxy:v1.0.0",
args: ["proxy", "sidecar"],
restartPolicy: "Always"
}
]
}
}
.spec.mutations
欄位包含一個表示式列表,這些表示式評估為資源修補程式。發出的修補程式可以是套用配置或 JSON Patch 修補程式。你不能指定一個空的 mutations 列表。在評估所有表示式後,API 伺服器會將這些變更套用到正在通過准入的資源。
若要配置可變更的准入政策以在叢集中使用,則需要繫結。僅當存在具有參照的 spec.policyName
與政策的 spec.name
相符的對應繫結時,MutatingAdmissionPolicy 才會處於活動狀態。
一旦建立繫結和政策,任何符合政策的 spec.matchConditions
的資源請求都將觸發定義的變更集。
在上面的範例中,建立 Pod 將新增 mesh-proxy
initContainer 變更
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: default
spec:
...
initContainers:
- name: mesh-proxy
image: mesh/proxy:v1.0.0
args: ["proxy", "sidecar"]
restartPolicy: Always
- name: myapp-initializer
image: example/initializer:v1.0.0
...
參數資源
參數資源允許政策配置與其定義分開。政策可以定義 paramKind
,它概述了參數資源的 GVK,然後政策繫結透過名稱(透過 policyName
)將政策繫結到特定的參數資源(透過 paramRef
)。
請參閱 參數資源 以取得更多資訊。
ApplyConfiguration
MutatingAdmissionPolicy 表示式始終是 CEL。每個套用配置 expression
必須評估為 CEL 物件(使用 Object()
初始化宣告)。
套用配置可能不會修改原子結構、映射或陣列,因為存在意外刪除未包含在套用配置中的值的風險。
CEL 表示式可以存取建立套用配置所需的物件類型
Object
- 資源物件的 CEL 類型。Object.<fieldName>
- 物件欄位的 CEL 類型(例如Object.spec
)Object.<fieldName1>.<fieldName2>...<fieldNameN>
- 巢狀欄位的 CEL 類型(例如Object.spec.containers
)
CEL 表示式可以存取 API 請求的內容,這些內容組織成 CEL 變數以及其他一些有用的變數
object
- 來自傳入請求的物件。對於 DELETE 請求,值為 null。oldObject
- 現有物件。對於 CREATE 請求,值為 null。request
- API 請求的屬性。params
- 由正在評估的政策繫結參照的參數資源。僅當政策具有 ParamKind 時才會填入。namespaceObject
- 傳入物件所屬的命名空間物件。對於叢集範圍的資源,值為 null。variables
- 組合變數的映射,從其名稱到其延遲評估的值。例如,名為foo
的變數可以作為variables.foo
存取。authorizer
- CEL Authorizer。可用於對請求的主體(使用者或服務帳戶)執行授權檢查。請參閱 https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authzauthorizer.requestResource
- 從authorizer
建構並使用請求資源配置的 CEL ResourceCheck。
apiVersion
、kind
、metadata.name
、metadata.generateName
和 metadata.labels
始終可以從根目錄存取
物件。無法存取其他中繼資料屬性。
JSONPatch
相同的變更可以寫成 JSON Patch,如下所示
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: MutatingAdmissionPolicy
metadata:
name: "sidecar-policy.example.com"
spec:
paramKind:
kind: Sidecar
apiVersion: mutations.example.com/v1
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
matchConditions:
- name: does-not-already-have-sidecar
expression: "!object.spec.initContainers.exists(ic, ic.name == \"mesh-proxy\")"
failurePolicy: Fail
reinvocationPolicy: IfNeeded
mutations:
- patchType: "JSONPatch"
jsonPatch:
expression: >
[
JSONPatch{
op: "add", path: "/spec/initContainers/-",
value: Object.spec.initContainers{
name: "mesh-proxy",
image: "mesh-proxy/v1.0.0",
restartPolicy: "Always"
}
}
]
表示式將由 CEL 評估以建立 JSON patch。參考:https://github.com/google/cel-spec
每個評估的 expression
必須傳回 JSONPatch
值的陣列。JSONPatch
類型代表 JSON patch 中的一個操作。
例如,此 CEL 表示式傳回一個 JSON patch 以有條件地修改值
[
JSONPatch{op: "test", path: "/spec/example", value: "Red"},
JSONPatch{op: "replace", path: "/spec/example", value: "Green"}
]
若要為 patch 操作 value
定義 JSON 物件,請使用 CEL Object
類型。例如
[
JSONPatch{
op: "add",
path: "/spec/selector",
value: Object.spec.selector{matchLabels: {"environment": "test"}}
}
]
若要使用包含 '/' 和 '~' 的字串作為 JSONPatch 路徑鍵,請使用 jsonpatch.escapeKey()
。例如
[
JSONPatch{
op: "add",
path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"),
value: "test"
},
]
CEL 表示式可以存取建立 JSON patch 和物件所需的類型
JSONPatch
- JSON Patch 操作的 CEL 類型。JSONPatch 具有欄位op
、from
、path
和value
。有關更多詳細資訊,請參閱 JSON patch。value
欄位可以設定為以下任何一項:字串、整數、陣列、映射或物件。如果設定,則path
和from
欄位必須設定為 JSON 指標 字串,其中可以使用jsonpatch.escapeKey()
CEL 函數來跳脫包含/
和~
的路徑鍵。Object
- 資源物件的 CEL 類型。Object.<fieldName>
- 物件欄位的 CEL 類型(例如Object.spec
)Object.<fieldName1>.<fieldName2>...<fieldNameN>
- 巢狀欄位的 CEL 類型(例如Object.spec.containers
)
CEL 表示式可以存取 API 請求的內容,這些內容組織成 CEL 變數以及其他一些有用的變數
object
- 來自傳入請求的物件。對於 DELETE 請求,值為 null。oldObject
- 現有物件。對於 CREATE 請求,值為 null。request
- API 請求的屬性。params
- 由正在評估的政策繫結參照的參數資源。僅當政策具有 ParamKind 時才會填入。namespaceObject
- 傳入物件所屬的命名空間物件。對於叢集範圍的資源,值為 null。variables
- 組合變數的映射,從其名稱到其延遲評估的值。例如,名為foo
的變數可以作為variables.foo
存取。authorizer
- CEL Authorizer。可用於對請求的主體(使用者或服務帳戶)執行授權檢查。請參閱 https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authzauthorizer.requestResource
- 從authorizer
建構並使用請求資源配置的 CEL ResourceCheck。
CEL 表示式可以存取 Kubernetes CEL 函數庫 以及
jsonpatch.escapeKey
- 執行 JSONPatch 金鑰跳脫。~
和/
分別跳脫為~0
和~1
。
僅可存取 [a-zA-Z_.-/][a-zA-Z0-9_.-/]*
形式的屬性名稱。