Kyverno Quick Start
This section is intended to provide you with some quick guides on how to get Kyverno up and running and demonstrate a few of Kyverno’s seminal features. There are quick start guides which focus on validation, mutation, as well as generation allowing you to select the one (or all) which is most relevant to your use case.
These guides are intended for proof-of-concept or lab demonstrations only and not recommended as a guide for production. Please see the installation page for more complete information on how to install Kyverno in production.
These guides require Kyverno v1.17.0 or later, the first verified release serving policies.kyverno.io/v1 for the ValidatingPolicy, MutatingPolicy, and GeneratingPolicy resources. Kyverno v1.16.0 serves these policy resources only at v1alpha1, not v1.
First, install the current Kyverno release using Helm:
helm repo add kyverno https://kyverno.github.io/kyverno/helm repo updatehelm install kyverno kyverno/kyverno -n kyverno --create-namespaceNext, select the quick start guide in which you are interested. Alternatively, start at the top and work your way down.
The validation and mutation examples do not require registry credentials or Secrets. The generation example is a separate, lab-only Secret demonstration.
Validate Resources
Section titled “Validate Resources”In the validation guide, you will see how simple an example Kyverno policy can be which ensures a label called team is present on every Pod. Validation is the most common use case for policy and functions as a “yes” or “no” decision making process. Resources which are compliant with the policy are allowed to pass (“yes, this is allowed”) and those which are not compliant may not be allowed to pass (“no, this is not allowed”).
Add the policy below to your cluster. It contains a single validation rule that requires all Pods in quick-start-validation to have the team label. Kyverno supports different policy types to validate, mutate, generate, cleanup, and verify image configurations. The validationActions field is set to Deny to block Pods that are non-compliant.
Create a namespace for this example. All Pods in this example will be in this namespace.
kubectl create namespace quick-start-validationkubectl create -f- << EOFapiVersion: policies.kyverno.io/v1kind: ValidatingPolicymetadata: name: require-labelsspec: validationActions: - Deny autogen: podControllers: controllers: - deployments matchConstraints: namespaceSelector: matchLabels: kubernetes.io/metadata.name: quick-start-validation resourceRules: - apiGroups: [''] apiVersions: ['v1'] operations: ['CREATE', 'UPDATE'] resources: ['pods'] validations: - message: "label 'team' is required" expression: "has(object.metadata.labels) && has(object.metadata.labels.team) && object.metadata.labels.team != ''"EOFTry creating a Deployment without the required label.
kubectl -n quick-start-validation create deployment nginx --image=nginxThe admission request should be denied with the message label 'team' is required.
Although the policy matches on Pods, Kyverno can also apply it to Pod controllers such as Deployments using auto-generation.
Now, create a Pod with the required label.
kubectl -n quick-start-validation run nginx --image registry.k8s.io/pause:3.10 --labels team=backendThis Pod configuration is compliant with the policy and is allowed.
Now that you’ve experienced validation, clean up by deleting the policy and namespace you created above.
kubectl delete validatingpolicy require-labelskubectl delete namespace quick-start-validationDeleting the namespace also removes the Deployment (if it was allowed) and the Pod created in this workflow.
Congratulations, you’ve just implemented a validation policy in your Kubernetes cluster! For more details on validation policies, see the ValidatingPolicy section.
Mutate Resources
Section titled “Mutate Resources”Mutation is the ability to change or “mutate” a resource in some way prior to it being admitted into the cluster. A mutate rule is similar to a validate rule in that it selects some type of resource (like Pods or ConfigMaps) and defines what the desired state should look like.
Add this Kyverno mutate policy to your cluster. This policy will add the label team to any new Pod and give it the value of bravo but only if a Pod does not already have this label assigned. Kyverno uses CEL expressions to perform conditional logic, making policies easy to write and read.
Create a namespace for this example.
kubectl create namespace quick-start-mutationkubectl create -f- << EOFapiVersion: policies.kyverno.io/v1kind: MutatingPolicymetadata: name: add-labelsspec: matchConstraints: namespaceSelector: matchLabels: kubernetes.io/metadata.name: quick-start-mutation resourceRules: - apiGroups: [''] apiVersions: ['v1'] operations: ['CREATE', 'UPDATE'] resources: ['pods'] matchConditions: - name: team-label-missing expression: '!has(object.metadata.labels) || !has(object.metadata.labels.team)' mutations: - patchType: ApplyConfiguration applyConfiguration: expression: > Object{ metadata: Object.metadata{ labels: Object.metadata.labels{ team: "bravo" } } }EOFLet’s now create a new Pod which does not have the desired label defined.
kubectl -n quick-start-mutation run redis --image registry.k8s.io/pause:3.10Once the Pod has been created, get the Pod to see if the team label was added.
kubectl -n quick-start-mutation get pod redis --show-labelsYou should see that the label team=bravo has been added by Kyverno.
Try one more Pod, this time one which does already define the team label.
kubectl -n quick-start-mutation run newredis --image registry.k8s.io/pause:3.10 -l team=alphaGet this Pod back and check once again for labels.
kubectl -n quick-start-mutation get pod newredis --show-labelsThis time, you should see Kyverno did not add the team label with the value defined in the policy since one was already found on the Pod.
Now that you’ve experienced mutate policies and seen how logic can be written easily, clean up by deleting the policy you created above.
kubectl delete mutatingpolicy add-labelskubectl delete namespace quick-start-mutationDeleting the namespace also removes both Pods created in this workflow.
Congratulations, you’ve just implemented a mutation policy in your Kubernetes cluster! For more details on mutate policies, see the MutatingPolicy section.
Generate Resources
Section titled “Generate Resources”Kyverno can generate (create) a Kubernetes resource based upon a definition stored in a policy. This example copies an image pull Secret once into one lab namespace.
Create the source namespace and a dummy image pull Secret. The .invalid domain and placeholder password are not real registry credentials and cannot authenticate to a registry.
kubectl create namespace quick-start-sourcekubectl -n quick-start-source create secret docker-registry regcred \ --docker-server=registry.example.invalid \ --docker-username=demo-user \ --docker-password=replace-with-non-sensitive-placeholder \ --docker-email=demo@example.invalidCreate a Role and RoleBinding that allow the background-controller to read only the source Secret named regcred.
kubectl apply -f- << EOFapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: kyverno-quick-start-source-secret namespace: quick-start-sourcerules:- apiGroups: - '' resources: - secrets resourceNames: - regcred verbs: - get---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: kyverno-quick-start-source-secret namespace: quick-start-sourcesubjects:- kind: ServiceAccount name: kyverno-background-controller namespace: kyvernoroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kyverno-quick-start-source-secret---apiVersion: v1kind: Namespacemetadata: name: quick-start-generated---apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: kyverno-quick-start-generated-secret namespace: quick-start-generatedrules:- apiGroups: - '' resources: - secrets resourceNames: - regcred verbs: - get- apiGroups: - '' resources: - secrets verbs: - create---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: kyverno-quick-start-generated-secret namespace: quick-start-generatedsubjects:- kind: ServiceAccount name: kyverno-background-controller namespace: kyvernoroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kyverno-quick-start-generated-secretEOFThe source Role is limited to reading regcred. In the destination namespace, the controller can read only regcred and create Secrets. Kubernetes RBAC cannot restrict create by resource name, so keep this namespace dedicated to the example. Create the policy below after both Roles and RoleBindings exist. It matches only the update that first adds the readiness label as true, so later namespace updates do not rerun generation.
kubectl create -f- << EOFapiVersion: policies.kyverno.io/v1kind: GeneratingPolicymetadata: name: sync-secretsspec: matchConstraints: resourceRules: - apiGroups: [''] apiVersions: ['v1'] operations: ['UPDATE'] resources: ['namespaces'] matchConditions: - name: destination-namespace-ready expression: "object.metadata.name == 'quick-start-generated' && object.metadata.labels.exists(k, k == 'quick-start.kyverno.io/ready' && object.metadata.labels[k] == 'true') && (!has(oldObject.metadata.labels) || !oldObject.metadata.labels.exists(k, k == 'quick-start.kyverno.io/ready'))" variables: - name: targetNs expression: 'object.metadata.name' - name: sourceSecret expression: 'resource.Get("v1", "secrets", "quick-start-source", "regcred")' generate: - expression: 'generator.Apply(variables.targetNs, [variables.sourceSecret])'EOFWait for the policy to be ready, then enable generation by updating the destination namespace label.
kubectl wait --for='jsonpath={.status.conditionStatus.ready}=true' generatingpolicy/sync-secrets --timeout=120skubectl label namespace quick-start-generated quick-start.kyverno.io/ready=trueGet the generated Secret:
kubectl wait --for=create secret/regcred -n quick-start-generated --timeout=120skubectl -n quick-start-generated get secretYou should see that Kyverno generated regcred from the source Secret in quick-start-source.
With a basic understanding of generate policies, clean up all resources created by this example.
kubectl delete generatingpolicy sync-secretskubectl -n quick-start-generated delete secret regcred --ignore-not-foundkubectl -n quick-start-generated delete rolebinding kyverno-quick-start-generated-secretkubectl -n quick-start-generated delete role kyverno-quick-start-generated-secretkubectl -n quick-start-source delete rolebinding kyverno-quick-start-source-secretkubectl -n quick-start-source delete role kyverno-quick-start-source-secretkubectl -n quick-start-source delete secret regcredkubectl delete namespace quick-start-generated quick-start-sourceCongratulations, you’ve just implemented a generation policy in your Kubernetes cluster! For more details on generate policies, see the GeneratingPolicy section.
When you finish all the guides, remove the Kyverno release and its namespace from a dedicated lab cluster:
helm uninstall kyverno -n kyvernokubectl delete namespace kyvernoHelm retains some Kyverno CRDs after uninstall. Keep any remaining CRDs on a shared cluster; to remove them from an isolated lab, delete the disposable cluster instead of deleting CRDs that may contain other policies or resources.