Build Your Own Admission Controllers in Kubernetes Using Go

Admission Control vs RBAC

With role-based access control (RBAC) you can limit access to K8s resources and impose different types of restrictions such as allowing or denying those with a particular role to create, list, update and delete any kind of objects or also restrict access within a namespace itself. But what if you want more than that? for example if the deployment is created and you want to validate its name should has prefix name or its image name should be allowed only from private registry? … The RBAC cannot validate and ensure this! So, that is where admission controller comes in.

What is Admission Controller?

As mentioned in Kubernetes docs: “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.” So, basically it helps to define rules or security measures to enforce how a cluster is used.

There are two admission controllers to use:

  1. MutatingAdmissionWebhook : allow for the use of mutating webhooks to modify the content of the resource before it is persisted.
  2. ValidatingAdmissionWebhooks : allow for the use of validating webhooks to enforce custom admission policies.

We can configure these webhooks to reach the webhook server that contains our logic of admission controller service . In this post, I develop a simple webhook server that includes mutating and validating the deployment’s start with the specific prefix prod.

Let’s get started!

What we need to develop our own admission controller?

Before jump into the implementation, let’s take an overview of the process. First, you need to write and deploy the webhook server and make it accessible. Next, configure the webhooks on K8s to reach your webhook server. After that, webhooks are sent POST requests with JSON payload as AdmissionReview API object which has all details about the request. Then, webhooks should get a JSON payload AdmissionReview response that contains the decision on whether the request is allowed or not.

Now for implementation:

  1. Deploy Webhook Server

In the above code, it handles requests coming in at /validate and /mutate from two calls: validate and mutate . The mutate call gets the deployment’s name and response with a JSON patch operation of adding deployment’s prefix name to the deployment ✅. Then, the validate receives a validation webhook request and in the code’s example validates the deployment’s prefix name if it prod or not and accepts or rejects the request.

I deployed in the Kubernetes cluster as deployment object and created a service as the front-end of the webhook server (you can also deploy your webhook server outside of the cluster):

Since the API server only communicates over HTTPS with the admission webhook servers, it needs TLS cert’s CA information. Therefore, I created self-signed certificate and then created kubernetes.io/tls secret for storing a certificate and its associated key:

then apply webhook_server.yml in K8s:

Note: in my GitHub repo you will find the create_k8s_objects.sh script that will create a self-signed certificates, tls secret, webhook server and webhooks.

2. Configure Admission Webhook

Note: To verify admissionregistration.k8s.io/v1 or admissionregistration.k8s.io/v1beta1 is enabled: kubectl api-versions | grep -i admissionregistration.k8s.io. Please check prerequisites to make sure the admission controllers are enabled.

In order to register admission webhooks, create MutatingWebhookConfiguration and ValidatingWebhookConfiguration API objects:

If your webhook server deployed outside the K8s, you need to replace service block under clientConfig by url in both webhooks like this:

Apply in K8s:

3. Test 💅

Now that our controller is written, to see all the created resources:

Let’s create a simple Nginx deployment to test our webhook server:

To see the logs of webhook-server when creating the Nginx deployment:

and now apply in K8s:

You’ll see:

If we get the Nginx deployment’s name, we can see it’s changed from nginx-deployment to prod-nginx-deployment :

The End

Here, we’ve covered how to create a simple Kubernetes admission controller in Golang and deploy it to an K8s cluster. It’s quite easy and you can think about many different cases used as admission controller which make your cluster more secure by applying some polices.

I hope this was helpful!

References:

Bye :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Bashayr Alabdullah

Bashayr Alabdullah

Hi, I’m Cloud Engineer, Golang & Python Enthusiast! A bit of random things...🥑🎶 🎯🌻