In addition to the default admission controllers, you can use admission webhooks as part of the admission chain.
Admission webhooks call webhook servers to either mutate pods upon creation, such as to inject labels, or to validate specific aspects of the pod configuration during the admission process.
Admission webhooks intercept requests to the master API prior to the persistence of a resource, but after the request is authenticated and authorized.
In OpenShift Container Platform you can use admission webhook objects that call webhook servers during the API admission chain.
There are two types of admission webhook objects you can configure:
Mutating admission webhooks allow for the use of mutating webhooks to modify resource content before it is persisted.
Validating admission webhooks allow for the use of validating webhooks to enforce custom admission policies.
Configuring the webhooks and external webhook servers is beyond the scope of this document. However, the webhooks must adhere to an interface in order to work properly with OpenShift Container Platform.
Admission webhooks is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs), might not be functionally complete, and Red Hat does not recommend to use them for production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process. For more information on Red Hat Technology Preview features support scope, see https://access.redhat.com/support/offerings/techpreview/. |
When an object is instantiated, OpenShift Container Platform makes an API call to admit the object. During the admission process, a mutating admission controller can invoke webhooks to perform tasks, such as injecting affinity labels. At the end of the admissions process, a validating admission controller can invoke webhooks to make sure the object is configured properly, such as verifying affinity labels. If the validation passes, OpenShift Container Platform schedules the object as configured.
When the API request comes in, the mutating or validating admission controller uses the list of external webhooks in the configuration and calls them in parallel:
If all of the webhooks approve the request, the admission chain continues.
If any of the webhooks deny the request, the admission request is denied, and the reason for doing so is based on the first webhook denial reason.
If more than one webhook denies the admission request, only the first will be returned to the user.
If there is an error encountered when calling a webhook, that request is either denied or the webhook is ignored.
The communication between the admission controller and the webhook server needs to be secured using TLS. Generate a CA certificate and use the certificate to sign the server certificate used by your webhook server. The PEM-formatted CA certificate is supplied to the admission controller using a mechanism, such as Service Serving Certificate Secrets.
The following diagram illustrates this process with two admission webhooks that call multiple webhooks.
A simple example use case for admission webhooks is syntactical validation of resources. For example, you have an infrastructure that requires all pods to have a common set of labels, and you do not want any pod to be persisted if the pod does not have those labels. You could write a webhook to inject these labels and another webhook to verify that the labels are present. The OpenShift Container Platform will then schedule pod that have the labels and pass validation and reject pods that do not pass due to missing labels.
Some common use-cases include:
Mutating resources to inject side-car containers into pods.
Restricting projects to block some resources from a project.
Custom resource validation to perform complex validation on dependent fields.
Cluster administrators can include mutating admission webhooks or validating admission webhooks in the admission chain of the API server.
Mutating admission webhooks are invoked during the mutation phase of the admission process, which allows modification of the resource content before it is persisted. One example of a mutating admission webhook is the Pod Node Selector feature, which uses an annotation on a namespace to find a label selector and add it to the pod specification.
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration (1)
metadata:
name: <controller_name> (2)
webhooks:
- name: <webhook_name> (3)
clientConfig: (4)
service:
namespace: (5)
name: (6)
path: <webhook_url> (7)
caBundle: <cert> (8)
rules: (9)
- operations: (10)
- <operation>
apiGroups:
- ""
apiVersions:
- "*"
resources:
- <resource>
failurePolicy: <policy> (11)
1 | Specifies a mutating admission webhook configuration. |
2 | The name for the admission webhook object. |
3 | The name of the webhook to call. |
4 | Information about how to connect to, trust, and send data to the webhook server. |
5 | The project where the front-end service is created. |
6 | The name of the front-end service. |
7 | The webhook URL used for admission requests. |
8 | A PEM-encoded CA certificate that signs the server certificate used by the webhook server. |
9 | Rules that define when the API server should use this controller. |
10 | The operation(s) that triggers the API server to call this controller:
|
11 | Specifies how the policy should proceed if the webhook admission server is unavailable.
Either Ignore (allow/fail open) or Fail (block/fail closed). |
Validating admission webhooks are invoked during the validation phase of the admission process.
This phase allows the enforcement of invariants on particular API resources
to ensure that the resource does not change again. The Pod Node Selector is also an example of a validation admission,
by ensuring that all nodeSelector
fields are constrained by the node selector restrictions on the project.
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration (1)
metadata:
name: <controller_name> (2)
webhooks:
- name: <webhook_name> (3)
clientConfig: (4)
service:
namespace: default (5)
name: kubernetes (6)
path: <webhook_url> (7)
caBundle: <cert> (8)
rules: (9)
- operations: (10)
- <operation>
apiGroups:
- ""
apiVersions:
- "*"
resources:
- <resource>
failurePolicy: <policy> (11)
1 | Specifies a validating admission webhook configuration. |
2 | The name for the webhook admission object. |
3 | The name of the webhook to call. |
4 | Information about how to connect to, trust, and send data to the webhook server. |
5 | The project where the front-end service is created. |
6 | The name of the front-end service. |
7 | The webhook URL used for admission requests. |
8 | A PEM-encoded CA certificate that signs the server certificate used by the webhook server. |
9 | Rules that define when the API server should use this controller. |
10 | The operation that triggers the API server to call this controller.
|
11 | Specifies how the policy should proceed if the webhook admission server is unavailable.
Either Ignore (allow/fail open) or Fail (block/fail closed). |
Fail open can result in unpredictable behavior for all clients. |
First deploy the external webhook server and ensure
it is working properly. Otherwise, depending whether the webhook is configured as fail open
or
fail closed
, operations will be unconditionally accepted or rejected.
Configure a mutating or validating admission webhook object in a YAML file.
Run the following command to create the object:
$ oc create -f <file-name>.yaml
After you create the admission webhook object, OpenShift Container Platform takes a few seconds to honor the new configuration.
Create a front-end service for the admission webhook:
apiVersion: v1
kind: Service
metadata:
labels:
role: webhook (1)
name: <name>
spec:
selector:
role: webhook (1)
1 | Free-form label to trigger the webhook. |
Run the following command to create the object:
$ oc create -f <file-name>.yaml
Add the admission webhook name to pods you want controlled by the webhook:
apiVersion: v1
kind: Pod
metadata:
labels:
role: webhook (1)
name: <name>
spec:
containers:
- name: <name>
image: myrepo/myimage:latest
imagePullPolicy: <policy>
ports:
- containerPort: 8000
1 | Label to trigger the webhook. |
See the kubernetes-namespace-reservation projects for an end-to-end example of how to build your own secure and portable webhook admission server and generic-admission-apiserver for the library. |
The following is an example admission webhook that will not allow namespace creation if the namespace is reserved:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: namespacereservations.admission.online.openshift.io
webhooks:
- name: namespacereservations.admission.online.openshift.io
clientConfig:
service:
namespace: default
name: webhooks
path: /apis/admission.online.openshift.io/v1beta1/namespacereservations
caBundle: KUBE_CA_HERE
rules:
- operations:
- CREATE
apiGroups:
- ""
apiVersions:
- "b1"
resources:
- namespaces
failurePolicy: Ignore
The following is an example pod that will be evaluated by the admission webhook named webhook:
apiVersion: v1
kind: Pod
metadata:
labels:
role: webhook
name: webhook
spec:
containers:
- name: webhook
image: myrepo/myimage:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
The following is the front-end service for the webhook:
apiVersion: v1
kind: Service
metadata:
labels:
role: webhook
name: webhook
spec:
ports:
- port: 443
targetPort: 8000
selector:
role: webhook