Stage 5 · Platform
Platform Engineering & Multi-Tenancy
Policy & Governance
Kyverno, Gatekeeper, OPA, and admission control at scale.
Policy Overview
Kubernetes policies enforce rules on resources at admission time. They prevent misconfigurations, enforce security standards, and ensure compliance. Two popular policy engines are Kyverno (Kubernetes-native) and Gatekeeper (OPA-based).
| Feature | Kyverno | Gatekeeper |
|---|---|---|
| Language | YAML | Rego (OPA) |
| Complexity | Low | High |
| Mutation | Yes | Limited |
| Validation | Yes | Yes |
| CRD-based | Yes | Yes |
| Performance | Good | Good |
Kyverno
Kyverno is a Kubernetes-native policy engine. Policies are written in YAML — no new language to learn. Kyverno validates, mutates, and generates resources. It can enforce labels, annotations, resource limits, image registries, and more.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-team-label
match:
any:
- resources:
kinds:
- Deployment
- StatefulSet
- DaemonSet
validate:
message: "The label 'team' is required"
pattern:
metadata:
labels:
team: "?*"
- name: check-app-label
match:
any:
- resources:
kinds:
- Deployment
validate:
message: "The label 'app' is required"
pattern:
metadata:
labels:
app: "?*"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
spec:
validationFailureAction: Enforce
rules:
- name: check-container-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "All containers must have CPU and memory limits"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"The first policy requires 'team' and 'app' labels on Deployments, StatefulSets, and DaemonSets. The second requires resource limits on all containers. validationFailureAction: Enforce rejects non-compliant resources.
Gatekeeper (OPA)
Gatekeeper uses OPA (Open Policy Agent) Rego language for policies. Policies are defined as ConstraintTemplates (Rego logic) and Constraints (specific rules). Gatekeeper is more flexible but requires learning Rego.
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels:
- team
- app
- environmentThe ConstraintTemplate defines Rego logic that checks for required labels. The Constraint applies the template to specific resources with parameters. The Rego code is reusable across multiple constraints.
Common Policy Patterns
Common policy patterns include: requiring labels, restricting image registries, enforcing resource limits, preventing privileged containers, blocking deprecated APIs, and validating NetworkPolicies.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Images must come from approved registries"
pattern:
spec:
containers:
- image: "ghcr.io/my-org/* | gcr.io/my-project/* | docker.io/library/*"This policy only allows images from three approved registries. Any pod using images from other registries is rejected. The | operator means OR — images from any of the three registries are allowed.
Enforcement Modes
Policies can run in audit or enforce mode. Audit mode logs violations without blocking them. Enforce mode rejects non-compliant resources. Start with audit mode to see what would be blocked, then switch to enforce once you've fixed existing violations.
# Audit mode — logs violations but allows creation
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: audit-policy
spec:
validationFailureAction: Audit # Don't block, just log
rules:
- name: check-labels
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Missing recommended labels"
pattern:
metadata:
labels:
app: "?*"
---
# Enforce mode — rejects non-compliant resources
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: enforce-policy
spec:
validationFailureAction: Enforce # Block non-compliant
rules:
- name: require-limits
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Resource limits required"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"Start with Audit mode. Check violations with kubectl get events -w or Kyverno policy reports. Fix existing resources, then switch to Enforce. This prevents breaking existing workloads.
Policy Testing
# Install kyverno CLI
brew install kyverno-cli
# Test policy against manifests
kyverno test ./tests/
---
# tests/test-policy.yaml
apiVersion: kyverno.io/v1alpha1
kind: Test
metadata:
name: require-labels-test
policies:
- require-labels.yaml
resources:
- name: good-pod
apiVersion: v1
kind: Pod
metadata:
labels:
app: test
expected:
result: pass
- name: bad-pod
apiVersion: v1
kind: Pod
metadata: {}
expected:
result: failThe kyverno test command validates policies against test cases. Each test case specifies a resource and expected result (pass/fail). Run tests in CI to catch policy regressions before deployment.
Kyverno generates PolicyReport CRDs showing compliance status per namespace. Install the policy-reporter to view reports in a UI. This helps teams understand which policies are blocking their workloads.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.