Oktober 2026
M D M D F S S
 1234
567891011
12131415161718
19202122232425
262728293031  

Bisher war die Reihenfolge klar: Wer eine eigene Admission-Regel durchsetzen wollte, die es in Kubernetes von Haus aus nicht gibt, hat eine dritte Komponente in den Cluster geholt, Kyverno oder OPA Gatekeeper, mit eigenem Lebenszyklus, eigenen CRDs, eigenem Betriebsaufwand. Seit Kubernetes 1.30 gibt es eine zweite Option, bevor du zu diesem Schritt greifst: ValidatingAdmissionPolicy (VAP), ein direkt in den kube-apiserver eingebauter Validator, der eigene Regeln in CEL (Common Expression Language) formuliert, ohne dass dafür irgendetwas zusätzlich installiert werden muss.

Dieser Artikel zeigt, wie eine ValidatingAdmissionPolicy tatsächlich aussieht, wo sie seit welcher Version steht und wo ihre Grenze verläuft.

Seit wann VAP eingebaut und stabil ist

Laut Kubernetes-Dokumentation ist der Feature-Status eindeutig vermerkt: „Feature state: Stable since Kubernetes v1.30.“ ValidatingAdmissionPolicy ist damit kein Beta-Feature mehr, sondern GA, kein Feature-Gate muss mehr aktiviert werden. Die Dokumentation beschreibt den Mechanismus als „a declarative, in-process alternative to validating admission webhooks“. In-process heißt: Die Regel läuft im kube-apiserver selbst, nicht als externer Webhook-Aufruf an einen separaten Controller wie bei Kyverno oder OPA Gatekeeper. Das spart nicht nur eine Komponente, sondern auch die Latenz und die Fehlerquelle eines Netzwerk-Hops bei jeder einzelnen Admission-Prüfung.

Minimalbeispiel: Policy und Binding gehören zusammen

Eine ValidatingAdmissionPolicy allein hat laut Dokumentation keine Wirkung: „At least a ValidatingAdmissionPolicy and a corresponding ValidatingAdmissionPolicyBinding must be defined for a policy to have an effect.“ Die Policy definiert die Regel und auf welche Ressourcen sie grundsätzlich passt, das Binding entscheidet, wo sie tatsächlich greift und was bei einem Verstoß passiert.

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "demo-policy.example.com"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: "object.spec.replicas <= 5"
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "demo-binding-test.example.com"
spec:
policyName: "demo-policy.example.com"
validationActions: [Deny]
matchResources:
namespaceSelector:
matchLabels:
environment: test

spec.validations enthält laut Dokumentation CEL-Ausdrücke, die die Anfrage prüfen: „If an expression evaluates to false, the validation check is enforced according to the spec.failurePolicy field.“ In diesem Beispiel wird jedes Deployment im Namespace-Label environment: test abgelehnt, sobald spec.replicas über 5 liegt, weil das Binding validationActions: [Deny] setzt. Die Policy selbst ist clusterweit gültig und wiederverwendbar, das Binding entscheidet pro Anwendungsfall, wo und wie streng sie wirkt. Neben Deny kennt validationActions laut Dokumentation auch Warn und Audit, für den schrittweisen Einstieg ohne sofortige Blockade.

Parametrisierte Regeln statt hartcodierter Werte

Eine hartcodierte Grenze wie <= 5 reicht selten für mehr als eine Team oder Umgebung. Für genau diesen Fall erlaubt VAP, die Policy an eine eigene Parameter-Ressource zu binden:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "deploy-replica-policy.example.com"
spec:
paramKind:
apiVersion: rules.example.com/v1
kind: ReplicaLimit
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: "object.spec.replicas <= params.maxReplicas"
messageExpression: "'object.spec.replicas must be no greater than ' + string(params.maxReplicas)"
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "replica-limit-test.example.com"
spec:
policyName: "deploy-replica-policy.example.com"
validationActions: [Deny]
paramRef:
name: "replica-limit-test.example.com"
namespace: "default"
parameterNotFoundAction: Deny

params.maxReplicas kommt zur Laufzeit aus der referenzierten ReplicaLimit-Ressource, dasselbe Policy-Objekt lässt sich damit über mehrere Bindings mit unterschiedlichen Grenzwerten wiederverwenden, zum Beispiel ein Namespace mit maxReplicas: 3 und ein anderer mit maxReplicas: 20. messageExpression liefert laut Dokumentation statt der generischen CEL-Fehlermeldung einen lesbaren Text, im Beispiel oben wörtlich: „object.spec.replicas must be no greater than 3“. Für Policies, die zwingend Parameter brauchen, empfiehlt die Dokumentation zusätzlich eine eigene Null-Prüfung im ersten Ausdruck: params != null.

Wo die eingebaute Grenze endet

