Webhook 配置
要注冊准入 Webhook,請創建 MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration API 對象。
每種配置可以包含一個或多個 Webhook。如果在單個配置中指定了多個 Webhook,則應為每個 webhook 賦予一個唯一的名稱。 這在 admissionregistration.k8s.io/v1 中是必需的,但是在使用 admissionregistration.k8s.io/v1beta1 時強烈建議使用, 以使生成的審核日志和指標更易於與活動配置相匹配。
每個 Webhook 定義以下內容。
匹配請求-規則
每個 webhook 必須指定用於確定是否應將對 apiserver 的請求發送到 webhook 的規則列表。 每個規則都指定一個或多個 operations、apiGroups、apiVersions 和 resources 以及資源的 scope:
operations列出一個或多個要匹配的操作。 可以是CREATE、UPDATE、DELETE、CONNECT或*以匹配所有內容。apiGroups列出了一個或多個要匹配的 API 組。""是核心 API 組。"*"匹配所有 API 組。apiVersions列出了一個或多個要匹配的 API 版本。"*"匹配所有 API 版本。resources列出了一個或多個要匹配的資源。"*"匹配所有資源,但不包括子資源。"*/*"匹配所有資源,包括子資源。"pods/*"匹配 pod 的所有子資源。"*/status"匹配所有 status 子資源。
scope指定要匹配的范圍。有效值為"Cluster"、"Namespaced"和"*"。 子資源匹配其父資源的范圍。在 Kubernetes v1.14+ 版本中才被支持。 默認值為"*",對應 1.14 版本之前的行為。"Cluster"表示只有集群作用域的資源才能匹配此規則(API 對象 Namespace 是集群作用域的)。"Namespaced"意味着僅具有名字空間的資源才符合此規則。"*"表示沒有范圍限制。
如果傳入請求與任何 Webhook 規則的指定操作、組、版本、資源和范圍匹配,則該請求將發送到 Webhook。
以下是可用於指定應攔截哪些資源的規則的其他示例。
匹配針對 apps/v1 和 apps/v1beta1 組中 deployments 和 replicasets 資源的 CREATE 或 UPDATE 請求:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1", "v1beta1"]
resources: ["deployments", "replicasets"]
scope: "Namespaced"
...
匹配所有 API 組和版本中的所有資源(但不包括子資源)的創建請求:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
...
匹配所有 API 組和版本中所有 status 子資源的更新請求:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
rules:
- operations: ["UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*/status"]
scope: "*"
...
匹配請求:objectSelector
在版本 v1.15+ 中, 通過指定 objectSelector,Webhook 能夠根據可能發送的對象的標簽來限制哪些請求被攔截。 如果指定,則將對 objectSelector 和可能發送到 Webhook 的 object 和 oldObject 進行評估。如果兩個對象之一與選擇器匹配,則認為該請求已匹配。
空對象(對於創建操作而言為 oldObject,對於刪除操作而言為 newObject), 或不能帶標簽的對象(例如 DeploymentRollback 或 PodProxyOptions 對象) 被認為不匹配。
僅當選擇使用 webhook 時才使用對象選擇器,因為最終用戶可以通過設置標簽來跳過准入 Webhook。
這個例子展示了一個 mutating webhook,它將匹配帶有標簽 foo:bar 的任何資源的 CREATE 的操作:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
objectSelector:
matchLabels:
foo: bar
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "*"
...
有關標簽選擇器的更多示例,請參見標簽。
匹配請求:namespaceSelector
通過指定 namespaceSelector,Webhook 可以根據具有名字空間的資源所處的名字空間的標簽來選擇攔截哪些資源的操作。
namespaceSelector 根據名字空間的標簽是否匹配選擇器,決定是否針對具名字空間的資源 (或 Namespace 對象)的請求運行 webhook。 如果對象是除 Namespace 以外的集群范圍的資源,則 namespaceSelector 標簽無效。
本例給出的修改性質的 Webhook 將匹配到對名字空間中具名字空間的資源的 CREATE 請求, 前提是這些資源不含值為 "0" 或 "1" 的 "runlevel" 標簽:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
namespaceSelector:
matchExpressions:
- key: runlevel
operator: NotIn
values: ["0","1"]
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "Namespaced"
...
matchExpressions是一個pod的選擇器條件的列表。合法的操作符包含In, NotIn, Exists, and DoesNotExist。在In和NotIn的情況下,值的組必須不能為空。所有的條件,包含 matchLabels and matchExpressions 中的,會用AND符號連接,他們必須都被滿足以完成匹配。
此示例顯示了一個驗證性質的 Webhook,它將匹配到對某名字空間中的任何具名字空間的資源的 CREATE 請求,前提是該名字空間具有值為 "prod" 或 "staging" 的 "environment" 標簽:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
namespaceSelector:
matchExpressions:
- key: environment
operator: In
values: ["prod","staging"]
rules:
- operations: ["CREATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
scope: "Namespaced"
...
有關標簽選擇器的更多示例,請參見 標簽。
匹配請求:matchPolicy
API 服務器可以通過多個 API 組或版本來提供對象。 例如,Kubernetes API 服務器允許通過 extensions/v1beta1、apps/v1beta1、 apps/v1beta2 和 apps/v1 API 創建和修改 Deployment 對象。
例如,如果一個 webhook 僅為某些 API 組/版本指定了規則(例如 apiGroups:["apps"], apiVersions:["v1","v1beta1"]),而修改資源的請求 是通過另一個 API 組/版本(例如 extensions/v1beta1)發出的, 該請求將不會被發送到 Webhook。
在 v1.15+ 中,matchPolicy 允許 webhook 定義如何使用其 rules 匹配傳入的請求。 允許的值為 Exact 或 Equivalent。
Exact表示僅當請求與指定規則完全匹配時才應攔截該請求。Equivalent表示如果某個請求意在修改rules中列出的資源, 即使該請求是通過其他 API 組或版本發起,也應攔截該請求。
在上面給出的示例中,僅為 apps/v1 注冊的 webhook 可以使用 matchPolicy:
matchPolicy: Exact表示不會將extensions/v1beta1請求發送到 WebhookmatchPolicy:Equivalent表示將extensions/v1beta1請求發送到 webhook (將對象轉換為 webhook 指定的版本:apps/v1)
建議指定 Equivalent,確保升級后啟用 API 服務器中資源的新版本時, Webhook 繼續攔截他們期望的資源。
當 API 服務器停止提供某資源時,該資源不再被視為等同於該資源的其他仍在提供服務的版本。 例如,extensions/v1beta1 中的 Deployment 已被廢棄,計划在 v1.16 中默認停止使用。 在這種情況下,帶有 apiGroups:["extensions"], apiVersions:["v1beta1"], resources: ["deployments"] 規則的 Webhook 將不再攔截通過 apps/v1 API 來創建 Deployment 的請求。 ["deployments"] 規則將不再攔截通過 apps/v1 API 創建的部署。
此示例顯示了一個驗證性質的 Webhook,該 Webhook 攔截對 Deployment 的修改(無論 API 組或版本是什么), 始終會發送一個 apps/v1 版本的 Deployment 對象:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
matchPolicy: Equivalent
rules:
- operations: ["CREATE","UPDATE","DELETE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
scope: "Namespaced"
...
使用 admissionregistration.k8s.io/v1 創建的 admission webhhok 默認為 Equivalent。
總結:
可以使用資源過濾器(objectSelector、namespaceSelector)來過濾需要進行修改或驗證的資源,他們必須都被滿足才能完成匹配。例如假設MutatingWebhookConfiguration資源實例同時配置了objectSelector和namespaceSelector這兩個資源過濾器,必須得這兩個資源過濾器過濾條件都滿足,Webhook 才會進行請求攔截。
參考:https://kubernetes.io/zh/docs/reference/access-authn-authz/extensible-admission-controllers/
