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/