Admission Webhook Kubernetes

Kubernetes admission webhooks are a powerful mechanism for customizing and controlling the behavior of your Kubernetes cluster at runtime. By intercepting requests to the Kubernetes API server, admission webhooks allow you to validate, mutate, or even reject operations like pod creation, service modifications, and more. Whether you're enforcing security policies, applying default configurations, or ensuring compliance with custom standards, admission webhooks give you the flexibility to tailor your Kubernetes environment to your organization’s needs. In this article, we’ll explore how to set up and leverage Kubernetes admission webhooks to enhance your cluster management.

Generate Certificates

Generating certificates is the most important step in creating your own custom admission controller. This allows the Kubernetes control plane to trust your web server. If the certificate is not trusted by Kubernetes the webhook calls will fail. I like to use Cloudflare's cfssl tool to generate these.

We can generate the CA certs with the below command.

cfssl gencert -initca ./deployment/ca-csr.json | cfssljson -bare ./certs/ca

Now we can generate the certificates.

cfssl gencert \
  -ca=./certs/ca.pem \
  -ca-key=./certs/ca-key.pem \
  -config=./deployment/ca-config.json \
  -hostname="harrison-admission.default.svc" \
  -profile=default \
  ./deployment/ca-csr.json | cfssljson -bare ./certs/harrison-admission

We will want to import the secrets into kubernetes. This will allow Kubernetes to know what certificates to trust.

kubectl create secret tls admission \
        --cert "./certs/harrison-admission.pem" \
        --key "./certs/harrison-admission-key.pem"

Install Webhooks

What makes this work is the MutatingWebhookConfiguration manifest. This tells Kubernetes that there is a web admission webhook along with the requirements for it to send. One of the requirements could be in a particular namespace. One feature could be any deployments that are deployed to a particular namespace needs an password injected into the environment variables, or a sidecar started along with it.

The below configuration tells Kubernetes to trigger the webhook when the namespace has a label of admission-webhook: enabled.

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: harrison-webhook
webhooks:
  - name: harrison-admission.default.svc
    admissionReviewVersions:
      - "v1beta1"
    sideEffects: "None"
    timeoutSeconds: 30
    # objectSelector:
    #   matchLabels:
    #     admission-webhook: enabled
    namespaceSelector:
      matchLabels:
        admission-webhook: enabled    
    clientConfig:
      service:
        name: harrison-admission
        namespace: default
        path: "/mutate"
      caBundle: "${CA_BUNDLE}"
    rules:
      - operations: [ "CREATE", "UPDATE", "DELETE" ]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]

Remember to replace the ${CA_bundle} with the CA certs that you generated in the first steps. This can easily be accomplished by the following command:

CA_BUNDLE=$(cat certs/ca.pem | base64 | tr -d '\n')
sed -e 's@${CA_BUNDLE}@'"$CA_BUNDLE"'@g' <"deployment/webhooks.yaml" | kubectl apply -f -

The webhook must accept request to /mutate as specified in the MutatingWebhookConfiguration. I have created sample code and pushed to github. Click Here

In the next post, we’ll dive deeper into the webhook’s internal logic and demonstrate how to customize it for specific use cases

References

Certificate Generation Software CFSSL

Addmission Webhooks

My Example Repo