Introducing Autopilot, an AI coding assistant
gradient
Using Kubernetes admission controllers and webhooks

Using Kubernetes admission controllers and webhooks

Nov 29, 2021
6 min read

Kubernetes provides organizations with rich deployment options for containerized services, yet additional configurations are sometimes needed to fully optimize infrastructure. Deeper controls situated between sender and receiver—in this latter case, the Kubernetes API server—are required to unlock all of Kubernetes’s powerful features.

The Kubernetes API undertakes a number of key operations within the overall system. This includes querying and manipulating API objects including namespaces, pods, events, and ConfigMaps. Since the Kubernetes API server is central to the Kubernetes control plane, the methods through which you can utilize the API are numerous. It’s what makes REST calls and kubectl commands so vital within a microservices architecture.

Admission webhooks and controllers provide the extensibility that many administrators require. Discussed in unison, webhooks are specialized types of controllers that either “validate” or “mutate” objects. Admission webhooks are HTTP callbacks, meaning they receive and route admission requests accordingly. These plugins ultimately have dominion over clusters and determine how Kubernetes uses them. An admissions controller is a code block that intercepts Kubernetes server requests and performs custom operations.

This article thoroughly reviews admissions controllers and webhooks. You’ll learn why each mechanism is important, how they exist throughout the system, and how they’re deployed or configured.

Why do you need admission webhooks and controllers?

We’ve touched on how webhooks help determine the way API requests travel between different components of the Kubernetes system. Because these link to the cluster control plane, leveraging them is immensely beneficial for those seeking ultimate configuration control. However, proceed with caution. This level of control is useful, yet missteps can cause larger problems that impact your overall system.

Webhooks are convenient because you don’t have to compile them into your builds. Their plugin nature lets them behave like extensions—which you can essentially bolt on to your infrastructure with minimal developmental work. After deployment, the mutate webhook type executes first, followed by the validate webhook. These mutations modify objects, while validations help decide which custom policies are enforced or rejected.

Controllers and webhooks exist separately within Kubernetes. Controllers effectively live within the kube-apiserver binary and are compiled accordingly. Webhooks are fittingly configured within the API itself, since they directly influence HTTP activity.

Controllers have elevated privileges within Kubernetes, given that they impact requests after authentication and authorization are completed.

Admission controllers can limit requests to the following:

  • Create
  • Delete
  • Modify
  • Connect to proxy

However, admission controllers cannot handle read requests. While requests may be successful, controllers can return error responses to users upon rejecting requests.

How to implement

Getting started with these powerful components of Kubernetes requires some prep work. Controllers must be activated before you can begin using them. Activation is easy to do with a quick kubectl command:

go

Turning off an admissions controller is equally simple. Simply enter the following prompt:

go

This same command works for any of Kubernetes 30+ admission controllers. Just replace CertificateApproval with your preferred controller. You can also simultaneously activate multiple controllers by sequentially writing in a comma-list format.

However, Kubernetes does save you the work of manually enabling default controllers. Because these controllers are already on, you can verify their status using the following command:

go

It’s important to note that over half of these controllers are automatically enabled. Kubernetes already has these controllers up and running:

go

As time passes, the team behind Kubernetes will deprecate various controllers through the development cycle. These changes are documented accordingly.

Kubernetes’s documentation also denotes which controllers are actively being developed (alpha) and which may not be stable enough (or supported for) production use. While some work out of the box, others require you to specify appropriate fields and values within a YAML configuration file.

Overview of admission controller types

There’s an impressive variety of controllers that you can use to enhance your Kubernetes deployments and achieve fine-grained control. It’s important to determine if these supplemental controllers can benefit you before implementing. Each non-default controller is broken down briefly and explained below.

  • AlwaysPullImages. Every new pod automatically forces the image pull policy to “Always” (useful for credential-dependent multi-tenant clusters, for privacy reasons).
  • DenyServiceExternalIPs. All net-new usages of the Service field externalIPs are rejected.
  • EventRateLimit. The controller prevents flurries of requests from overwhelming the server, through enforced rate-limiting controls.
  • ExtendedResourceToleration. Allows the creation of new nodes with extended resources.
  • ImagePolicyWebhook. Permits a backend webhook to make admission decisions.
  • LimitPodHardAntiAffinityTopology. Denies any pods that define an AntiAffinity topology key aside from kubernetes.io/hostname.
  • NamespaceAutoProvision. Checks all incoming requests for the existence of referenced namespaces, otherwise creating an associated namespace.
  • NamespaceExists. Checks all requests on namespaced resources other than Namespace.
  • NodeRestriction. Limits the Node and Pod objects a kubelet can modify.
  • OwnerReferencesPermissionEnforcement. Protects access to an object’s metadata.ownerReferences file, so only owners with delete permissions can modify it.
  • PodNodeSelector. Determines and limits which node selectors are usable within a namespace.
  • PodSecurity. Determines on pod modification and creation if that pod should be admitted based on security controls (alpha).
  • PodTolerationRestriction. Verifies conflicts between pod and namespace tolerations, either rejecting pods or merging tolerances accordingly.
  • SecurityContextDeny. Denies any pod which attempts to escalate certain SecurityContext fields outside of scope.

