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.

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

Alternatively, use Helm:

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

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.

# 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: "?*"

Applying the policy:

kubectl apply -f kyverno-require-label.yaml
kubectl get clusterpolicy

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.

# 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*"

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.

# 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

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.

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 * * * *"

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.

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)

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

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

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.