變更性准入政策

功能狀態: 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#Authz
  • authorizer.requestResource - 從 authorizer 建構並使用請求資源配置的 CEL ResourceCheck。

apiVersionkindmetadata.namemetadata.generateNamemetadata.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 具有欄位 opfrompathvalue。有關更多詳細資訊,請參閱 JSON patchvalue 欄位可以設定為以下任何一項:字串、整數、陣列、映射或物件。如果設定,則 pathfrom 欄位必須設定為 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#Authz
  • authorizer.requestResource - 從 authorizer 建構並使用請求資源配置的 CEL ResourceCheck。

CEL 表示式可以存取 Kubernetes CEL 函數庫 以及

  • jsonpatch.escapeKey - 執行 JSONPatch 金鑰跳脫。~/ 分別跳脫為 ~0~1

僅可存取 [a-zA-Z_.-/][a-zA-Z0-9_.-/]* 形式的屬性名稱。

上次修改時間:2024 年 11 月 26 日下午 1:20 PST:KEP-3962:Mutating admission policy documentation (#48646) (cb8e5a7ce5)