Kyverno: Kubernetes-Policies ohne Rego
Das Policy-Problem in Kubernetes
Wer Kubernetes-Cluster betreibt, kennt das Problem: Je mehr Teams und Services auf einem Cluster arbeiten, desto wichtiger werden verbindliche Regeln. Kein Container soll mit dem latest-Tag in Production landen. Jedes Deployment braucht Resource Limits. Neue Namespaces sollen automatisch eine NetworkPolicy bekommen. Diese Anforderungen manuell durchzusetzen -- per Dokumentation und Code Review -- skaliert nicht.
Wir bei encircle360 haben dieses Thema in den vergangenen Jahren immer wieder berührt. In unserem Artikel zu Kubernetes in Production haben wir beschrieben, wie wichtig Resource Limits und saubere Konfigurationen sind. Aber wir haben damals noch nicht beantwortet, wie man diese Standards automatisiert durchsetzt. Genau hier kommen Policy Engines ins Spiel.
OPA Gatekeeper: Der etablierte Ansatz
Der bekannteste Kandidat in diesem Bereich ist OPA Gatekeeper -- eine Kombination aus dem Open Policy Agent und einer Kubernetes-spezifischen Integration. OPA ist ein mächtiges, universelles Policy-Framework. Es nutzt Rego, eine deklarative Abfragesprache, die an Datalog angelehnt ist.
Wir haben OPA Gatekeeper Anfang 2021 evaluiert und waren von der Flexibilität beeindruckt. Rego kann im Grunde jede erdenkliche Policy abbilden. Das Problem: Die Lernkurve ist steil. Rego ist keine Sprache, die ein Kubernetes-Administrator mal eben an einem Nachmittag lernt. Die Syntax ist ungewöhnt, das Debugging umständlich, und für einfache Policies wie "verbiete den latest-Tag" schreibt man überraschend viel Code.
Ein Beispiel -- diese Rego-Policy verbietet den latest-Tag:
package k8scontainerlimits
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
endswith(container.image, ":latest")
msg := sprintf("Container '%v' uses the latest tag", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not contains(container.image, ":")
msg := sprintf("Container '%v' has no tag specified", [container.name])
}
Dazu kommen noch das ConstraintTemplate und das Constraint als Kubernetes-Ressourcen. Für ein Team, das primär mit YAML und Helm arbeitet, ist das eine hohe Einstiegshürde.
Kyverno: Der Kubernetes-native Ansatz
Dann sind wir auf Kyverno gestoßen. Kyverno wurde Ende 2020 in Version 1.0 veröffentlicht und ist seit Mitte 2021 ein CNCF-Sandbox-Projekt. Zum Zeitpunkt dieses Artikels steht Version 1.5 zur Verfügung, und das Projekt gewinnt sichtbar an Traktion in der Community.
Der fundamentale Unterschied zu OPA Gatekeeper: Kyverno-Policies werden in reinem YAML geschrieben. Keine neue Sprache, kein separates Tooling. Wer Kubernetes-Manifeste schreiben kann, kann auch Kyverno-Policies schreiben. Für uns war das der entscheidende Faktor.
Kyverno integriert sich als Admission Webhook in den Kubernetes API Server. Jede Anfrage an die API -- sei es das Erstellen eines Pods, das Aktualisieren eines Deployments oder das Anlegen eines Namespaces -- durchläuft die konfigurierten Policies. Kyverno kann dabei drei Dinge tun: validieren, mutieren und generieren.
Validation: Regeln durchsetzen
Die offensichtlichste Funktion ist Validation. Eine Policy prüft eingehende Ressourcen gegen definierte Kriterien und lehnt sie ab, wenn sie nicht passen.
Das Beispiel von oben -- den latest-Tag verbieten -- sieht in Kyverno so aus:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
policies.kyverno.io/title: Disallow Latest Tag
policies.kyverno.io/description: >-
Der latest-Tag ist nicht deterministisch und sollte
in Production nicht verwendet werden.
spec:
validationFailureAction: enforce
rules:
- name: validate-image-tag
match:
resources:
kinds:
- Pod
validate:
message: "Der Tag 'latest' ist nicht erlaubt. Bitte einen spezifischen Tag verwenden."
pattern:
spec:
containers:
- image: "!*:latest"
Das ist reines YAML. Keine neue Sprache, kein Kompilieren, kein separates Testing-Framework. Die Policy beschreibt das gewünschte Muster, und Kyverno lehnt alles ab, was nicht passt. Der validationFailureAction: enforce sorgt dafür, dass die Policy tatsächlich blockiert -- im Gegensatz zu audit, das nur einen Report erstellt, ohne die Anfrage abzulehnen.
Für den Einstieg empfehlen wir, neue Policies zuerst im Audit-Modus laufen zu lassen. So sieht man, welche bestehenden Ressourcen die Policy verletzen würden, ohne den laufenden Betrieb zu stören.
Mutation: Ressourcen automatisch anpassen
Mutation ist die zweite Säule von Kyverno und in der Praxis mindestens so wertvoll wie Validation. Eine Mutation-Policy verändert eingehende Ressourcen automatisch, bevor sie im Cluster landen.
Ein typischer Anwendungsfall: Standard-Labels auf alle Deployments setzen. In unseren Clustern wollen wir, dass jedes Deployment mindestens ein managed-by-Label und ein team-Label trägt.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
rules:
- name: add-labels
match:
resources:
kinds:
- Deployment
- StatefulSet
mutate:
patchStrategicMerge:
metadata:
labels:
+(app.kubernetes.io/managed-by): kyverno
+(encircle360.com/policy-version): "1.0"
Das +-Präfix vor dem Label-Key bedeutet: Füge dieses Label nur hinzu, wenn es noch nicht existiert. Bestehende Labels werden nicht überschrieben. Diese kleine Syntax-Konvention macht Mutation-Policies sicher und vorhersagbar.
Wir nutzen Mutation-Policies außerdem, um automatisch Resource Requests auf Pods zu setzen, die ohne definiert wurden, und um Annotations für unser Monitoring-System hinzuzufügen. Das reduziert die Menge an Boilerplate in unseren Helm Charts erheblich.
Generation: Ressourcen automatisch erstellen
Die dritte Funktion von Kyverno ist Generation -- und sie hat uns am meisten überrascht. Eine Generate-Policy erstellt automatisch neue Kubernetes-Ressourcen als Reaktion auf andere Ereignisse.
Unser konkreter Anwendungsfall: Jeder neue Namespace soll automatisch eine Standard-NetworkPolicy bekommen, die allen Egress-Traffic erlaubt, aber Ingress-Traffic auf explizit freigegebene Ports beschränkt. Früher haben wir das manuell gemacht oder über ein Shell-Script in der CI-Pipeline gelöst. Mit Kyverno geht das deklarativ:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-networkpolicy
spec:
rules:
- name: default-deny-ingress
match:
resources:
kinds:
- Namespace
exclude:
resources:
namespaces:
- kube-system
- kube-public
- kyverno
generate:
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
data:
spec:
podSelector: {}
policyTypes:
- Ingress
Sobald jemand einen neuen Namespace anlegt, erstellt Kyverno automatisch die NetworkPolicy darin. Die exclude-Regel sorgt dafür, dass System-Namespaces nicht betroffen sind. Das ist ein mächtiges Konzept, das weit über NetworkPolicies hinausgeht. Wir experimentieren aktuell damit, auch Standard-ResourceQuotas und LimitRanges automatisch generieren zu lassen.
Kyverno vs. OPA Gatekeeper: Unsere Einschätzung
Nach mehreren Monaten mit Kyverno in Staging und Production können wir einen recht klaren Vergleich ziehen.
OPA Gatekeeper ist das mächtigere, flexiblere Tool. Rego kann Policies abbilden, die in Kyvernos YAML-Ansatz schwer oder gar nicht umsetzbar sind -- etwa komplexe Cross-Resource-Validierungen oder Policies, die externe Datenquellen einbeziehen. Für Organisationen mit einem dedizierten Platform-Engineering-Team, das die Zeit und Motivation hat, Rego zu lernen und zu pflegen, ist OPA Gatekeeper eine exzellente Wahl.
Für uns -- ein kleineres Team, das Kubernetes als Werkzeug nutzt, nicht als Selbstzweck -- war Kyverno die bessere Entscheidung. Die Einstiegshürde ist minimal. Jeder im Team, der YAML lesen kann, kann Kyverno-Policies lesen, verstehen und anpassen. Neue Policies sind in Minuten geschrieben, nicht in Stunden. Und für die allermeisten Anwendungsfälle -- Tag-Validierung, Label-Standards, Default-Ressourcen -- reicht Kyvernos Funktionsumfang vollkommen aus.
Ein praktischer Vorteil, der oft übersehen wird: Kyverno-Policies sind reguläre Kubernetes-Ressourcen. Man kann sie mit kubectl verwalten, in Helm Charts paketieren und über die gleichen GitOps-Workflows deployen, die man für alle anderen Ressourcen nutzt. Es gibt keine separate Toolchain, keinen zusätzlichen Build-Schritt.
Installation und erste Schritte
Die Installation ist unkompliziert -- ein einzelnes Helm Chart:
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
Kyverno bringt auch eine wachsende Bibliothek an vorgefertigten Policies mit, die Best Practices abdecken. Auf der offiziellen Website findet man Policies für Pod Security Standards, Best Practices und Compliance-Anforderungen. Viele davon konnten wir direkt übernehmen oder mit minimalen Anpassungen nutzen.
Fazit
Kyverno ist knapp ein Jahr nach dem 1.0-Release bereits ein ernstzunehmender Akteur im Kubernetes-Policy-Bereich. Das Projekt löst ein reales Problem auf eine Art, die zum Kubernetes-Ökosystem passt: deklarativ, YAML-basiert und ohne unnötigen Overhead.
Für Teams, die Policy-Enforcement einführen wollen, ohne eine neue Programmiersprache zu lernen, ist Kyverno unsere klare Empfehlung. Es deckt die häufigsten Anwendungsfälle ab -- Validation, Mutation, Generation -- und integriert sich nahtlos in bestehende Workflows. Die Kombination aus niedriger Einstiegshürde und hohem praktischen Nutzen hat uns überzeugt.
Unser nächster Schritt ist die Integration von Kyverno in unsere CI-Pipeline, um Policies schon beim Helm-Template-Rendering zu validieren -- bevor die Manifeste überhaupt den Cluster erreichen. Aber dazu vielleicht ein anderes Mal mehr.
Geschrieben von
Patrick HütterGründer & Software-Architekt
Softwarearchitekt, Ingenieur und Unternehmer. Patrick baut seit über einem Jahrzehnt Produkte und Plattformen — von Enterprise-Backends über Cloud-Native-Infrastruktur bis hin zu KI-gestützten Anwendungen. Als Gründer von encircle360 verbindet er technische Tiefe mit unternehmerischem Denken und treibt Open-Source-Projekte voran, die echten Impact haben.
Das könnte dich auch interessieren
CI-Runner in der microVM: Docker-Builds mit Kata Containers auf Kubernetes
31.08.2026 · 10 Min. Lesezeit
GitOps mit Helmfile und Kyverno: Unser Deployment-Workflow
10.03.2025 · 7 Min. Lesezeit
K3s und KubeVirt: Konvergente Infrastruktur auf Bare Metal
20.01.2025 · 6 Min. Lesezeit