Kyverno is a great tool that can be installed into any Kubernetes cluster, allowing cluster administrators to enforce policies for resources in the cluster, and even modify resources before they are applied. Kyverno can be used to ensure deployments are secure, ensure deployments meet certain organizational criteria (e.g. define a cost center label), or even ensure all deployments mount a common volume.
Kyverno works by deploying a pod and services into your existing cluster. It creates multiple Admission Webhooks in the cluster. These webhooks are responsible for handling API requests coming in to Kubernetes and either validating something from the request (Validating Admission Webhook, or modifying the request before it is applied (Mutating Admission Webhook).
In the diagram below, you can see where in the process of an API call to Kubernetes, each of the Mutating Admission and Validating Admission webhooks will run.
All of the Kubernetes Manifests and Kyverno Policies are available in this GitHub repo.
Deploying Kyverno
Getting started with Kyverno is pretty simple. While there are a lot of knobs that can be turned to configure Kyverno, the initial default goes a long way. I deployed this into my DigitalOcean Kubernetes cluster.
To install, I simply ran:
$ helm repo add kyverno https://kyverno.github.io/kyverno/ $ helm repo update $ helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace
I now have a single Kyverno pod running in the cluster:
$ kubectl get pods -n kyverno NAME READY STATUS RESTARTS AGE kyverno-6d94754db4-tdl9s 1/1 Running 0 5s
Policies
Anatomy of a basic policy
Policies can be written with many different options in Kyverno. The most basic policies can be written to check values of specific field(s) within an API request to Kubernetes, and make a decision whether the request should be allowed or not.
Require specific pod labels
This example requires specific labels to be set on a pod prior to creating those resources. One of the great benefits Kyverno provides is that you can specify Pod
as the resource kind, but it will also check against the policy whenever creating resources which will end up creating pods (Deployment, StatefulSet, etc.)
The below example policy requires that all pods have the labels.acmecorp.com/costCenter
and labels.acmecorp.com/department
labels. They can be set to any value.
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-business-labels annotations: policies.kyverno.io/title: Require Business Labels policies.kyverno.io/category: Best Practices policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod, Label policies.kyverno.io/description: >- Define required labels used by our internal business processes to understand which applications are running in each cluster, and used to handle chargeback activities for resources consumed by this specific application. spec: validationFailureAction: enforce background: false rules: - name: check-for-business-labels match: resources: kinds: - Pod validate: message: "The labels `labels.acmecorp.com/costCenter` and `labels.acmecorp.com/department` are required." pattern: metadata: labels: labels.acmecorp.com/costCenter: "?*" labels.acmecorp.com/department: "?*"
Example Policy Tests:
- Example Deployment which will be denied under this policy.
- Example Deployment which will be allowed under this policy.
Demo showing policy in cluster:
Require the use of a specific container registry
This policy checks for 2 important items: 1. images specified in a pod definition must be from a specific container registry (in this case, from the DigitalOcean registry); and 2. images cannot have the latest
tag.
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: restrict-image-registries annotations: policies.kyverno.io/title: Restrict Image Registries and Latest policies.kyverno.io/category: Best Practices policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- Requires all images for pods be sourced from the Digital Ocean Container Registry. Any other image sources are denied. spec: validationFailureAction: enforce background: false rules: - name: validate-registries match: resources: kinds: - Pod validate: message: "Unknown image registry." pattern: spec: containers: - image: "registry.digitalocean.com/*" - name: validate-image-tag match: resources: kinds: - Pod validate: message: "Must not use the tag `latest` on any images." pattern: spec: containers: - image: "!*:latest"
Example Policy Tests:
- Example Deployment which will be denied under this policy.
- Example Deployment which will be allowed under this policy.
Demo showing policy in cluster:
Require a runAsUser be specified
This policy requires that every container specified within a pod has a runAsUser
defined and that the value is greater than 0
, meaning the container cannot run as root. In reality, there are additional items you will probably want to check in a policy like this, but this provides a good place to get started.
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-pod-runasuser annotations: policies.kyverno.io/title: Require the RunAsUser to be Specified policies.kyverno.io/category: Best Practices policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- Requires Pods to specify as runAsUser value within their containers which are not root. spec: validationFailureAction: enforce background: false rules: - name: check-userid match: resources: kinds: - Pod validate: message: >- The field spec.containers.*.securityContext.runAsUser must specified and greater than zero. pattern: spec: containers: - securityContext: runAsUser: ">0"
Example Policy Tests:
- Example Deployment which will be denied under this policy.
- Example Deployment which will be allowed under this policy.
Demo showing policy in cluster:
Conclusion
Overall, this is meant to be a couple basic examples of using policies with Kyverno in Kubernetes. You can certainly get much more complex, or implement a policy which mutates a resource, to keep resources in your cluster compliant with your rules.
If you end up trying Kyverno and find out you need something more complex, take a look at Gatekeeper. The Gatekeeper project works very similar to Kyverno, except it allows for defining policies in Rego language, which adds complexity but allow for additional customization.
Top comments (0)