Configuring dynamic admission
You can complete high-level steps to configure dynamic admission. These steps extend the admission chain by configuring a webhook admission plugin to call out to a webhook server.
The webhook server is also configured as an aggregated API server. This allows other Red Hat OpenShift Container Platform components to communicate with the webhook that uses internal credentials and facilitates testing that uses the oc command. Additionally, this enables role-based access control (RBAC) into the webhook and prevents token information from other API servers from being disclosed to the webhook.
-
An Red Hat OpenShift Container Platform account with cluster administrator access.
-
The Red Hat OpenShift Container Platform OpenShift CLI (
oc) installed. -
A published webhook server container image.
-
Build a webhook server container image and make it available to the cluster by using an image registry.
-
Create a local CA key and certificate and use them to sign the webhook server’s certificate signing request (CSR).
-
Create a new project for webhook resources:
$ oc new-project my-webhook-namespace-
Note that the webhook server might expect a specific name.
-
-
Define RBAC rules for the aggregated API service in a file called
rbac.yaml:apiVersion: v1 kind: List items: - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: auth-delegator-my-webhook-namespace roleRef: kind: ClusterRole apiGroup: rbac.authorization.k8s.io name: system:auth-delegator subjects: - kind: ServiceAccount namespace: my-webhook-namespace name: server - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: name: system:openshift:online:my-webhook-server rules: - apiGroups: - online.openshift.io resources: - namespacereservations verbs: - get - list - watch - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:openshift:online:my-webhook-requester rules: - apiGroups: - admission.online.openshift.io resources: - namespacereservations verbs: - create - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: my-webhook-server-my-webhook-namespace roleRef: kind: ClusterRole apiGroup: rbac.authorization.k8s.io name: system:openshift:online:my-webhook-server subjects: - kind: ServiceAccount namespace: my-webhook-namespace name: server - apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: kube-system name: extension-server-authentication-reader-my-webhook-namespace roleRef: kind: Role apiGroup: rbac.authorization.k8s.io name: extension-apiserver-authentication-reader subjects: - kind: ServiceAccount namespace: my-webhook-namespace name: server - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: my-cluster-role rules: - apiGroups: - admissionregistration.k8s.io resources: - validatingwebhookconfigurations - mutatingwebhookconfigurations verbs: - get - list - watch - apiGroups: - "" resources: - namespaces verbs: - get - list - watch - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: my-cluster-role roleRef: kind: ClusterRole apiGroup: rbac.authorization.k8s.io name: my-cluster-role subjects: - kind: ServiceAccount namespace: my-webhook-namespace name: serverwhere:
apiVersion: rbac.authorization.k8s.io/v1-
For
ClusterRoleBinding, specifies authentication and authorization metadata to the webhook server API. apiVersion: rbac.authorization.k8s.io/v1-
For
ClusterRole, specifies the webhook server that is allowed access cluster resources. rules.resources-
For
ClusterRole, specifies the location to resources. This example points to thenamespacereservationsresource. apiVersion: rbac.authorization.k8s.io/v1-
For
ClusterRole, specifies the enablement of the aggregated API server to create admission reviews. apiVersion: rbac.authorization.k8s.io/v1-
For
ClusterRoleBinding, specifies the enablement of the webhook server to access cluster resources. apiVersion: rbac.authorization.k8s.io/v1-
For
RoleBinding, specifies role binding to read the configuration for terminating authentication. apiVersion: rbac.authorization.k8s.io/v1-
For
ClusterRole, specifies the default cluster role and cluster role bindings for an aggregated API server.
-
Apply those RBAC rules to the cluster:
$ oc auth reconcile -f rbac.yaml -
Create a YAML file called
webhook-daemonset.yamlthat is used to deploy a webhook as a daemon set server in a namespace:apiVersion: apps/v1 kind: DaemonSet metadata: namespace: my-webhook-namespace name: server labels: server: "true" spec: selector: matchLabels: server: "true" template: metadata: name: server labels: server: "true" spec: serviceAccountName: server containers: - name: my-webhook-container image: <image_registry_username>/<image_path>:<tag> imagePullPolicy: IfNotPresent command: - <container_commands> ports: - containerPort: 8443 volumeMounts: - mountPath: /var/serving-cert name: serving-cert readinessProbe: httpGet: path: /healthz port: 8443 scheme: HTTPS volumes: - name: serving-cert secret: defaultMode: 420 secretName: server-serving-certwhere:
spec.template.spec.name-
Specifies the container name. Note that the webhook server might expect a specific container name.
spec.template.spec.image-
Specifies the path to a webhook server container image. Replace
<image_registry_username>/<image_path>:<tag>with the appropriate value. spec.template.spec.command-
Specifies webhook container run commands. Replace
<container_commands>with the appropriate value. spec.template.spec.ports.containerPort-
Specifies the target port within pods. This example uses port 8443.
spec.template.spec.readinessProbe.port-
Specifies the port used by the readiness probe. This example uses port 8443.
-
Deploy the daemon set:
$ oc apply -f webhook-daemonset.yaml -
Define a secret for the service serving certificate signer, within a YAML file called
webhook-secret.yaml:apiVersion: v1 kind: Secret metadata: namespace: my-webhook-namespace name: server-serving-cert type: kubernetes.io/tls data: tls.crt: <server_certificate> tls.key: <server_key>where:
data.tls.crt-
References the signed webhook server certificate. Replace
<server_certificate>with the appropriate certificate in base64 format. data.tls.key-
References the signed webhook server key. Replace
<server_key>with the appropriate key in base64 format.
-
Create the secret:
$ oc apply -f webhook-secret.yaml -
Define a service account and service, within a YAML file called
webhook-service.yaml:apiVersion: v1 kind: List items: - apiVersion: v1 kind: ServiceAccount metadata: namespace: my-webhook-namespace name: server - apiVersion: v1 kind: Service metadata: namespace: my-webhook-namespace name: server annotations: service.beta.openshift.io/serving-cert-secret-name: server-serving-cert spec: selector: server: "true" ports: - port: 443 targetPort: 8443where:
spec.ports.port-
Specifies the port that the service listens on. This example uses port 443.
spec.ports.targetPort-
Specifies the target port within pods that the service forwards connections to. This example uses port 8443.
-
Expose the webhook server within the cluster:
$ oc apply -f webhook-service.yaml -
Define a custom resource definition for the webhook server, in a file called
webhook-crd.yaml:apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: namespacereservations.online.openshift.io spec: group: online.openshift.io version: v1alpha1 scope: Cluster names: plural: namespacereservations singular: namespacereservation kind: NamespaceReservationwhere:
metadata.name-
Reflects
CustomResourceDefinitionspecvalues and is in the format<plural>.<group>. This example uses thenamespacereservationsresource. spec.group-
Specifies the REST API group name.
spec.version-
Specifies the REST API version name.
spec.scope-
Specifies accepted values are
NamespacedorCluster. spec.names.plural-
Specifies the plural name to be included in URL.
spec.names.singular-
Specifies the alias seen in
ocoutput. spec.names.kind-
Specifies the reference for resource manifests.
-
Apply the custom resource definition:
$ oc apply -f webhook-crd.yaml -
Configure the webhook server also as an aggregated API server, within a file called
webhook-api-service.yaml:apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: name: v1beta1.admission.online.openshift.io spec: caBundle: <ca_signing_certificate> group: admission.online.openshift.io groupPriorityMinimum: 1000 versionPriority: 15 service: name: server namespace: my-webhook-namespace version: v1beta1-
The
spec.caBundlefield specifies a PEM-encoded CA certificate that signs the server certificate. This certificate is used by the webhook server. Replace<ca_signing_certificate>with the appropriate certificate in base64 format.
-
-
Deploy the aggregated API service:
$ oc apply -f webhook-api-service.yaml -
Define the webhook admission plugin configuration within a file called
webhook-config.yaml. This example uses the validating admission plugin: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: kubernetes path: /apis/admission.online.openshift.io/v1beta1/namespacereservations caBundle: <ca_signing_certificate> rules: - operations: - CREATE apiGroups: - project.openshift.io apiVersions: - "*" resources: - projectrequests - operations: - CREATE apiGroups: - "" apiVersions: - "*" resources: - namespaces failurePolicy: Failwhere:
metadata.name-
Specifies the name for the
ValidatingWebhookConfigurationobject. This example uses thenamespacereservationsresource. webhooks.name-
Specifies the name of the webhook to call. This example uses the
namespacereservationsresource. name.clientConfig.service-
Enables access to the webhook server through the aggregated API.
name.clientConfig.service.path-
Specifies the webhook URL used for admission requests. This example uses the
namespacereservationresource. name.clientConfig.caBundle-
Specifies a PEM-encoded CA certificate that signs the server certificate that is used by the webhook server. Replace
<ca_signing_certificate>with the appropriate certificate in base64 format.
-
Deploy the webhook:
$ oc apply -f webhook-config.yaml -
Verify that the webhook is functioning as expected. For example, if you have configured dynamic admission to reserve specific namespaces, confirm that requests to create those namespaces are rejected and that requests to create non-reserved namespaces succeed.