Undoubtedly, Kubernetes has become the standard for container orchestration, making it necessary to work with extensions that add a layer of security and modularity.
So, what exactly are these extensions? According to the Kubernetes documentation, “An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized.”
In essence, these extensions help us define and govern operations for our Kubernetes cluster. They act as a security checkpoint before object data from API requests is executed or stored into etcd.
In this blog, I will show you how to install and configure these admission controllers. For your information, you can find the list of all functions of the admission controller for version 1.26 of Kubernetes in the official documentation.
Deploy status
In this blog, I suggest testing two admission controllers, which are the ImagePolicyWebhook and the NodeRestriction, which will check and validate if a pod can be deployed or not. First, let’s test the deployment of an nginx pod with version 1.42.
kubectl run nginx --image=nginx:1.14.2
kubectl get pod --watch
nabil@dbi-master01:~$ kubectl run nginx --image=nginx:1.14.2
pod/nginx created
nabil@dbi-master01:~$ kubectl get pod --watch
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 13s
The pod is running, so we can delete it.
kubectl delete pod nginx
Check the configuration
Check the Kubernetes setup currently being used. This should show the admissionregistration.k8s.io/vi
API.:
kubectl api-versions | grep admissionregistration
nabil@dbi-master01:~$ kubectl api-versions | grep admissionregistration
admissionregistration.k8s.io/v1
Dump the k8s cluster configuration to display the references to mutating webhooks and validating webhooks, but without image policy webhooks:
kubectl cluster-info dump | grep -i imagepolicyWebhook
nabil@dbi-master01:~$ kubectl cluster-info dump | grep -i imagepolicyWebhook
nabil@dbi-master01:~$
Normally, the command should return nothing as you can see above.
Enable Controller
We will now activate the admission controller. Simply edit the kubernetes apiserver manfiest file , look for the --enable-admission-plugins
flag in the configuration section of the kube-apiserver and add the ImagePolicyWebhook plugin at the end of the line to enable the webhook.
With a high user privilege, edit the /etc/kubernetes/manifests/kube-apiserver.yaml
file
nabil@dbi-master01:~$ sudo su -
[sudo] password for nabil:
root@dbi-master01:~# vi /etc/kubernetes/manifests/kube-apiserver.yaml
Navigate down to the spec code block to find the --enable-admission-plugins
line (here, the 6th flag in the kube-apiserver spec).
spec:
containers:
- command:
- kube-apiserver
- --admission-control-config-file=/etc/kubernetes/admission-control/admission-control.conf
- --advertise-address=*.*.*.*
- --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
- --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
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-issuer=https://kubernetes.default.svc.cluster.local
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.*.*.*/12
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
Add ImagePolicyWebhook at the end of the line to enable the webhook:
--enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
Save and exit. Then, check the status of the server:
kubectl get nodes
The connection may be refused, as the cluster take few minutes to set up the configuration.
nabil@dbi-master01:~$ kubectl get nodes
The connection to the server 10.*.*.*:6443 was refused - did you specify the right host or port?
Keep cool! Wait and retry a couple of minutes later to the nodes UP and RUNNING (Ready state).
nabil@dbi-master01:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane 58m v1.25.0
k8s-worker01 Ready <none> 57m v1.25.0
Test the setup
Search again to see if the image policy webhook is enabled:
kubectl cluster-info dump | grep ImagePolicyWebhook
nabil@dbi-master01:~$ kubectl cluster-info dump | grep ImagePolicyWebhook
"--enable-admission-plugins=NodeRestriction,ImagePolicyWebhook",
I0704 13:21:57.710001 1 plugins.go:161] Loaded 12 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,ImagePolicyWebhook,PodSecurity,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota.
I0704 13:21:57.711659 1 plugins.go:161] Loaded 12 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,ImagePolicyWebhook,PodSecurity,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota.
I0704 13:21:58.647369 1 plugins.go:161] Loaded 12 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,ImagePolicyWebhook,PodSecurity,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota.
nabil@dbi-master01:~$
We can clearly see here that the command returns that the image policy webhook is enabled, unlike the previous paragraph where the command returned nothing
Now, we will try to deploy a nginx image which contain some known vulnerabilities:
kubectl run nginx --image=1.14.2
nabil@dbi-master01:~$ kubectl run nginx --image=1.14.2
Error from server (Forbidden): pods "nginx" is forbidden: image policy webhook backend denied one or more images: Image(s) contain serious vulnerabilities: [1.14.2]
nabil@dbi-master01:~$
This time, the deployment should be denied from being provisioned because of image vulnerabilities.
Now, try with a busybox image:
kubectl run busybox --image=busybox:1.36.1
nabil@dbi-master01:~$ kubectl run busybox --image=busybox:1.36.1
pod/busybox created
The pod is created successfully, meaning the webhook works as intended.
Good job, you have successfully activated and used an admission controller.
deep
16.08.2023Hi, where is your backen service please ?