Kubernetes Admission Controllers: What They Are and Why They Matter
Tags: kubernetes, vcluster, devspace, loft
Published: 2022-06-16 16:40:19

By Harshit Mehndiratta

With Kubernetes becoming the gold standard for advanced container orchestration, it’s also become necessary to use extensions that work alongside Kubernetes to provide security and modularity. As more developers and organizations move toward the containerized framework, they need more features to support their ever-evolving requirements.

Some of the most advanced security features that work alongside Kubernetes nowadays are admission controllers. These are plugins that intercept API requests before the system processes them. 

Admission controllers have many benefits, which we’ll examine in this article. You’ll also learn about the technical details of admission controllers, their types, and how they provide first-class integration with Kubernetes.

Let's get started.

## What Are Admission Controllers?

Admission controllers are a set of extensions that help define and govern operations for Kubernetes clusters. They act as gatekeepers and process Kubernetes API server requests before the object data is executed or persisted into etcd, the distributed key-value store. 

Admission controllers can completely deny/accept the requests or change the request object altogether. Depending on the Kubernetes distribution, admission controllers may come compiled and shipped into the `kube-apiserver` binary and can be easily enabled by the cluster administrators, to run secure and reliable services. 

Admission controllers have different functions but implement a typical two-phase admission control process.

The first phase is called the *change of request object* or *mutating phase*. In this phase, changes are made to the incoming request.

This is followed by the allow/disallow of requests—the second or *validating phase*—which acts on changes made in the mutating phase. If any request is disallowed in the validating phase, the entire request gets rejected, and error messages are returned as responses.

### Admission Controller Types

Admission controllers are divided into two basic classes for ease of use.

1. **Validating admission controllers:** These types of admission controllers validate API object contents and make sure they are valid. The responses are returned as binary results in the form of `yes`, if the object is granted permission, or `no` when it is not.
2. **Mutating admission controllers:** These admission controllers assess the API object and may add or modify the API object contents.

