本頁面說明如何使用 Policy Controller 變動資源。這項功能可用於設定預設值等作業。舉例來說,您可能想為特定命名空間中的所有資源插入標籤,或將 Pod 的 imagePullPolicy
預設為 Always
(如果尚未設定)。
啟用突變
控制台
如要啟用突變,請完成下列步驟:
- 在 Google Cloud 控制台中,前往「Posture Management」(狀態管理) 專區下方的 GKE Enterprise「Policy」(政策) 頁面。
- 在「設定」分頁的叢集表格中,選取「編輯設定」欄中的「編輯」edit。
- 展開「編輯 Policy Controller 設定」選單。
- 勾選「Enable mutation webhook」(啟用異動 Webhook) 核取方塊。
- 選取「儲存變更」。
gcloud
如要啟用突變,請執行下列指令:
gcloud container fleet policycontroller update \
--memberships=MEMBERSHIP_NAME \
--mutation
將 MEMBERSHIP_NAME
替換為已註冊叢集的成員資格名稱,以啟用變動。你可以指定多個會員方案,並以半形逗號分隔。
定義
- 變異器:Kubernetes 資源,可協助設定 Policy Controller 的變異行為。
- 系統:多個突變器的排列方式
突變範例
以下範例顯示的突變器會將所有 Pod 中所有容器的 imagePullPolicy
設為 Always
:
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
assign:
value: "Always"
在這個範例中,有標準的 Kubernetes 中繼資料欄位 (apiVersion
、kind
、metadata.name
),但 spec
是設定突變器行為的位置。
spec.applyTo
會將變異器繫結至指定資源。由於我們要變更物件中的特定欄位,因此會隱含定義該物件的結構定義。舉例來說,如果將目前的變異子套用至 Namespace
資源,就毫無意義。因此,這個欄位為必填,Policy Controller 才能瞭解這個突變器適用的結構定義。這份清單中缺少的 GroupVersionKinds
不會發生突變。
spec.location
告訴我們要修改哪個欄位。在本例中,我們使用 glob (*
) 表示要修改容器清單中的所有項目。請注意,location
欄位可能遍歷的清單類型只有地圖類型清單,且必須指定地圖的鍵欄位。對應型清單是 Kubernetes 建構體。如要進一步瞭解這些項目,請參閱 Kubernetes 的說明文件。
spec.parameters.assign.value
是要指派給 location
的值。這個欄位沒有型別,可以接受任何值,但請注意,Kubernetes 仍會在變動後驗證要求,因此如果插入的值與要修改的物件架構不符,要求就會遭到拒絕。
使用工作變異子
如果您要設定 Job 或 CronJob,必須分別指定版本和群組,如下例所示:
applyTo:
- groups: ["batch"]
kind: ["Job"]
versions: ["v1"]
使用 Jobs 的變動器時,除非修改現有 Jobs,否則不會變動。修改工作會觸發異動 Webhook 的要求,並導致工作異動。
執行流程
瞭解 Kubernetes 突變 Webhook 最重要的概念,或許就是重新叫用政策,因為一個突變器的輸出內容可能會改變另一個突變器的行為。舉例來說,如果您新增 Sidecar 容器,現在就有新的容器需要變更,因此變更所有容器的映像檔提取政策的突變器,會變更這個新容器。
實際上,這表示對於任何指定要求,系統可能會多次呼叫 Policy Controller 的變動 Webhook。
為減少延遲,Policy Controller 會重新叫用自身,避免額外的 HTTP 要求。這表示附屬容器注入和映像檔提取政策會產生預期結果。
Policy Controller 的突變常式會持續重新叫用自身,直到資源「收斂」為止,也就是說,額外的疊代不會再產生任何影響。
位置語法
位置語法會使用點 (.
) 存取子來遍歷欄位。如果是鍵控清單,使用者可以使用 [<key>: <value>]
語法參照清單中的個別物件,或使用 [<key>: *]
參照清單中的所有物件。
值和欄位可以使用單引號 ('
) 或雙引號 ("
) 括住。如果含有點或空格等特殊字元,就必須使用引號。
在加引號的值中,特殊字元可以加上 \
前置字元來逸出。"Use \" to escape and \\\" to escape"
變成 Use " to escape and \" to escape
。
「v1/Pod
」資源的範例:
spec.priority
參考資料spec.priority
spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnly
參照foo
容器的/my/mount
掛接點的readOnly
欄位。spec.containers[name: *].volumeMounts[mountPath: "/my/mount"].readOnly
參照所有容器的/my/mount
掛接點的readOnly
欄位。
如果您參照資源上目前不存在的位置,系統預設會建立該位置。您可以透過路徑測試設定這項行為。
路徑測試
如何執行預設作業,避免修改現有值?舉例來說,我們可能想將所有容器的 /secure-mount
設為唯讀,但如果容器還沒有 /secure-mount
,我們就不想建立。我們可以透過路徑測試執行其中任一操作。
以下範例說明如何避免在 imagePullPolicy
已設定的情況下突變:
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
assign:
value: "Always"
pathTests:
- subPath: "spec.containers[name: *].imagePullPolicy"
condition: "MustNotExist"
以下是另一個範例,可避免建立空白的 sidecar
容器 (如果該容器不存在):
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: 'spec.containers[name: "sidecar"].imagePullPolicy'
parameters:
assign:
value: "Always"
pathTests:
- subPath: 'spec.containers[name: "sidecar"]'
condition: "MustExist"
如有需要,可以指定多個路徑測試。
subPath
必須是 location
的前置字元 (或等於 location
)。
condition
的有效值只有 MustExist
和 MustNotExist
。
比對
變異器也允許比對,使用的條件與限制相同。
突變子
目前有兩種變動器:Assign
和 AssignMetadata
。
指派
Assign
可以變更資源 metadata
欄位以外的任何值。
由於所有 GroupVersionKinds
都有專屬結構定義,因此必須繫結至一組特定 GroupVersionKinds
。
結構定義如下:
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
kinds: # redundant because of `applyTo`, but left in for consistency
- apiGroups: ["*"]
kinds: ["*"]
namespaces: ["my-namespace"]
scope: "Namespaced" # or "Cluster"
excludedNamespaces: ["some-other-ns"]
labelSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
namespaceSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
pathTests:
- subPath: 'spec.containers[name: "sidecar"]' # must be a prefix of `location`
condition: "MustExist" # or "MustNotExist"
- subPath: "spec.containers[name: *].imagePullPolicy"
condition: "MustNotExist"
assign:
value: "Always" # any type can go here, not just a string
AssignMetadata
AssignMetadata
可以新增中繼資料標籤。但無法變更現有中繼資料標籤的值。否則,系統可能會編寫無限遞迴的變異子,導致要求逾時。
由於所有資源共用相同的 metadata
結構定義,因此不需要指定 AssignMetadata
適用的資源。
此外,由於 AssignMetadata
的功能較少,因此架構也較為簡單。
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: AssignMetadata
metadata:
name: set-team-name
spec:
match:
kinds:
- apiGroups: ["*"]
kinds: ["*"]
namespaces: ["my-namespace"]
scope: "Namespaced" # or "Cluster"
excludedNamespaces: ["some-other-ns"]
labelSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
namespaceSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
location: "metadata.labels.team" # must start with `metadata.labels`
parameters:
assign:
value: "Always" # any type can go here, not just a string
最佳做法
Kubernetes 注意事項
Kubernetes 說明文件列出使用突變 Webhook 時的重要考量。由於 Policy Controller 是以 Kubernetes 准入 Webhook 運作,因此上述建議也適用於此。
Policy Controller 的變異語法旨在簡化變異網路掛鉤的作業問題,包括等冪性。
撰寫 Mutator
完整性
最佳做法是盡可能讓每個變異子都自給自足。由於 Kubernetes 最終會保持一致,因此一個變異器不應依賴第二個變異器來正確執行工作。舉例來說,新增側車時,請新增整個側車,不要使用多個突變子逐一建構。
驗證
如有要強制執行的條件,建議變異器採用相符的限制。這有助於確保系統拒絕違規要求,並在稽核時偵測到先前違規事項。
緊急復原
異動是以 Kubernetes 異動 Webhook 的形式實作。停止方式與驗證 Webhook 相同,但相關資源是名為 gatekeeper-mutating-webhook-configuration
的 MutatingWebhookConfiguration
。
後續步驟
- 如需 Gatekeeper 突變說明和範例,請參閱開放原始碼說明文件