The admission controller has been removed in favor of the declarative validation admission policies
This proposal is to add support for admission controllers in Rook. An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized
There are two special controllers: MutatingAdmissionWebhook and ValidatingAdmissionWebhook.
Mutating controllers may modify the objects they admit but validation controllers are only allowed to validate requests.
Currently, user can manipulate Custom Resource specs with any values which may result in Rook not functioning as expected. The present validation method in Kubernetes is the OpenAPI schema validation which can be used for basic validations like checking type of data, providing a range for the values etc but anything more complex (checking resource availability, network status, error handling) would not be possible under this scenario.
As shown in the above diagram, the admission control process proceeds in two phases. In the first phase, mutating admission controllers are run. In the second phase, validating admission controllers are run. Note again that some of the controllers are both.
The admission controllers intercept requests based on the values given in the configuration. In this config, we have to provide the details on
A webhook server should be in place (with valid TLS certificates) to intercept any HTTPs request that comes with the above path value. Once the request is intercepted by the server, an AdmissionRequest object is sent through with the resource specifications.
When the webhook server receives Admission Request, it will perform predefined validations on the provided resource values and send back an AdmissionResponse with the indication whether request is accepted or rejected.
If any of the controllers in either phase reject the request, the entire request is rejected immediately and an error is returned to the end-user.
We can use self-signed certificates approved by the Kubernetes Certificate Authority for development purposes.This can be done by following the steps given below.
Sample : Generating the public and private keys
openssl genrsa -out ${PRIVATE_KEY_NAME}.pem 2048
openssl req -new -key ${PRIVATE_KEY_NAME}.pem -subj "/CN=${service}.${namespace}.svc"
#Created after CSR is approved
openssl base64 -d -A -out ${PUBLIC_KEY_NAME}.pem
Sample : Certificate Signing Request (CSR) in Kubernetes
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: ${csrName}
spec:
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
Verify with
kubectl get csr ${csrName}
Sample : Approval of Signed Certificate
kubectl certificate approve ${csrName}
If it is approved, then we can check the certificate with following command
$(kubectl get csr ${csrName} -o jsonpath='{.status.certificate}')
Sample : Creating a Secret in Kubernetes
kubectl create secret generic ${secret} \
--from-file=key.pem=${PRIVATE_KEY_NAME}.pem \
--from-file=cert.pem=${PUBLIC_KEY_NAME}.pem
Using the above approach, the dev/admins will have the responsibility of rotating the certificates when they expire.
Below is an excerpt of what a ValidatingWebhookConfig looks like
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: demo-webhook
webhooks:
- name: webhook-server.webhook-demo.svc
clientConfig:
service:
name: webhook-server
namespace: rook-ceph
path: "/validate"
caBundle: ${CA_PEM_B64}
rules:
- operations: [ "CREATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
We can make changes to the above values according to intercept based on whether a resource is being updated/deleted/created or change the type of resource or the request path which will be sent to the server.
Based on the whether the secrets are present, the rook operator will deploy the relevant configuration files onto the cluster and start the server.
The secrets will be volume mounted on the rook operator pod dynamically when they are detected. After the volumes are mounted, an HTTPs server would be started.
Once the server starts, it will look for the appropriate tls key and crt files in the mounted volumes and start intercepting requests based on the path set in ValidatingWebhookConfig.
If the server is unable to find valid certificates, It will not deploy any admission controller components onto the cluster and hence rook will continue to function normally as before.