Cloud Native 20 min read

Mastering Kyverno: From Installation to Advanced Policy Management in Kubernetes

This guide walks you through Kyverno, the CNCF‑graduated Kubernetes policy engine, covering its architecture, high‑availability installation, creation of validation, mutation, generation, and cleanup policies, as well as advanced features like variables, JMESPath expressions, and integration with Helm and the Kyverno Playground.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Mastering Kyverno: From Installation to Advanced Policy Management in Kubernetes

Kyverno is an open‑source policy engine originally from Nirmata and now part of the CNCF. It provides validation, mutation, generation, and cleanup capabilities for Kubernetes resources without requiring a dedicated language.

Kyverno runs as a dynamic admission controller, receiving AdmissionReview callbacks from the kube‑apiserver and applying matching policies to either accept or reject requests. Policies can match resources by kind, name, and label selectors, and support wildcard names.

Policy execution is captured via Kubernetes events, and the overall architecture is illustrated in the diagram below.

High‑availability installations run multiple Kyverno replicas, each hosting several controllers that handle AdmissionReview requests (

AdmissionReview

), monitor policies (

PolicyController

), and manage generated resources (

GenerateController

).

Installation

Kyverno requires a Kubernetes cluster version ≥ v1.14. For a v1.28.x cluster, install the latest 1.11.4 release.

<code>kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.11.3/install.yaml</code>

Alternatively, use Helm:

<code>helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm upgrade --install kyverno kyverno/kyverno -n kube-kyverno --create-namespace</code>

Installation creates the

kube-kyverno

namespace and installs the required CRDs, admission controller, reports controller, cleanup controller, and background controller.

Policies and Rules

A Kyverno policy is a collection of rules. Each rule contains a

match

clause, an optional

exclude

clause, and one of the action clauses:

validate

,

mutate

,

generate

, or

verifyImages

. Only one action can be defined per rule.

Policies can be cluster‑wide (

ClusterPolicy

) or namespace‑scoped (

Policy

).

Policy applies only to resources within its own namespace.

ClusterPolicy applies to resources across all namespaces.

Policy Definition Example – Validation

The following policy enforces that every Pod carries a

kyverno

label. It uses

validationFailureAction

set to

Enforce

, which blocks non‑compliant resources.

<code># kyverno-require-label.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-label-policy
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-for-labels
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "label 'kyverno' is required"
      pattern:
        metadata:
          labels:
            kyverno: "?*"
</code>

Applying the policy:

<code>kubectl apply -f kyverno-require-label.yaml
kubectl get clusterpolicy
</code>

Creating a Pod without the label results in an admission error, while adding the label allows successful creation.

Policy Definition Example – Mutation

This policy adds the label

kyverno=nginx

to any Pod that uses an image containing

nginx

.

<code># kyverno-mutate-label.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: nginx-label-policy
spec:
  rules:
  - name: nginx-label
    match:
      resources:
        kinds:
        - Pod
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            kyverno: nginx
        spec:
          (containers):
            - (image): "*nginx*"
</code>

After applying the policy, a newly created

nginx

Pod automatically receives the label.

Policy Definition Example – Generation

Generation rules can create auxiliary resources. The example synchronizes a

regcred

Secret from the

default

namespace to any newly created namespace.

<code># kyverno-generate-secret.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: sync-secrets-policy
spec:
  rules:
  - name: sync-image-pull-secret
    match:
      any:
      - resources:
          kinds:
          - Namespace
    generate:
      apiVersion: v1
      kind: Secret
      name: regcred
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      clone:
        namespace: default
        name: regcred
</code>

Creating a new namespace automatically creates a copy of the

regcred

Secret inside it.

Policy Definition Example – Cleanup

Cleanup policies declaratively delete resources. The example removes Deployments labeled

canremove:true

when they have fewer than two replicas, running every five minutes.

<code>apiVersion: kyverno.io/v2beta1
kind: ClusterCleanupPolicy
metadata:
  name: cleandeploy
spec:
  match:
    any:
    - resources:
        kinds:
        - Deployment
        selector:
          matchLabels:
            canremove: "true"
  conditions:
    any:
    - key: "{{ target.spec.replicas }}"
      operator: LessThan
      value: 2
  schedule: "*/5 * * * *"
</code>

Cleanup can also be driven by a TTL label such as

cleanup.kyverno.io/ttl: 2m

on any resource.

Policy Variables

Variables let policies reference dynamic data from the admission request, ConfigMaps, the API server, OCI registries, or external services. Kyverno stores data as JSON and uses JMESPath expressions to extract values, referenced with

{{key.path}}

syntax.

Predefined variables include

serviceAccountName

,

serviceAccountNamespace

,

request.roles

,

request.clusterRoles

, and

images

.

Variables can be escaped with a leading backslash (

\{{...}}

) when the literal string is needed.

Advanced Example – Injecting OTEL Environment Variables

The policy below mutates Pods to add several environment variables, including

OTEL_RESOURCE_ATTRIBUTES

that references other variables using the

$(...)

syntax.

<code>apiVersion: kyverno.io/v1
kind: Policy
metadata:
  name: add-otel-resource-env
  namespace: foobar
spec:
  background: false
  rules:
  - name: imbue-pod-spec
    match:
      any:
      - resources:
          kinds:
          - v1/Pod
    mutate:
      patchStrategicMerge:
        spec:
          containers:
          - (name): "?*"
            env:
            - name: NODE_NAME
              value: "mutated_name"
            - name: POD_IP_ADDRESS
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: POD_SERVICE_ACCOUNT
              valueFrom:
                fieldRef:
                  fieldPath: spec.serviceAccountName
            - name: OTEL_RESOURCE_ATTRIBUTES
              value: >-
                k8s.namespace.name=\$(POD_NAMESPACE),
                k8s.node.name=\$(NODE_NAME),
                k8s.pod.name=\$(POD_NAME),
                k8s.pod.primary_ip_address=\$(POD_IP_ADDRESS),
                k8s.pod.service_account.name=\$(POD_SERVICE_ACCOUNT),
                rule_applied=$(./../../../../../../../../name)
</code>

When the mutated Pod runs, it prints the composed

OTEL_RESOURCE_ATTRIBUTES

value, demonstrating variable substitution.

For more Kyverno policies and examples, visit the official website https://kyverno.io/policies or use the Kyverno Playground to test your policies.

KubernetesInfrastructure as CodePolicy EngineAdmission ControlKyverno
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.