Veröffentlicht am

Kyverno Policies: Policy-as-Code ohne Rego in YAML

Teilen:
Authors

Kubernetes Kyverno: Policy-as-Code fuer Compliance Automation

TL;DR

  • Kyverno ist eine Kubernetes-native Policy Engine, die Policies in reinem YAML definiert -- kein Rego, kein neues Programmiermodell noetig.
  • Drei Policy-Typen decken alle Anwendungsfaelle ab: Validate (blockiert non-compliant Ressourcen), Mutate (korrigiert automatisch) und Generate (erstellt zusaetzliche Ressourcen).
  • Im Audit-Modus protokolliert Kyverno Verstoesse ohne zu blockieren. Im Enforce-Modus werden non-compliant Requests abgelehnt.
  • Policy Reports liefern einen zentralen Ueberblick ueber den Compliance-Status aller Namespaces.
  • Im Vergleich zu OPA Gatekeeper ist die Lernkurve deutlich flacher: Kubernetes-Admins schreiben Kyverno Policies, ohne eine neue Sprache lernen zu muessen.

Das Problem: Compliance ohne Automatisierung

In jedem Kubernetes-Cluster gibt es Regeln: Jeder Pod braucht Resource Limits. Container duerfen nicht als Root laufen. Bestimmte Labels muessen gesetzt sein. Images duerfen nur aus der internen Registry kommen.

Diese Regeln stehen typischerweise in einem Wiki oder im Kopf des Senior Engineers. Neue Teammitglieder kennen sie nicht. CI/CD-Pipelines pruefen sie nicht. Das Ergebnis: Abweichungen haeufen sich, bis ein Security-Audit die Luecken aufdeckt.

Policy-as-Code automatisiert die Durchsetzung. Regeln werden als Code definiert, versioniert und automatisch geprueft.

Kyverno vs. OPA Gatekeeper

EigenschaftKyvernoOPA Gatekeeper
Policy-SpracheYAML (Kubernetes-nativ)Rego (eigene Sprache)
LernkurveFlach (YAML reicht)Steil (Rego lernen)
ValidateJaJa
MutateJa (nativ)Eingeschraenkt
GenerateJa (erstellt Ressourcen)Nein
Image VerificationJa (Cosign, Notary)Ueber externe Tools
Policy ReportsJa (PolicyReport CRD)Ueber Audit-Logs
CNCF-StatusGraduated (2024)Graduated (2021)

Fuer Teams ohne Rego-Expertise ist Kubernetes Kyverno der pragmatischere Weg. Weitere Policy-Ansaetze unter Kubernetes Policy Automation.

Installation per Helm

helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

helm install kyverno kyverno/kyverno \
  --namespace kyverno \
  --create-namespace \
  --set admissionController.replicas=3 \
  --set backgroundController.replicas=2 \
  --set reportsController.replicas=2 \
  --wait

kubectl get pods -n kyverno
# NAME                                             READY   STATUS    AGE
# kyverno-admission-controller-6d8b7c5f4-xxxxx     1/1     Running   45s
# kyverno-admission-controller-6d8b7c5f4-yyyyy     1/1     Running   45s
# kyverno-admission-controller-6d8b7c5f4-zzzzz     1/1     Running   45s
# kyverno-background-controller-7f9b8d6c5-xxxxx    1/1     Running   45s
# kyverno-reports-controller-9d8c7f6b5-xxxxx       1/1     Running   45s

Mindestens 3 Replicas des Admission Controllers sind Pflicht fuer Produktion. Kyverno sitzt als Webhook im kritischen Pfad jeder API-Anfrage.

Validate: Non-Compliant blockieren

Labels erzwingen

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
  annotations:
    policies.kyverno.io/title: Require Labels
    policies.kyverno.io/severity: medium
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: check-required-labels
      match:
        any:
          - resources:
              kinds:
                - Deployment
      validate:
        message: "Labels 'app', 'team' und 'environment' sind Pflicht."
        pattern:
          metadata:
            labels:
              app: "?*"
              team: "?*"
              environment: "dev | staging | production"
# Test: Deployment ohne Labels wird abgelehnt
kubectl create deployment nginx --image=nginx
# Error: resource Deployment/default/nginx was blocked due to the following policies:
# require-labels: check-required-labels: Labels 'app', 'team' und 'environment' sind Pflicht.

Resource Limits erzwingen

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resource-limits
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Jeder Container braucht CPU und Memory Limits."
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"

Privilegierte Container verbieten

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  rules:
    - name: no-privileged
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Privilegierte Container sind verboten."
        pattern:
          spec:
            containers:
              - securityContext:
                  privileged: "false"
                  allowPrivilegeEscalation: "false"

Mutate: Automatisch korrigieren

Mutate-Policies aendern eingehende Ressourcen, bevor sie im Cluster landen:

Security Context automatisch setzen

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-security-context
spec:
  rules:
    - name: add-run-as-nonroot
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          spec:
            securityContext:
              runAsNonRoot: true
              seccompProfile:
                type: RuntimeDefault
            containers:
              - (name): "*"
                securityContext:
                  allowPrivilegeEscalation: false
                  readOnlyRootFilesystem: true
                  capabilities:
                    drop:
                      - ALL

