Difference between Kyverno vs Gatekeeper
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,
Gatekeeper | Kyverno |
It acts as an admission controller which means it evaluates policies during the admission of resources | It 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 policies | It 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 policies | Users 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 started | Kyverno 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 nature | Its 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.