Difference between Kyverno vs Gatekeeper

Policy Jul 26, 2023

Gatekeeper is a general-purpose policy engine based on Open Policy Agent (OPA). It allows you to define and enforce custom policies across various Kubernetes resources.

Kyverno is specifically designed for Kubernetes policy management. It focuses on validating and mutating resources in Kubernetes to enforce desired configurations and security policies.

Small Comparison of both tools that gives you a clear picture,

GatekeeperKyverno
It acts as an admission controller which means it evaluates policies during the admission of resourcesIt is built using Custom Resource Definitions (CRDs) and operates as a validating and mutating webhook.
It uses the powerful Rego language, part of the OPA project, for defining policiesIt uses a YAML or JSON-based declarative policy language that is easier to read and write for many users
Users should have prior knowledge to understand and write rego policiesUsers are familiar with Kubernetes YAML or JSON which makes it easier to write policies
It does not provide built-in policies out of the box, but there are community-contributed policies available to get startedKyverno comes with a set of built-in policies and examples that cover common use cases
It is more extensible and can be used to enforce policy beyond Kubernetes since it’s general-purpose natureIts primary focus is Kubernetes, making it highly optimised for handling Kubernetes resources and scenarios

Key Points that you don’t miss!!

  • Gatekeeper is an open policy agent with a general-purpose focus, while Kyverno is specifically tailored for Kubernetes.
  • Gatekeeper solely supports validating webhooks, whereas Kyverno offers support for validating, mutating, generating, and image verification webhooks.
  • Gatekeeper can be challenging when it comes to writing simple policies, whereas Kyverno provides a more straightforward implementation experience.
  • Kyverno may face some difficulty with complex custom policies, which can be addressed using rego in the background of the OPA gatekeeper.
  • Kyverno provides a direct method for implementing policies, whereas gatekeeper requires creating CRDs like templates and constraints.

Implementation of Gatekeeper

Installation: Gatekeeper supports three methods of installation.

Install using releases to deploy:COPY

 kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

Deploy using Helm:COPY

 helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
 helm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace

Deploy HEAD using make:COPY

 git clone https://github.com/open-policy-agent/gatekeeper.git
 export DESTINATION_GATEKEEPER_IMAGE=<add registry like "myregistry.docker.io/gatekeeper">
 make docker-buildx REPOSITORY=$DESTINATION_GATEKEEPER_DOCKER_IMAGE OUTPUT_TYPE=type=registry
 make deploy REPOSITORY=$DESTINATION_GATEKEEPER_DOCKER_IMAGE

After successful installation, you can create templates and constraints to implement the policies. Here we are trying to restrict Deployment if the deployment is not having the label “app”. If the specified label is not present it should not be allowed to deploy.

Create a template.yaml file and paste this YAML and apply the fileCOPY

 apiVersion: templates.gatekeeper.sh/v1beta1
 kind: ConstraintTemplate
 metadata:
   name: kubernetesvalidatinglabel
 spec:
   crd:
     spec:
       names:
         kind: KubernetesValidatingLabel
   targets:
     - target: admission.k8s.gatekeeper.sh
       rego: |
         package kubernetes.validating.labels
         import future.keywords.contains
         import future.keywords.if
         import future.keywords.in
         violation[{"msg": msg, "details": {"missing_labels": missing}}] {
           provided := {label | input.review.object.metadata.labels[label]}
           required := {label | label := input.parameters.labels[_]}
           missing := required - provided
           count(missing) > 0
           msg := sprintf("you must provide labels: %v", [missing])
         }

Create a constraint.yaml file and paste this YAML and apply the fileCOPY

 apiVersion: constraints.gatekeeper.sh/v1beta1
 kind: KubernetesValidatingLabel
 metadata:
   name: require-deployment-labels
 spec:
   match:
     kinds:
       - apiGroups:
         kinds:
           - Deployment
   parameters:
     labels:
       - app

After successfully applying the template and constraints we will try to create a deployment without the label app such that we can see the error message.COPY

 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: nginx-deployment
   labels:
     test: prod
 spec:
   replicas: 2
   selector:
     matchLabels:
       test: prod
   template:
     metadata:
       labels:
         test: prod
     spec:
       containers:
       - name: nginx-container
         image: nginx
         ports:
         - containerPort: 80

While applying this YAML you will get a message like thisCOPY

 Error from server (Forbidden): error when creating "deploy.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [require-deployment-labels]
 [require-deployment-labels] you must provide labels: {"app"}

Implementation of Kyverno

Installation:

Installation using Helm:COPY

 helm repo add kyverno https://kyverno.github.io/kyverno/
 helm install kyverno-policies kyverno/kyverno-policies -n kyverno -- create-namespace

Install using YAMLs:COPY

 kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.10.0/install.yaml

Testing unreleased code:COPY

 kubectl create -f https://github.com/kyverno/kyverno/raw/main/config/install-latest-testing.yaml

Here, you can directly create policies using the YAML files. We will create a cluster policy using Kyverno’s CRDsCOPY

 apiVersion: kyverno.io/v1
 # The `ClusterPolicy` kind applies to the entire cluster.
 kind: ClusterPolicy
 metadata:
   name: require-ns-purpose-label
 # The `spec` defines properties of the policy.
 spec:
   # The `validationFailureAction` tells Kyverno if the resource being validated should be allowed but reported (`Audit`) or blocked (`Enforce`).
   validationFailureAction: Enforce
   # The `rules` is one or more rules which must be true.
   rules:
   - name: require-ns-purpose-label
     # The `match` statement sets the scope of what will be checked. In this case, it is any `Namespace` resource.
     match:
       any:
       - resources:
           kinds:
           - Namespace
     # The `validate` statement tries to positively check what is defined. If the statement, when compared with the requested resource, is true, it is allowed. If false, it is blocked.
     validate:
       # The `message` is what gets displayed to a user if this rule fails validation.
       message: "You must have label `purpose` with value `production` set on all new namespaces."
       # The `pattern` object defines what pattern will be checked in the resource. In this case, it is looking for `metadata.labels` with `purpose=production`.
       pattern:
         metadata:
           labels:
             app: test

We are using only one file to apply the policies rather than creating templates and constraints in the gatekeeper.

After applying this policy try to create the same deployment using the deployment file and you will get the error message like this.COPY

 Error from server: error when creating "deploy.yaml": admission webhook "validate.kyverno.svc-fail" denied the request: 
 resource Deployment/default/nginx-deployment was blocked due to the following policies 
 require-ns-purpose-label:
   require-ns-purpose-label: 'validation error: You must have label `purpose` with
     value `production` set on all new namespaces. rule require-ns-purpose-label failed
     at path /metadata/labels/jk/'

If you want to pass the deployment then you should add the label “app” in the metadata of your deployment file.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.