VAP deckt Validierung ab, nicht Mutation. Die Dokumentation grenzt den Mechanismus ausdrücklich als Alternative zu validierenden Webhooks ein, nicht zu mutierenden. Wer Felder eines Objekts nicht nur prüfen, sondern automatisch ergänzen oder korrigieren will, etwa ein fehlendes Label setzen oder einen Standardwert einfügen, braucht die separate MutatingAdmissionPolicy. Die ist seit Kubernetes 1.36 ebenfalls stabil und standardmäßig aktiv, war davor mehrere Versionen lang Beta hinter einem eigenen Feature-Gate.

Zweite Grenze: der Rechenaufwand jedes CEL-Ausdrucks ist begrenzt. Laut Kubernetes-API-Referenz gilt: „Each evaluation of the policy is given an independent CEL cost budget“, und die Ausdrücke einer Policy müssen laut derselben Referenz unter einem Maximalbudget bleiben: „The CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget.“ Ein zu teurer Ausdruck wird abgelehnt, bevor er überhaupt zur Laufzeit zum Zug kommt. Konkrete Zahlenwerte für dieses Budget nennt die aktuelle Referenzseite an der von mir geprüften Stelle nicht; wer an die Grenze stößt, bekommt das über eine Fehlermeldung beim Anlegen der Policy zu sehen, nicht erst im Betrieb.

Dritte Grenze: Komplexität über mehrere Ressourcen oder externe Zustände hinweg. Ein CEL-Ausdruck in spec.validations prüft das eingehende Objekt (object), das alte Objekt bei Updates (oldObject) und optional Parameter (params), aber keine beliebigen zusätzlichen API-Aufrufe zur Laufzeit, keine externen Datenquellen, keine Policy-Ketten mit eigener Ablauflogik über mehrere Schritte. Genau das ist die Domäne, in der Kyverno oder OPA Gatekeeper mit ihrer eigenen Policy-Sprache und ihrem eigenen Controller-Lebenszyklus weiterhin ihren Platz haben.

Abgrenzung zu zwei früheren Beiträgen

Im Beitrag Admission Control im Cluster: Kyverno und Policy Controller praktisch vom 03.08.2026 ging es um den Betrieb einer dritten Policy-Engine im Cluster: Installation, Lebenszyklus, Policy-Sprache, laufender Controller. Hier geht es um den Punkt davor: wann du diese dritte Komponente für eine eigene Regel überhaupt brauchst, und wann der eingebaute, GA-gesetzte CEL-Validator im kube-apiserver ausreicht, ganz ohne zusätzlichen Betrieb.

Im Beitrag Pod Security Admission: die eingebaute Kubernetes-Grenze vom 21.09.2026 ging es um Pod Security Admission (PSA), die ebenfalls eingebaut ist, aber nur die drei vordefinierten, nicht veränderbaren Pod Security Standards (privileged, baseline, restricted) durchsetzt. PSA deckt genau diese drei Stufen ab, nicht mehr und nicht weniger. ValidatingAdmissionPolicy ist für eigene Regeln gedacht, die über diese drei Standardstufen hinausgehen, etwa Replica-Grenzen, Namenskonventionen oder Feldwerte, die PSA strukturell nicht kennt.

Entscheidung: VAP, Kyverno/Gatekeeper, oder beides

Lässt sich deine Regel in einem oder wenigen CEL-Ausdrücken formulieren, bezieht sie sich auf das Objekt selbst, sein Vorgängerobjekt und höchstens eine Parameter-Ressource, und braucht sie keine Mutation, ist ValidatingAdmissionPolicy der kürzere Weg: kein Helm-Chart, kein Update-Zyklus einer dritten Komponente, kein zusätzlicher Controller, der selbst wieder überwacht werden muss. Brauchst du Mutation, Regelketten mit mehreren aufeinander aufbauenden Schritten, Reporting-Oberflächen für Policy-Verstöße oder eine Policy-Sprache, die über einzelne CEL-Ausdrücke hinaus strukturiert bleiben soll, bleibt Kyverno oder OPA Gatekeeper die richtige Wahl. Beides lässt sich nebeneinander betreiben: VAP für die einfachen, klar abgrenzbaren Validierungsregeln, die dritte Engine für alles, was CEL allein nicht mehr sauber abbildet.

Fragen zur Einordnung von ValidatingAdmissionPolicy in deinem Cluster: Schreib mir an mm@mhm-dl.de.

Über das Anmeldeformular für den Newsletter trägst du deine E-Mail-Adresse ein, kreuzt die Einwilligung an und bestätigst die Anmeldung danach per Mail. Mit der Anmeldung willigst du ein, dass der Newsletter unter anderem folgende Themen behandelt: Schulungen zu Docker, Kubernetes, CI/CD, Git-Workflows und DevSecOps-Werkzeugen sowie die Anforderungen aus NIS2, CRA und DORA und deren technische Umsetzung.

Kommentar verfassen

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..