CKA Certification Course - Certified Kubernetes Administrator

Scheduling

Solution Admission Controllers 2025 Updates

In this lesson, we walk through the solutions for the admission controllers lab. We will cover the following topics:

• Identifying non-functional admission controllers
• Inspecting enabled admission plugins
• Enabling the NamespaceAutoProvision admission controller
• Disabling the DefaultStorageClass admission controller

Let's dive into each step.


Understanding Admission Controller Functions

For the first question, the lab asks: "What is not a function of admission controllers?"
The correct answer is that admission controllers do not handle user authentication; authentication occurs before admission controllers come into play.

The image shows a KodeKloud practice test interface with a question about the functions of an admission controller, alongside a terminal window.


Listing Enabled Admission Plugins

The next question asks which admission controller is not enabled by default. To determine this, inspect the enabled admission plugins using the kube-apiserver help options. Notice the diagram below:

The image shows a KodeKloud practice test interface with a terminal on the right and a multiple-choice question on the left asking which admission controller is not enabled by default.

Start by listing the pods in the kube-system namespace to locate the kube-apiserver pod:

kubectl get pods -n kube-system

Then, execute the following command on the kube-apiserver pod to list the enabled admission plugins:

kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep 'enable-admission-plugins'

The output displays the default enabled plugins, such as:

• NamespaceLifecycle
• LimitRanger
• ServiceAccount
• TaintNodesByCondition
• Priority
• DefaultTolerationSeconds
• DefaultStorageClass
• StorageObjectInUseProtection
• PersistentVolumeClaimResize
• RuntimeClass
• CertificateApproval
• CertificateSigning
• CertificateSubjectRestriction
• DefaultIngressClass
• MutatingAdmissionWebhook
• ValidatingAdmissionWebhook
• ResourceQuota

For example, NamespaceLifecycle should be enabled by default. If you see both “mutating admission webhook” and “validating admission webhook” in the list, they are active. However, if "NamespaceAutoProvision" is missing, then that admission controller is not enabled by default.


Verifying Explicitly Enabled Admission Controllers

The following question focuses on an admission controller that is normally disabled but is enabled in this cluster. To verify which one it is, inspect the kube-apiserver configuration file located at /etc/kubernetes/manifests/kube-apiserver.yaml. Search for the --enable-admission-plugins parameter using your editor or grep. For example:

kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep 'enable-admission-plugins'

You might see output similar to the snippet below from the manifest file:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.49.219.9:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=10.49.219.9
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction
    - --enable-bootstrap-token-auth=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --insecure-port=0
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt

From this configuration, you can see that NodeRestriction is explicitly enabled. Since this controller is normally disabled by default, its presence indicates that it was deliberately activated.


Enabling NamespaceAutoProvision

The next task instructs you to create an NGINX pod in the "blue" namespace. However, note that the lab explicitly states not to create the namespace manually. Creating the pod with the following command produces an error because the "blue" namespace does not exist:

kubectl run nginx --image nginx -n blue

Expected error:

Error from server (NotFound): namespaces "blue" not found

This error occurs because the Kubernetes "NamespaceExists" admission controller is rejecting requests to create pods within non-existent namespaces. To have Kubernetes automatically create the namespace for you, you need to enable the NamespaceAutoProvision admission controller.

Tip

To automatically handle namespace creation, modify the kube-apiserver manifest to include NamespaceAutoProvision in the enabled plugins list.

To enable it, modify the kube-apiserver manifest located at /etc/kubernetes/manifests/kube-apiserver.yaml. Locate the line with the enabled admission plugins:

grep enable-admission-plugins /etc/kubernetes/manifests/kube-apiserver.yaml

Initially, you will see something like:

- --enable-admission-plugins=NodeRestriction

Edit the file to add NamespaceAutoProvision so that it reads:

- --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision

After saving your changes, the API server pod will restart. Wait a couple of minutes for it to come back online before validating the update.

Now, try creating the NGINX pod again:

kubectl run nginx --image nginx -n blue

If the admission controller is functioning correctly, Kubernetes will automatically create the "blue" namespace. Verify this by listing all namespaces:

kubectl get ns

You should now see an entry for the "blue" namespace, created automatically by the admission controller. Note that NamespaceAutoProvision is deprecated in favor of the NamespaceLifecycle admission controller.


Disabling the DefaultStorageClass Admission Controller

The final part of the lab requires you to disable the DefaultStorageClass admission controller. To do this, reopen the kube-apiserver manifest file:

vi /etc/kubernetes/manifests/kube-apiserver.yaml

Locate the section where the admission plugins are configured. Add a parameter to disable the DefaultStorageClass admission controller so your configuration now includes:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.49.219.9:6443
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=10.49.219.9
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision
    - --disable-admission-plugins=DefaultStorageClass
    - --enable-bootstrap-token-auth=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --insecure-port=0
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt

After saving these changes, let the API server restart. Once it’s back online, validate your cluster configuration by checking that the "blue" namespace still exists and that the nginx pod is correctly running:

kubectl get ns
kubectl run nginx --image nginx -n blue

You can further confirm the changes by listing the running kube-apiserver process and reviewing the enabled and disabled plugins:

ps -ef | grep kube-apiserver

Summary

In this lab, you learned how to: • Identify functionalities not handled by admission controllers
• Verify and inspect enabled admission plugins
• Enable the NamespaceAutoProvision admission controller for automatic namespace creation
• Disable the DefaultStorageClass admission controller via the kube-apiserver manifest
These adjustments help tailor your Kubernetes cluster's behavior to specific requirements.

This concludes the admission controllers lab.

Watch Video

Watch video content

Previous
Admission Controllers 2025 Updates