Skip to main content
In this lesson, we will explore the lab on validating and mutating admission controllers. You will learn how these controllers work together, create a namespace and TLS secret, deploy the webhook server with corresponding configurations, and test pod security contexts.

Determining the Correct Controller Actions

The first step in this lab is to understand which admission controller action is mutating and which one is validating. Consider the following:
  • The “namespace auto-provision” admission controller is mutating because it automatically creates and modifies a namespace’s configuration.
  • The “namespace exists” admission controller is validating as it solely checks for the existence of a namespace.
Thus, the correct pairing is:
  • Mutating: Namespace auto-provision
  • Validating: Namespace exists
Remember, the admission controller invocation sequence always applies mutations first and then validations.

Creating the Namespace

Next, create a namespace called webhook-demo by running:
Verify the creation of the namespace with:

Creating the TLS Secret

For secure webhook communication, you need to create a TLS secret named webhook-server-tls in the webhook-demo namespace. This secret uses a certificate and key from specific file paths:
You should see the confirmation:

Deploying the Webhook Deployment

Deploy the webhook server next using the provided deployment definition in webhook-deployment.yaml. First, you can inspect the file with:
Then, apply the configuration:
The expected output should be similar to:

Deploying the Webhook Service

A service definition for the webhook server is provided in the webhook-service.yaml file. Deploy it by running:
This command creates the service necessary for the webhook server to operate.

Deploying the Mutating Webhook Configuration

Next, configure the mutating webhook with the settings provided in webhook-configuration.yaml. This file defines a webhook that intercepts pod creation events. For instance, it uses the following rule to match create operations for pods:
Apply this configuration using:
You might receive a deprecation warning:
Warning: admissionregistration.k8s.io/v1beta1 MutatingWebhookConfiguration is deprecated in v1.16+ and will be unavailable in v1.22+. Please use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration.
The webhook is designed to reject any pod request that attempts to run as root without a proper security context. If no runAsNonRoot value is specified, the webhook mutates the pod by setting runAsNonRoot to true and defaults the user ID to 1234. However, if the security context explicitly sets runAsNonRoot to false, the webhook will not override it.

Testing the Default Pod Security Context

First, test the webhook by deploying a pod without a security context. The file pod-with-defaults.yaml contains a pod definition that, by default, would run as root. However, the webhook mutates it:
Apply the configuration:
After deployment, inspect the pod configuration (or use kubectl describe pod pod-with-defaults) to confirm that the security context has been mutated — runAsNonRoot should be true and runAsUser should be set to 1234.

Deploying a Pod with an Explicit Security Context

Now, deploy a pod that explicitly permits running as root. The file pod-with-override.yaml contains the configuration that sets runAsNonRoot to false, preventing the webhook from applying its defaults:
Deploy the pod with:
For further reference, you can view the content of pod-with-conflict.yaml with:

Deploying a Pod with a Conflicting Security Context

The final test involves deploying a pod with a conflicting security context. In this scenario, the pod configuration requires the container to run as a non-root user by setting runAsNonRoot to true while explicitly requesting a user ID of 0 (root). Without the webhook, this could lead to a CreateContainerConfigError. With the webhook enabled, the pod creation is rejected:
Attempt to deploy the conflicting pod:
The expected error message should be similar to:
This confirms that the webhook correctly rejected the pod due to the conflicting security settings.

Conclusion

In this lab, you learned how to:
  • Distinguish between mutating and validating admission controllers.
  • Create a namespace and configure TLS for secure webhook communication.
  • Deploy a webhook server along with its service and webhook configurations.
  • Test the webhook behavior by deploying pods with default, overridden, and conflicting security contexts.
By following these steps, you ensure that your Kubernetes resources adhere to the required security policies enforced by admission controllers.

Watch Video