As you can see, admission controllers can directly impact horizontal scaling, proper resource consumption, security, tolerations, and more. While these aren’t inherently required to leverage Kubernetes, the evolution of your deployment (and use cases) may make them relevant. Some are more challenging to enable than others. However, the Kuberenetes controllers documentation is extremely handy for exploring best practices.

Deploying webhooks for mutation and validation

Before deploying and experimenting with webhooks, the following prerequisites must be met:

  • Your Kubernetes cluster(s) must be running v1.16 or newer, or v1.9 when using admissionregistration.k8s.io/v1beta1.
  • Both the MutatingAdmissionWebhook and ValidatingAdmissionWebhook controllers must be enabled.
  • Either the admissionregistration.k8s.io/v1 or admissionregistration.k8s.io/v1beta1 API must be enabled.

You’ll also have to include or write an intermediary admission webhook server to handle these specialized requests as they traverse the network. The AdmissionReview object relays any decisions made regarding those requests once they’re sent, thus determining whether they’re valid or denied. It’s not always necessary to authenticate clients or other fields (for example), and you can configure your server protocols accordingly. You may also opt for or against mutual TLS (Transport Layer Security).

Deployments also enjoy some flexibility. You can deploy your webhooks either within or outside your clusters depending on preference or functional requirements. This is true for both test cases and production deployments. The former relies on the Deployment API. This creates a service, which acts as the frontend component to your webhooks server. The code is quite extensive, yet openly available via GitHub.

Deploying externally, by contrast, may require some additional configurations to ensure everything works properly. This is where ValidatingWebhookConfiguration and MutatingWebhookConfiguration come in handy. The Kubernetes documentation outlines the following example:

yaml

It’s also expected that you define your webhook requests and responses via YAML files. This includes any matching request and policy configurations, which are widely varied akin to controller types. URLs, references, timeouts, failures, and reinvocations will be essential elements in this equation. Each piece is configurable and customizable to your deployment. Kubernetes provides two separate YAML configurations depending on your admissionregistration version.

Be sure to follow best practices as defined by Kubernetes, especially when avoiding any problematic side effects. You can also monitor your webhooks in production through metrics collection.

In addition, consider how deep your webhooks deployments will extend. Those that touch the control plane need the kube-system namespace to be intercepted prior to modification. If your deployment ignores the control plane, use the namespaceSelector field to exclude kube-system. This prevents unpredictability and ensures that everything functions normally.

Final thoughts

Kubernetes’s default functionality is undoubtedly impressive, yet ambitious administrators might favor extensibility for their use cases. Admission controllers and webhooks give teams added flexibility while unlocking Kubernetes’s complete granularity. These separate basic deployments form purpose-built deployments.

However, remember that configuration changes aren’t geared toward Kubernetes novices—they’re mostly advanced operations with careful considerations attached.

If you're looking for a maintenance-free platform to build internal dashboards and workflows, then check out Airplane. With Airplane, you can transform scripts, queries, APIs, and more into custom internal tools. The basic building blocks of Airplane are Tasks, which are single or multi-step operations that anyone can use. Airplane also offers Views, a React-based platform for building internal UIs. Airplane features strong built-ins, such as approval flows, audit logs, and more. You can also use webhooks to trigger task execution from an external source.

Sign up for a free account or book a demo to try it out and build your first workflow in minutes.  

Share this article:
Tyler Charboneau
Tyler is a hardware-software devotee and researcher. He specializes in simplifying the complex while speaking effectively to all audiences.

Subscribe to new blog posts from Airplane.