No! You shall not pass! Kyverno’s here!
Hi everyone! This is a blog for DigitalOcean Kubernetes Challenge 2021 and I’m taking a challenge to deploy a solution for policy enforcement using Kyverno. It’s a really easy one to do if you have some concept about Kubernetes dynamic admission control in your mind so let’s start!
But what is Kyverno? And what it does?
Well, Kyverno is nothing than just a deployment in your cluster but with special roles ✨. It’s acting as a Dynamic Admission Control plugin of your cluster. When you are going to create some resources in the cluster, the manifest you sent to Kubernetes API must pass many stages before they get created as a resource you desire. Two stages in which we are interesting are Mutating Admission and Validating admission.
The mutating admission stage will be done first by modifying the manifest you sent to the Kubernetes API, after that, your manifest is going to be validated based on their object schema (i.e. The fields are the right data type? Do required fields are filled? etc.), then it’s going to reach validating stage which will judge if your manifest meet the policy existing the cluster. If there’s no problem, congratulations! Your resource is going to be created. But if not, validating admission will either log the error or reject the creation of that resource depending on your configuration.
Those 2 stages are containing their configurations which will act as a webhook to the service you install and intend to make them be a mutation or validation webhook. You can also have more than one webhook in each stage.
As I said, Kyverno will act as both mutation and validation webhook to help enforce your policy in a much easier way. You don’t need to create your webhook service and think about how you will handle the policy you created. Just use Kyverno, create your policies and pass them to Kyverno. Tada! Easily done.
Sounds fun! Let’s try it!
Of course, first thing first, we’re going to need a Kubernetes cluster as our playground. Thanks to DigitalOcean, we can create it in just a few clicks.
All you need is just choose your cluster’s version, region, node pool, and some other fancy options. Then choose a good name for it and let’s click Create Cluster
After a while, your cluster will be created and ready to go. You can follow the instruction on the cluster summary page to access your cluster. You can either use your old friend kubectl or use DigitalOcean’s doctl. Pick one you are comfortable with.
Kyverno’s installation documentation has provided many ways to install it on our cluster. I will be going with helm today. I will assume that everyone has helm installed on their machine already. Just run these commands and you will get Kyverno installed.
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo updatehelm install kyverno kyverno/kyverno --namespace kyverno --create-namespace # this will create new kyverno namespace for you
helm install kyverno-policies kyverno/kyverno-policies --namespace kyverno
Field test time
It’s up and running so let’s give it some tests. For the challenge, you are tasked to create a policy that mandatory labels for every deployment and image download is only permitted from DigitalOcean Container Registry (DOCR)
Let’s say if I want to make sure every deployment that entered my cluster must have labels
kyverno.dok8s.wowza/label-needed (with any value), I can create a policy like this to validate those deployments applied
Let’s try creating a deployment that won’t go along with the policy
kubectl create deployment nginx --image=nginx
Ah-ha! Nicely done. Now let’s try creating a good deployment (according to our policy)
Now you can see that the new deployment which has the label
kyverno.dok8s.wowza/label-needed passed the Kyverno. But the pod didn’t need to have the label required like deployment. Pop quiz time: can we enforce both deployment and pod to have the label required? Of course, we can. Just add some modifications to the kind we wanted to match in the policy.
The newly added spec block reflects the pod spec in our deployment manifest so let’s see what’ll happen when I try to create a new deployment using the previous manifest.
NOICE! The deployment got blocked. If we wanted to deploy it again, we must edit the pod’s label to match the policy
Good! Now let’s move on to the next task. “Image download is only permitted from DigitalOcean Container Registry”
So basically we need to create a policy to watch for the pod whose image repo is not DOCR. This can be done with this policy.
You might be wondering “What? It’s that easy? And what if I have more than 1 container in a pod?” Don’t worry. Kyverno is really smart to enforce the policy on all array members so you’re covered here. And you might notice that you can use the wildcard
* to indicate any repo/image/tags is fine as long as they’re from DOCR. You can see more fancy matching pattern from Kyverno documentation here
Let’s apply it and test with this deployment, which must not pass our policy
As expected, Kyverno won’t allow us to create the deployment if the image of the container inside the pod is not from DOCR. Let’s make it right then.
Good! Since we compile the policy, Kyverno allows us to create the deployment. And you can see that I have 2 containers, both are images from DOCR. But what if someone sneaky-sneaky inserts another image that is not from DOCR?
Yep! Kyverno won’t let that escape it. Good guy Kyverno
It’s your adventure now!
That’s all for the challenge’s write-up today. This is just a small path of Kyverno and what it can do, as well as the DigitalOcean universe. Now it’s your turn to discover their potency and use them to enhance your cluster! Happy Ops-ing!