Finally, we get to test this admission controller.
Let's create two namespaces:
kubectl create namespace ns-with-validation
kubectl create namespace ns-free
And add the label we specified in our webhook to activate our Admission controller in the namespace we want to impose a limit to the number of replicas ns-with-validation
:
kubectl label namespace ns-with-validation k8s-admission-demo.kubernetes.io/assert-deployment-more-than-one-replicas=true
Creating a one-replica deployment in the free namespace is ok:
# kubectl create deployment one-replica -n ns-free --image nginx --replicas=1
deployment.apps/one-replica created
Creating a one-replica deployment in the limited namespace is not ok:
# kubectl create deployment one-replica -n ns-with-validation --image nginx --replicas=1
error: failed to create deployment: admission webhook "k8s-admission-demo.kubernetes.io" denied the request: Minimum number of replicas for a deployment is 2!
Creating a two-replica deployment in the limited namespace is ok:
# kubectl create deployment two-replica -n ns-with-validation --image nginx --replicas=2
deployment.apps/two-replica created
I had several issues during this creation. Here are they and an explanation of what went wrong:
# kubectl create deployment one-replica -n ns-with-validation --image nginx --replicas=1
error: failed to create deployment: Internal error occurred: failed calling webhook "k8s-admission-demo.kubernetes.io": failed to call webhook: Post "https://k8s-admission-demo.default.svc:443/validate?timeout=10s": x509: certificate relies on legacy Common Name field, use SANs instead
Solution: Recreate certificate with SAN and redeploy
# kubectl create deployment one-replica -n ns-with-validation --image nginx --replicas=1
error: failed to create deployment: Internal error occurred: failed calling webhook "k8s-admission-demo.kubernetes.io": failed to call webhook: Post "https://k8s-admission-demo.default.svc:443/validate?timeout=10s": dial tcp 192.166.0.141:443: connect: connection refused
Solution: Make sure deployment is running
# kubectl create deployment one-replica -n ns-with-validation --image nginx --replicas=1
error: failed to create deployment: Internal error occurred: failed calling webhook "k8s-admission-demo.kubernetes.io": failed to call webhook: Post "https://admission-demo.default.svc:443/validate?timeout=10s": x509: certificate is not valid for any names, but wanted to match admission-demo.default.svc
Solution: Make sure CN and SAN match the service name
error: failed to create deployment: Internal error occurred: failed calling webhook "k8s-admission-demo.kubernetes.io": received invalid webhook response: expected response.uid="854e0949-c8cb-4cd8-8d5b-93608934f9d8", got ""
Solution: If you don't specify a failure Policy to ignore you can't just return an empty response for a valid response. Make sure you return a valid AdmissionReview response with Response.allowed equals to true.
error: failed to create deployment: Internal error occurred: failed calling webhook "k8s-admission-demo.kubernetes.io": received invalid webhook response: expected webhook response of admission.k8s.io/v1, Kind=AdmissionReview, got /, Kind=
Solution: In v1 AdmissionReview there is additional validation to make sure the Response and Request metadata match.