Webhook admission plugins allow for mutation and validation of any resource on any API server, so the possible applications are vast. Some common use-cases include:
1. Mutation of resources like pods. Istio has talked about doing this to inject side-car containers into pods. You could also write a plugin which forcefully resolves image tags into image SHAs.
2. Name restrictions. On multi-tenant systems, reserving namespaces has emerged as a use-case.
3. Complex CustomResource validation. Because the entire object is visible, a clever admission plugin can perform complex validation on dependent fields (A requires B) and even external resources (compare to LimitRanges).
4. Security response. If you forced image tags into image SHAs, you could write an admission plugin that prevents certain SHAs from running.
### Registration
Webhook admission plugins of both types are registered in the API, and all API servers (kube-apiserver and all extension API servers) share a common config for them. During the registration process, a webhook admission plugin describes:
1. How to connect to the webhook admission server
2. How to verify the webhook admission server (Is it really the server I expect?)
3. Where to send the data at that server (which URL path)
4. Which resources and which HTTP verbs it will handle
5. What an API server should do on connection failures (for example, if the admission webhook server goes down)
```
1 apiVersion: admissionregistration.k8s.io/v1beta1
2 kind: ValidatingWebhookConfiguration
3 metadata:
4 name: namespacereservations.admission.online.openshift.io
5 webhooks:
6 - name: namespacereservations.admission.online.openshift.io
7 clientConfig:
8 service:
9 namespace: default
10 name: kubernetes
11 path: /apis/admission.online.openshift.io/v1alpha1/namespacereservations
12 caBundle: KUBE\_CA\_HERE
13 rules:
14 - operations:
15 - CREATE
16 apiGroups:
17 - ""
18 apiVersions:
19 - "\*"
20 resources:
21 - namespaces
22 failurePolicy: Fail
```
Line 6: `name` - the name for the webhook itself. For mutating webhooks, these are sorted to provide ordering.
Line 7: `clientConfig` - provides information about how to connect to, trust, and send data to the webhook admission server.
Line 13: `rules` - describe when an API server should call this admission plugin. In this case, only for creates of namespaces. You can specify any resource here so specifying creates of `serviceinstances.servicecatalog.k8s.io` is also legal.
Line 22: `failurePolicy` - says what to do if the webhook admission server is unavailable. Choices are “Ignore” (fail open) or “Fail” (fail closed). Failing open makes for unpredictable behavior for all clients.
### Authentication and trust
Because webhook admission plugins have a lot of power (remember, they get to see the API resource content of any request sent to them and might modify them for mutating plugins), it is important to consider:
- How individual API servers verify their connection to the webhook admission server
- How the webhook admission server authenticates precisely which API server is contacting it
- Whether that particular API server has authorization to make the request
There are three major categories of connection:
1. From kube-apiserver or extension-apiservers to externally hosted admission webhooks (webhooks not hosted in the cluster)
2. From kube-apiserver to self-hosted admission webhooks
3. From extension-apiservers to self-hosted admission webhooks
To support these categories, the webhook admission plugins accept a kubeconfig file which describes how to connect to individual servers. For interacting with externally hosted admission webhooks, there is really no alternative to configuring that file manually since the authentication/authorization and access paths are owned by the server you’re hooking to.
For the self-hosted category, a cleverly built webhook admission server and topology can take advantage of the safe defaulting built into the admission plugin and have a secure, portable, zero-config topology that works from any API server.