Image reference: https://unsplash.com/photos/w7ZyuGYNpRQ

Kubernetes Admission Controllers: Request Interceptors

A Kubernetes Control plane consists of several components.One such component is kube-apiserver or simply an API server. It exposes a REST endpoint through which users, cluster components or any client application can communicate with the cluster. In simple words it does the following:

  1. Receives a standard HTTP request from a client application like kubectl.
  2. Authenticates the incoming request and applies Authorization policies.
  3. On a successful authentication, it performs an action based on the endpoint object (Pod,Deployments, Namespace etc) and the http verb (Create, Put, Get, Delete etc) .
  4. Makes changes to etcd data store to persist the data.
  5. Once the action is completed, it sends back a response to the client.
Request Flow

Now let’s consider a scenario in which you have to intercept this request after it was Authenticated but before any changes were made to etcd data store. For instance:

  1. Intercept the request sent by a client.
  2. Parse the request and perform an action.
  3. Based on the result of the action, execute a logic that decides whether to make changes to etcd or reject the request without making any changes to etcd.

Kubernetes Admission Controllers are plugins that are used in such scenario’s. At code level an Admission Controllers logic is decoupled from API server logic and that was intentionally done so that users can develop custom interceptor’s that can be invoked whenever objects were being created, updated or deleted from etcd.

With Admission Controllers in place, the request flow from any source to API server will look as shown below:

Admission Controller Phases (From official docs)

Based on the type of activity performed by an admission controller, it can be classified into 3 types:

  1. Mutating
  2. Validating
  3. Both

Mutating: Such controllers parse the request and make changes (mutates the request) to the request before forwarding it down the chain.

Example: AlwaysPullImages

Validating: These controllers parse the request and validate it against specific data.

Example: NamespaceExists

Both: A Controller can also perform both Mutating and Validation activities.

Example: CertificateSigning

For more information on these controllers, you can check the official docs.

An admission controller process consists of 2 phases that are executed in sequence:

  1. Mutating phase (executed first)
  2. Validation phase (executed after mutating phase)

A Kubernetes cluster already makes use of Admission Controllers (30+ at the time of writing) to perform many tasks. Here is a list of Admission Controllers that are shipped with Kubernetes. If you observe the list carefully, you will be amazed to see that most of the activities like AlwaysPullImages, DefaultStorageClass, PodSecurityPolicy etc are actually performed by different Admission Controllers.

How to enable or disable admission controllers?

To enable an admission controller, we have to pass a comma-delimited list of admission controller plugin names to the flag “--enable-admission-plugins” while starting the kube-apiserver. For default plugins, the command might look like below:

To disable admission controller plugins, pass the list of plugin names to “--disable-admission-plugins” flag. This will override the list of plugins that are enabled by default.

Default Admission controllers

  1. NamespaceLifecycle
  2. LimitRanger
  3. ServiceAccount
  4. TaintNodesByCondition
  5. Priority
  6. DefaultTolerationSeconds
  7. DefaultStorageClass
  8. StorageObjectInUseProtection
  9. PersistentVolumeClaimResize
  10. RuntimeClass
  11. CertificateApproval
  12. CertificateSigning
  13. CertificateSubjectRestriction
  14. DefaultIngressClass
  15. MutatingAdmissionWebhook
  16. ValidatingAdmissionWebhook
  17. ResourceQuota

Why should we use Admission Controllers?

Admission Controllers provide additional layer of security and governance that determines how a Kubernetes Cluster can be used by it’s users.

  1. To enforce policies: By using custom admission controllers, we can validate a request and check if it contains a certain required information. Example, we can check if the pod specs have a proper label set. If the condition is not satisfied the request can be rejected all together. In certain situations you might also mutate certain fields if those are not present in the request. Example, if the resource limits are not set in the pod specs, we can add a specific resource limit for the pod and then forward it down the chain. By doing so, all the pods in the cluster will always have a resource limit set according to your specification unless specified explicitly.
  2. Security: We can reject request that do not follow a particular specification. Example, none of the pod request can have security context set to run as root user.
  3. Uniform workloads: By mutating request and setting default values for specs that aren’t set by a user, we can make sure that workloads running on the cluster are uniform and follow a particular standard defined by the cluster administrator.

That’s all the theory we need to know to start working with Kubernetes Admission Controllers.

Check out my next post on How to implement custom Kubernetes admission controllers

Thanks for taking time to read this article.Your feed backs are always welcome!

Note: CloudLego is providing free training’s on Kubernetes, Terraform, Azure Devops and Azure Cloud. If you or any of your acquaintances are interested please drop an email to support@cloudlego.com and mention your interested topic in the subject line. You will then receive an email with training details. We are doing this particularly for people who are affected by current situation of Software industry but anyone who has an interest to learn is also welcome!

I work on cloud and containerization technologies and interested in coding, problem solving and writing philosophical and motivational quotes.