It’s also worth noting that admission controllers can be both validating and mutating controllers. A great example of that is the [LimitRanger](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#limitranger) admission controller, which can handle functioning for both of these controller methods. As a validating admission controller, it can allow or deny the deployment objects from violating the limit range constraints. Meanwhile, as a mutating admission controller, it can change or assign resource limits for pods.

There is a set of static Kubernetes admission controllers that you can find in any vanilla Kubernetes deployment, which we’ll discuss in the next section. To check the complete list of available admission controllers, visit the [Kubernetes documentation here](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/).

## Admission Controller Benefits

We’ve covered how admission controllers enforce control on the Kubernetes cluster, but you need to see some concrete scenarios.

There are actually many ways admission controllers can benefit your business workflows and provide security compliance and validation.

### Improved Security

As mentioned earlier, admission controllers intercept API server requests before they’re executed or persisted in [etcd](https://etcd.io/). This makes them a perfect contender to apply security measures to help organizations meet policy requirements. Admission controllers can improve the security of Kubernetes workloads through a built-in PodSecurityPolicy (PSP), which mounts the root file system as read-only and prevents the containers from running as the root user. 

Also, denying the pulling of images from registries that are unknown to the enterprise can mitigate many security risks. You can implement a catch-based logic, where an admission controller handles every image differently after its content is scanned during the build process. 

### Seamless Configuration and Deployment

Configuration management is an essential practice required in Kubernetes to automatically deploy components based on different parameters. An admission controller in this context can validate the configuration of objects on a cluster and manage deployment misconfiguration requesting too many resources, missing appropriate pod labels, or image tags.

Also, using an image signature ensures that a verified image is used for deployment to enforce security in a pipeline. 

### Easy Kubernetes Governance

To be Kubernetes production-ready, governance is critical. You have to ensure that teams deploying clusters are adhering to specific rules.

Kubernetes admission controllers allow enforcement of these rules through labels, annotations, and automated policy management. Label validation is enforced across departments, groups, or the entire organization, so an appropriate label is assigned for every project. Deployment policies are also created based on the particular namespace so that only certain users or service accounts have access to deploy containers.

## Built-in Static Kubernetes Admission Controllers

Kubernetes recommends enabling several built-in admission controllers by default to secure the running containers:

* **PodSecurityPolicy:** This controller implements pod admission (i.e., create and modify pods) and determines whether they should be admitted based on the security policies. Note that PSPs [will be deprecated](https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/) in a future Kubernetes release.
* **DenyEscalatingExec:** This controller blocks exec and attach commands from privileged containers so hackers cannot have access to the host even if they have access to a shell in privileged containers.
* **AlwaysPullImages:** This controller ensures that the latest builds for the container images are always downloaded. While there is a performance deficit for pulling and using new images every time for a node, it's important to run up-to-date container images.
* **LimitRange and ResourceQuota:** This controller observes incoming requests and checks them for limits violations to prevent DoS attacks and unauthorized processes from running.
* **DefaultStorageClass:** This controller handles PersistentVolumeClaim (PVC) objects creation. It also automatically adds a default storage class to them if they are not mapped to any specific ones.
* **NamespaceLifecycle:** This controller ensures that namespaces under the process of termination are not allowed to create new objects. All the requests made to nonexisting namespaces are rejected, while modification of system namespaces is disabled.
* **Service Account:** In Kubernetes, service accounts are processes that run in pods. This controller implements the automation of service accounts.
* **DefaultTolerationSeconds:** This controller sets toleration duration for pods to tolerate the taints, which allows a particular node to repel a set of pods.
* **MutatingAdmissionWebhook and ValidatingAdmissionWebhook:** These are dynamic admission controllers that can be extended with custom logic through webhooks.

## Dynamic Admission Controllers

In Kubernetes, dynamic admission controllers are user-configured controllers that can modify or reject API requests based on custom logic. As previously discussed, Kubernetes already provides a large set of admission controllers to change basic behavior. However, those are not enough for organizations that have their own specific set of policies to implement.

That's where the *dynamic* part comes in. These controllers can extend the Kubernetes API functionality and provide customized configuration through webhooks.

A webhook is a standard interface that listens to API server incoming requests and responds with the results. Unlike other interfaces, webhooks are flexible and easy to code in any language or framework, which allows seamless integration of Kubernetes admission controllers with any third-party code. 

There are various scenarios where cluster admins can use webhooks to create admission logic for Kubernetes resources. Some are:

* Limiting customization each time a resource gets created or modified in the cluster.
* Making the resources immutable through RBAC policies so unauthorized teams cannot add or delete resources.
* Injecting sidecar containers for implementing additional traffic controllers, auditing, and logging tools.

### Dynamic Admission Controller Types

There are three specific types of dynamic admission controllers that can extend API functionality through webhooks:

* `ImagePolicyWebhook`: Controls admission for a particular container image. 
* `MutatingAdmissionWebhook`: Modifies the objects received in the admission requests. It runs before the validating webhooks. 
* `ValidatingAdmissionWebhook`: Accepts or rejects admission requests.

To create and configure a webhook in the Kubernetes cluster, `MutatingAdmissionWebhook` and `ValidatingAdmissionWebhook` must be enabled. A `MutatingAdmissionWebhook` controller can trigger the registered webhooks to enforce custom options, while the `ValidatingAdmissionWebhook` controller can trigger registered webhooks to enforce custom policies.

A validating admission webhook controller cannot mutate or modify requests and only runs in parallel. Any request that does not match the webhook gets rejected, while the mutating admission webhook controller matches the desired webhook in serial. Therefore, any incoming request that does not meet the criteria can get modified.

## Open Policy Agent (OPA) as a Dynamic Admission Controller

Developed by [Styra](https://www.styra.com/), OPA is an open-source framework used to enforce policy decisions on clusters, CI/CD pipelines, and microservices. It’s currently a part of the Cloud Native Computing Foundation (CNCF) as an incubating project. OPA can be tightly integrated with Kubernetes to make policy decisions.

This framework specifies policies as code using high-level declarative language and pushes them into a policy engine that understands the code and dynamically enforces rules. 

Kubernetes specific implementation of OPA happens through an [OPA Gatekeeper](https://kubernetes.io/blog/2019/08/06/opa-gatekeeper-policy-and-governance-for-kubernetes/) agent, which acts as a validating webhook to enforce the policies. Gatekeeper only checks whether the request meets the defined criteria or not, which is why it is installed as a validating webhook.

Several other policy frameworks for Kubernetes exist. A newer alternative to OPA is [jsPolicy](https://jspolicy.com), an open source policy framework maintained by the team at Loft Labs. jsPolicy allows you to write policies using JavaScript or TypeScript. Other options include [Kyverno](https://kyverno.io/) and [Kubewarden](https://www.kubewarden.io/).

## Conclusion

For a cluster admin, admission controllers provide all the necessary tooling to enforce security policies for clusters. In this article, you’ve become acquainted with all the basic and a few advanced features in Kubernetes, such as pod security policies, limits, or custom webhooks, and how admission controllers implement them.

Admission control is an essential tool for securing Kubernetes clusters, and it should be part of your toolkit if you administrate clusters.

*Photo by [Kyle Glenn](https://unsplash.com/@kylejglenn?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/do-not-enter?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)*