An admission webhook that prevents the creation of specified namespaces
Installation on Kubernetes 1.9+
- make sure to have at least Kubernetes 1.9, kubectl is working and that jq is installed
- clone this repo
make build-image push-image REPO=<your-docker-username>/namespace-reservation-server
- adapt the namespace-reservation-server image in artifacts/kube-install/apiserver-list.yaml.template to your chosen Docker REPO.
hack/install-kube.sh, compare install-kube.sh
Then test the setup:
kubectl create -f artifacts/example/reserve-deads.yamlwill reserve the
deadsnamespace, compare reserve-deads.yaml.
kubectl create namespace deadsshould produce "Error from server (Forbidden): "deads" is reserved"
The webhook is deployed as DaemonSet
server in the namespace
a real cluster this is to be restricted to the master nodes. The server pods get a TLS key and cert
injected by the secret
server-serving-cert, self-signed by a local CA.
In front of the DaemonSet pods is a service named
server in the same namespace.
The webhook is an API server itself. An APIService object named
the API group
v1beta1.admission.online.openshift.io/v1beta1 available within and outside of the cluster via
API aggregation of kube-apiserver. The group can be reached at
of the kube-apiserver, i.e. via the
kubernetes.default.svc service hostname inside the
There are numerous advantages to registering the webhook server as an aggregated API:
- allows other kubernetes components to talk to the the admission webhook using the
- allows other kubernetes components to use their in-cluster credentials to communicate with the webhook
- allows you to test the webhook using kubectl
- allows you to govern access to the webhook using RBAC
- prevents other extension API servers from leaking their service account tokens to the webhook
For more information, see: https://kubernetes.io/blog/2018/01/extensible-admission-is-beta
The admission webhook is registered via a
ValidatingWebhookConfiguration object. The webhook URL used
for admission requests is https://kubernetes.default.svc/apis/admission.online.openshift.io/v1beta1/namespacereservations,
i.e. the kube-apiserver sends admission requests to itself. They are forwarded by the aggregator proxy code
to the actual webhook service and finally reach the webhook server.
- kube-apiserver trusts itself under https://kubernetes.default.svc because the kube-apiserver CA cert
is part of the
ValidatingWebhookConfigurationobject in the
- kube-apiserver trusts https://server.openshift-namespace-reservation.svc because the local CA cert
is part of the APIService object as field
SERVICE_SERVING_CERT_CAin artifacts/kube-install/apiserver-list.yaml.template), therefore trusted by kube-apiserver and the webhook server answers with its server cert which is signed by that local CA.
- the webhook server trusts the admission requests from the kube-apiserver because
- it finds the
extension-apiserver-authenticationaConfigMap in the
- which includes a CA cert of the kube-apiserver that the request's client cert is signed with.
- it finds the