Kubernetes admission controllers in 5 minutes

By Kaizhe Huang - FEBRUARY 18, 2021

SHARE:

Admission controllers are a powerful Kubernetes-native feature that helps you define and customize what is allowed to run on your cluster.

As watchdogs, they can control what’s going into your cluster. They can manage deployments requesting too many resources, enforce pod security policies, and even block vulnerable images from being deployed.

In this article, you’ll learn what admission controllers are in Kubernetes and how their webhooks can be used to implement image scanning.

Admission controllers guard the door to your Kubernetes cluster

An admission controller intercepts and processes requests to the Kubernetes API prior to persistence of the object, but after the request is authenticated and authorized.

These controllers are compiled and shipped into the kube-apiserver binary, and can only be enabled and configured by the cluster administrator using the --enable-admission-plugins and --admission-control-config-file flags.

Diagram showing the flow of admission controllers. First API Handler, then Auth, then the mutating admission controllers with their webhooks, then the object schema validation, then the validating admission controllers with their webhooks, and finally persistence in ETCD.

Most of the available admission controllers have very specific functions.

For example, LimitRanger validates that none of the objects in a Kubernetes deployment violate the constraints specified in the LimitRange object of a Namespace. It can also mutate the request to assign default resource limits and requests to Pods that don’t specify any.

This is the set of recommended Kubernetes admission controllers that you may find in any vanilla deployment:

--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota,PodSecurityPolicy

You can check the full list of available admission controllers in the Kubernetes documentation.

Admission controllers guard the door to your #Kubernetes cluster. From resources requests, to blocking images, they are really useful. Discover them! Click to tweet

The power of Kubernetes admission controllers

Admission controllers can answer existential questions in the life of a DevOps:

  • Is the pod requesting too many resources?
  • Are the base images used to spawn the microservice pods secure?
  • What is the priority of this deployment compared to the others?
  • Which privileges are currently granted to the service account linked to these pods/deployments? Do they adhere to the principle of least privilege?

They also can take action.

They can block pods from running if the cluster is out of resources or if the images are not secure. And, as we saw earlier, they can even mutate the request to tweak the resources request from a pod.

You are probably already running several Kubernetes admission controllers that come pre-configured out-of-the-box with your standard deployment. Some aspects of Kubernetes that you may consider built-in are actually enforced by these controllers, for example:

  • LimitRanger: Manages resource limits and requests, as mentioned before.
  • PodSecurityPolicy: Acts on creation and modification of the pod and determines if it should be admitted based on the requested security context and the available Pod Security Policies.
  • PersistentVolumeClaimResize: Implements additional validations for checking incoming PersistentVolumeClaim resize requests.
Flow of an image validation webhook. After a deployment request, the kubernetes API calls the image validation webhook. This webhook can trigger an image scan and apply your security policies. If the image doesn't pass the scan, the webhook can abort the deployment.

Again, all of this is done before the request is persisted in etcd, which means before it is executed. This is what makes Kubernetes admissions controllers such a perfect candidate to deploy preventive security controls on your cluster.

Extending Kubernetes admission controllers with webhooks

All of these features we’ve been describing so far are critical to run reliable and secure services.

However, as each organization has their own policies and default set of best practices, such highly specific controls may not be enough.

Fortunately, Kubernetes has you covered.

You can extend and customize the Kubernetes API functionality, without adding complexity to its base code, by using webhooks.

The Kubernetes API server will call a registered webhook, which is a rather standard interface. This makes admission controllers easy to integrate with any third-party code.

These three specific admission controllers let you expand the API functionality via webhooks:

  • ImagePolicyWebhook to decide if an image should be admitted.
  • MutatingAdmissionWebhook to modify a request.
  • ValidatingAdmissionWebhook to decide whether the request should be allowed to run at all.

Implementing your own Kubernetes admission controller webhook

Now that we know how the admission controllers work, let’s see what marvelous things we can do with this power.

Let’s imagine we want to implement an ImagePolicyWebhook.

For starters, we’ll need to make sure that the webhook is enabled when we start kube-apiserver:

kube-apiserver --enable-admission-plugins=ImagePolicyWebhook …

We also need to configure the webhook server that will be called by the API server:

kube-apiserver --admission-control-config-file=admission-config.yaml …

An example admission-config.yaml contains an AdmissionConfiguration object:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  configuration:
    imagePolicy:
      kubeConfigFile: <path-to-kubeconfig-file>
      allowTTL: 50
      denyTTL: 50
      retryBackoff: 500
      defaultAllow: true

And then, the webhook server is configured into a kubeconfig file:

# clusters refers to the remote service.
clusters:
- name: name-of-remote-imagepolicy-service
  cluster:
    certificate-authority: /path/to/ca.pem    # CA for verifying the remote service.
    server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
  user:
    client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use
    client-key: /path/to/key.pem          # key matching the cert

Please refer to the ImagePolicyWebhook documentation for a detailed description of the configuration options and alternatives.

We can now code our HTTP server to attend the webhook requests.

Once the Kubernetes API server receives a request for a deployment, our webhook will receive a JSON request similar to:

{
  "apiVersion":"imagepolicy.k8s.io/v1alpha1",
  "kind":"ImageReview",
  "spec":{
    "containers":[
      {
        "image":"myrepo/myimage:v1"
      }
    ],
    "namespace":"mynamespace"
  }
}

Then, you can process this request on your server. For example, checking that image against your image scanner to ensure that it doesn’t contain vulnerabilities or misconfigurations.

In our example, that image does not conform with our company policies, so we would respond with the following JSON payload:

{
  "apiVersion": "imagepolicy.k8s.io/v1alpha1",
  "kind": "ImageReview",
  "status": {
    "allowed": false,
    "reason": "image runs as root"
  }
}

Because we have rejected one part of the request, the entire API request is immediately rejected, the image won’t be deployed, and an error is returned to the end-user.

Kubernetes Admission controllers for image scanning

Implementing image scanning should be one of your first steps when implementing Kubernetes security. It is a reliable mechanism to detect vulnerabilities and misconfigurations.

If you are following image scanning best practices, you probably secured your CI/CD pipeline and your registries already.

So why should you do image scanning with an admission controller too?

Ryan reynolds in medical clothes, asking but why while taking his surgical mask off.

There are two use cases you might be interested in:

Manual deployments can still occur. For example, you may skip protocol to do a manual deploy in a rush, or an attacker that gains access to your cluster deployed images skipping your image scanner.

There are also rules that rely on Kubernetes-specific context. For example, if you want to restrict one image to a specific namespace.

If you want to dig deeper into this topic, don’t miss our article “Shielding your Kubernetes runtime with an Admission Controller and image scanning.” In it, we cover image scanning with more detail and offer guidelines to help you implement such a solution.

Conclusion

Admission controllers are a powerful Kuberentes-native tool that help you enforce your organization policies.

Many basic features of Kubernetes are implemented with the help of Admission controllers, like limits and requests, and pod security policies.

Being able to expand the Kubernetes API server with webhooks opens the door to very interesting features, like implementing image scanning.

They are worth exploring!


The Sysdig Admission Controller leverages admission controllers for image scanning. Reuse your existing scanning policies mapped to compliance controls, report vulnerabilities to your team, and more. You’ll be set up in just a few minutes. Request your free trial today!

Subscribe and get the latest updates