Admission Control
Kyverno
A Kubernetes native policy engine for validating, mutating, and generating resources.
Kyverno is a policy engine built specifically for Kubernetes. Policies are written as Kubernetes resources in YAML, so there is no new language to learn for common rules.
Kyverno installs as a set of admission webhooks and can do three things:
- validate: reject or flag objects that break a rule
- mutate: patch objects on the way in, for example adding default labels
- generate: create companion resources, for example a default
NetworkPolicyfor every new namespace
Install
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno \
--namespace kyverno --create-namespace
Verify the controllers are running:
kubectl get pods -n kyverno
Expected output:
NAME READY STATUS RESTARTS AGE
kyverno-admission-controller-... 1/1 Running 0 60s
kyverno-background-controller-... 1/1 Running 0 60s
kyverno-cleanup-controller-... 1/1 Running 0 60s
kyverno-reports-controller-... 1/1 Running 0 60s
Write A Validation Policy
This ClusterPolicy rejects privileged containers. The pattern mirrors the shape of a pod spec; =(...) means “if this field is present, it must match”:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
spec:
validationFailureAction: Enforce
background: true
rules:
- name: privileged-containers
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "Privileged containers are not allowed."
pattern:
spec:
containers:
- =(securityContext):
=(privileged): "false"
Apply it and test:
kubectl apply -f disallow-privileged.yaml
kubectl run priv --image=busybox:1.36 --restart=Never -n lab \
--overrides='{"spec":{"containers":[{"name":"priv","image":"busybox:1.36","command":["sleep","3600"],"securityContext":{"privileged":true}}]}}'
Expected output:
Error from server: admission webhook "validate.kyverno.svc-fail" denied the request:
resource Pod/lab/priv was blocked due to the following policies
disallow-privileged-containers:
privileged-containers: 'validation error: Privileged containers are not allowed. ...'
An unprivileged pod still runs:
kubectl run ok --image=busybox:1.36 --restart=Never -n lab -- sleep 3600
Audit Mode And Policy Reports
Set validationFailureAction: Audit and Kyverno records violations instead of blocking. Because background: true, existing resources are scanned too:
kubectl get policyreport -A
The report lists pass and fail counts per namespace. This is the safe way to trial a policy against a live cluster before switching it to Enforce.
Ready-Made Policies
The Kyverno project maintains a large policy library, including a full implementation of the Pod Security Standards, at kyverno.io/policies. Starting from the library and tightening is faster and safer than writing rules from scratch.
Clean Up
kubectl delete pod ok -n lab
kubectl delete clusterpolicy disallow-privileged-containers
helm uninstall kyverno -n kyverno
kubectl delete namespace kyverno
Practical Guidance
- Start every policy in
Auditmode, review the policy reports, then move toEnforce. - Keep
background: trueso violations in existing objects are visible, not just new ones. - Prefer validation over mutation; silent mutation surprises the people who own the manifests.
- Match on
Podfor runtime truth, but remember blocked deployment pods fail quietly inside the ReplicaSet, so checkkubectl describe replicasetwhen a rollout stalls. - Kyverno itself runs with high privileges; pin its version, restrict who can edit
ClusterPolicyobjects, and monitor its webhook availability.