Default-Labels hinzufuegen

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-labels
spec:
  rules:
    - name: add-managed-by
      match:
        any:
          - resources:
              kinds:
                - Deployment
                - StatefulSet
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              managed-by: "kyverno"
              cost-center: "{{request.namespace}}"

Generate: Ressourcen automatisch erstellen

Generate-Policies erstellen Kubernetes-Ressourcen bei bestimmten Events. Haeufigster Anwendungsfall: Bei jedem neuen Namespace automatisch NetworkPolicy und ResourceQuota anlegen.

NetworkPolicy pro Namespace

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-default-networkpolicy
spec:
  rules:
    - name: default-deny-ingress
      match:
        any:
          - resources:
              kinds:
                - Namespace
      exclude:
        any:
          - resources:
              namespaces:
                - kube-system
                - kyverno
                - monitoring
      generate:
        synchronize: true
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny-ingress
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress

ResourceQuota pro Team-Namespace

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-default-quota
spec:
  rules:
    - name: default-quota
      match:
        any:
          - resources:
              kinds:
                - Namespace
              selector:
                matchLabels:
                  type: "team-namespace"
      generate:
        synchronize: true
        apiVersion: v1
        kind: ResourceQuota
        name: default-quota
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            hard:
              requests.cpu: "4"
              requests.memory: "8Gi"
              limits.cpu: "8"
              limits.memory: "16Gi"
              pods: "50"

Mit synchronize: true stellt Kyverno geloeschte Ressourcen automatisch wieder her.

ClusterPolicy vs. Policy

ClusterPolicy gilt cluster-weit und wird vom Platform-Team verwaltet. Policy gilt nur im eigenen Namespace und kann von Team-Ownern erstellt werden. In der Praxis definiert das Platform-Team ClusterPolicies fuer grundlegende Compliance, waehrend Teams eigene Policies ergaenzen.

Audit vs. Enforce: Schrittweiser Rollout

Neue Kyverno Policies niemals direkt auf Enforce setzen. Der empfohlene Rollout:

Phase 1 -- Audit (Woche 1-4): Policies protokollieren Verstoesse, blockieren aber nichts.

spec:
  validationFailureAction: Audit
kubectl get polr -A
# NAMESPACE   NAME              PASS   FAIL   WARN   ERROR
# default     polr-ns-default   12     5      0      0
# backend     polr-ns-backend   45     3      0      0

Phase 2 -- Fehler beheben (Woche 2-6): Bestehende Workloads anpassen.

Phase 3 -- Enforce mit Exceptions (Woche 4-8): Fuer Legacy-Workloads PolicyExceptions definieren:

apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
  name: legacy-app-exception
  namespace: legacy
spec:
  exceptions:
    - policyName: require-resource-limits
      ruleNames:
        - check-limits
  match:
    any:
      - resources:
          kinds:
            - Pod
          namespaces:
            - legacy

CI/CD-Integration mit Kyverno CLI

Kyverno Policies koennen auch in der Pipeline geprueft werden, bevor Manifeste den Cluster erreichen:

# Manifeste lokal gegen Policies pruefen
kubectl kyverno apply ./policies/ --resource ./manifests/deployment.yaml
# pass: 3, fail: 1, warn: 0, error: 0, skip: 0
# FAILED: require-resource-limits / check-limits

Die Kyverno CLI laesst sich direkt in GitHub Actions, GitLab CI oder Jenkins einbinden. Damit werden Policy-Verstoesse bereits im Pull Request sichtbar -- nicht erst beim Deployment. Mehr zu Security in CI/CD: Kubernetes Security Scanning automatisiert.

Monitoring: Policy Reports

Kyverno erstellt automatisch PolicyReport-Ressourcen. Mit dem Policy Reporter (installierbar per Helm: helm install policy-reporter policy-reporter/policy-reporter) werden sie in Grafana sichtbar.

Prometheus-Metriken:

# Compliance-Rate pro Namespace
sum(policy_report_result{status="pass"}) by (namespace) /
(sum(policy_report_result{status="pass"}) by (namespace) +
 sum(policy_report_result{status="fail"}) by (namespace)) * 100

Fuer ein vollstaendiges Monitoring-Setup: Kubernetes Observability Stack.

Best Practices

  1. Audit zuerst, dann Enforce: Immer im Audit-Modus starten und Reports auswerten.
  2. Policies in Git versionieren: Aenderungen ueber Pull Requests mit Review-Prozess.
  3. Annotations nutzen: policies.kyverno.io/title, description und severity machen Policies selbstdokumentierend.
  4. System-Namespaces excluden: kube-system, kyverno und monitoring von den meisten Policies ausnehmen.
  5. Generate mit synchronize: synchronize: true damit Kyverno geloeschte Ressourcen wiederherstellt.
  6. Failure Policy verstehen: failurePolicy: Ignore laesst Requests durch wenn Kyverno ausfaellt -- in Produktion oft sicherer als Fail, um Cluster-Lockouts zu vermeiden.

Weitere Compliance-Strategien unter Kubernetes Compliance Automation.

Verwandte Artikel


Wenn ihr Kyverno Policies fuer euren Cluster planen, OPA-Gatekeeper-Regeln migrieren oder ein Compliance-Dashboard aufbauen wollt, meldet euch unter /kontakt -- wir unterstuetzen bei Policy-Design, Rollout und Monitoring.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen