Skip to content

Diving into Kubernetes Admission Webhooks with Go#

This blog post explores the world of Kubernetes admission webhooks and how to create a simple validating admission webhook using the Go programming language. We'll cover the basics of Go, the concept of admission webhooks, and walk through a practical example.

You can find the full code in the Github repo.

More information and reference can be found in the official k8s documentation for Dynamic Admission Control

Introduction to Admission Webhooks#

Kubernetes admission webhooks are HTTP callbacks that intercept requests to the Kubernetes API server. They act as gatekeepers, allowing you to control and enforce policies on objects before they are persisted in the cluster. There are two types of admission webhooks:

  • Mutating Admission Webhooks: These webhooks can modify objects before they are created or updated. For example, you can use a mutating webhook to automatically inject sidecar containers or set default resource requests and limits.
  • Validating Admission Webhooks: These webhooks validate objects and can reject requests that don't meet your defined criteria. For example, you can use a validating webhook to ensure all pods have resource limits defined or prevent deployments to a specific namespace.

The Journey of a Request:#

  1. API Handler: The journey begins with an API handler, which receives the request.
  2. Authentication: The request is then authenticated to ensure it comes from a trusted source.
  3. Mutating Admission: This stage allows you to modify the request before it reaches the API server. Think of it as a pre-flight check.
  4. Object Schema Validation: The request is then validated against the Kubernetes schema to ensure it's well-formed.
  5. Validating Admission: This is where you can enforce your custom policies and reject requests that don't meet your criteria.
  6. ETCD Persistence: Finally, the request is persisted in the ETCD database, the heart of Kubernetes' data storage.
img
Kubernetes Admission Controllers flow diagram
Source: https://sysdig.com/blog/kubernetes-admission-controllers

A Quick Tour of Go#

Go, also known as Golang, is a statically-typed, compiled programming language designed at Google. It's known for its simplicity, efficiency, and strong support for concurrency. Here's a quick overview of some key Go concepts:

  • Packages: Go programs are organized into packages, similar to libraries or modules in other languages.
  • Variables: Variables are declared using the var keyword, followed by the variable name and type.
  • Functions: Functions are defined using the func keyword, followed by the function name, parameters, and return type.
  • Structs: Structs are custom data types that group together fields of different types. They are similar to classes in object-oriented languages.
  • Interfaces: Interfaces define a set of methods that a type must implement. They provide a way to achieve polymorphism in Go.
  • Goroutines: Goroutines are lightweight threads managed by the Go runtime. They enable concurrent execution of code.
  • Channels: Channels are typed conduits through which you can send and receive values between goroutines. They facilitate communication and synchronization in concurrent programs.

Recomended Resource: Go Tour

Building a Validating Admission Webhook#

Our example focuses on building a validating admission webhook that checks if a pod has memory limits defined before allowing its creation.

Here's a breakdown of the code:

  1. Dependencies: We import necessary packages like net/http, k8s.io/api/admission/v1, and k8s.io/apimachinery/pkg/runtime/serializer.
  2. Configuration: We define a ValidatingWebhookConfiguration object in a YAML file. This configuration specifies the webhook's name, namespace, service, rules, and the CA bundle used for TLS.
  3. Webhook Server: We create an HTTP server that listens for incoming requests on a specific port. The server uses TLS for secure communication.
  4. Validation Logic: The serveValidate function handles incoming requests. It decodes the request body, parses it into an AdmissionReview object, and checks if the incoming pod has memory limits defined. If not, it rejects the request with an appropriate error message.
  5. Response: The webhook server sends back an AdmissionReview object as a response. The response includes a UID (unique identifier), allowed (boolean indicating whether the request is allowed), and a status object containing the code and message.

Demo and Explanation#

The demo showcases the webhook in action. We first deploy the webhook server and configure Kubernetes to use it. Then, we try to deploy two pods: one with memory limits and one without. The pod with memory limits is successfully created, while the pod without memory limits is rejected, and an error message is displayed in the terminal and the Kubernetes API server logs.

The code demonstrates how to:

  • Receive and parse incoming HTTP requests.
  • Decode the request body into an AdmissionReview object.
  • Access and validate the pod spec.
  • Construct and send back an AdmissionReview response.

To run the demo, we first build and deploy the webhook server to our Kubernetes cluster. Then, we attempt to create two Pods: one with a memory limit and one without.

Observations:#

  • The Pod with the memory limit is successfully created.
  • The Pod without the memory limit is rejected by the webhook. The error message returned to kubectl indicates that the Pod has no memory resource limits specified.

Conclusion#

Kubernetes admission webhooks are a powerful tool for enforcing policies and customizing the behavior of your cluster. By leveraging the simplicity and concurrency features of Go, you can easily create custom webhooks to meet your specific needs. This example provides a starting point for exploring the world of admission webhooks and building more complex validation and mutation logic.