Veröffentlicht am

Kubernetes Compliance automatisieren mit Policy-as-Code

Teilen:
Authors

TL;DR

  • Policy-as-Code ersetzt manuelle Checklisten durch automatisierte, Git-versionierte Regeln, die bei jedem Deployment durchgesetzt werden
  • OPA/Gatekeeper nutzt die Sprache Rego fuer maximale Flexibilitaet -- geeignet fuer komplexe, organisationsuebergreifende Policy-Frameworks
  • Kyverno schreibt Policies in nativem YAML ohne eigene Sprache -- deutlich niedrigere Einstiegshuerde fuer Kubernetes-Teams
  • Admission Controller fangen Policy-Verstoesse ab, bevor Ressourcen im Cluster erstellt werden -- Shift-Left fuer Security und Compliance
  • Audit-Reporting mit beiden Tools generiert nachweisbare Compliance-Reports fuer BSI-Audits und NIS2-Pruefungen

Kubernetes Policy Automation: Compliance automatisieren statt manuell pruefen

Manuelle Compliance-Pruefungen skalieren nicht. Ein Cluster mit 200 Deployments, 50 Namespaces und 15 Entwicklerteams kann nicht durch woechentliche Reviews abgesichert werden. Bis der Auditor einen Verstoss findet, laeuft der betroffene Pod seit Wochen in Produktion.

Policy-as-Code loest dieses Problem: Compliance-Anforderungen werden als maschinenlesbare Regeln definiert, in Git versioniert und automatisch bei jedem Deployment durchgesetzt. Kein Pod kommt in den Cluster, der gegen die Regeln verstoesst.

In der Kubernetes-Welt haben sich zwei Tools etabliert: OPA/Gatekeeper und Kyverno. Beide arbeiten als Admission Controller, beide koennen Policies durchsetzen und auditieren. Die Unterschiede liegen in der Sprache, der Architektur und der Lernkurve.


Wie Admission Controller funktionieren

Wenn kubectl apply ausgefuehrt wird, durchlaeuft die Anfrage mehrere Stationen:

kubectl apply
    |
    v
API Server */} Authentication */} Authorization */} Mutating Admission
    |                                                      |
    v                                                      v
etcd <-- Validating Admission <-- Schema Validation <-- Webhook

Admission Controller sitzen zwischen Authorization und der Speicherung in etcd. Es gibt zwei Typen:

  • Mutating Admission Webhooks: Koennen Ressourcen veraendern (z.B. Labels hinzufuegen, Security Contexts setzen)
  • Validating Admission Webhooks: Koennen Ressourcen ablehnen (z.B. wenn kein Resource Limit gesetzt ist)

Sowohl OPA/Gatekeeper als auch Kyverno registrieren sich als Admission Webhooks beim API Server.


OPA/Gatekeeper: Maximale Flexibilitaet

Architektur

Open Policy Agent (OPA) ist eine allgemeine Policy-Engine, die nicht nur fuer Kubernetes gedacht ist. Gatekeeper ist der Kubernetes-spezifische Adapter, der OPA als Admission Controller integriert.

Gatekeeper fuehrt zwei Custom Resources ein:

  • ConstraintTemplate: Definiert die Policy-Logik in Rego (OPAs Policy-Sprache)
  • Constraint: Wendet ein Template auf bestimmte Ressourcen an

Beispiel: Container-Images nur aus erlaubten Registries

# ConstraintTemplate: Definiert die Regel in Rego
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8sallowedregistries
spec:
  crd:
    spec:
      names:
        kind: K8sAllowedRegistries
      validation:
        openAPIV3Schema:
          type: object
          properties:
            registries:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sallowedregistries

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not startswith(container.image, input.parameters.registries[_])
          msg := sprintf(
            "Container '%s' verwendet Image '%s' aus nicht erlaubter Registry. Erlaubt: %v",
            [container.name, container.image, input.parameters.registries]
          )
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.initContainers[_]
          not startswith(container.image, input.parameters.registries[_])
          msg := sprintf(
            "Init-Container '%s' verwendet Image '%s' aus nicht erlaubter Registry. Erlaubt: %v",
            [container.name, container.image, input.parameters.registries]
          )
        }
---
# Constraint: Wendet die Regel an
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRegistries
metadata:
  name: nur-interne-registries
spec:
  enforcementAction: deny
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
      - apiGroups: ["apps"]
        kinds: ["Deployment", "StatefulSet", "DaemonSet"]
    namespaces:
      - produktion
      - staging
  parameters:
    registries:
      - "harbor.unternehmen.de/"
      - "registry.unternehmen.de/"

Staerken und Schwaechen von OPA/Gatekeeper

AspektBewertung
FlexibilitaetSehr hoch -- Rego kann beliebig komplexe Logik ausdruecken
LernkurveSteil -- Rego ist eine eigene Programmiersprache
EcosystemGross -- OPA wird auch ausserhalb von Kubernetes eingesetzt
PerformanceGut -- Policies werden kompiliert
MutationSeit Gatekeeper v3.14 unterstuetzt, aber weniger ausgereift als bei Kyverno
AuditIntegriert -- Gatekeeper prueft bestehende Ressourcen periodisch

Kyverno: Kubernetes-native Policies in YAML

Architektur

Kyverno wurde speziell fuer Kubernetes gebaut. Policies werden in YAML geschrieben, ohne eine eigene Sprache lernen zu muessen. Das macht den Einstieg deutlich einfacher, besonders fuer Teams, die bereits mit Kubernetes-Manifesten vertraut sind.

Kyverno-Policies koennen drei Dinge:

  • Validate: Ressourcen ablehnen, die gegen Regeln verstossen
  • Mutate: Ressourcen beim Erstellen veraendern (z.B. Labels hinzufuegen)
  • Generate: Automatisch zusaetzliche Ressourcen erstellen (z.B. NetworkPolicies)

Beispiel: Gleiche Registry-Policy in Kyverno

# Kyverno ClusterPolicy: Nur erlaubte Container Registries
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: nur-erlaubte-registries
  annotations:
    policies.kyverno.io/title: Erlaubte Container Registries
    policies.kyverno.io/category: Supply Chain Security
    policies.kyverno.io/severity: high
    policies.kyverno.io/description: >-
      Stellt sicher, dass nur Container-Images aus internen
      Registries deployed werden. Erfuellt BSI IT-Grundschutz
      APP.4.4.A14 (Schutz vor schadhaften Images).
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: validate-container-registry
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - produktion
                - staging
      validate:
        message: >-
          Image {{ request.object.spec.containers[].image }} stammt
          nicht aus einer erlaubten Registry.
          Erlaubt sind: harbor.unternehmen.de/ und registry.unternehmen.de/
        pattern:
          spec:
            containers:
              - image: "harbor.unternehmen.de/*"
            =(initContainers):
              - image: "harbor.unternehmen.de/*"
---
# Kyverno Mutating Policy: Automatisch Labels und Security Context setzen
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: security-defaults-erzwingen
spec:
  rules:
    - name: set-security-context
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          spec:
            containers:
              - (name): "*"
                securityContext:
                  allowPrivilegeEscalation: false
                  readOnlyRootFilesystem: true
                  runAsNonRoot: true
                  capabilities:
                    drop:
                      - ALL

Der Unterschied ist sofort sichtbar: Kyverno-Policies lesen sich wie Standard-Kubernetes-YAML. Kein Rego, keine neue Syntax.


OPA/Gatekeeper vs. Kyverno: Direktvergleich

KriteriumOPA/GatekeeperKyverno
Policy-SpracheRego (eigene Sprache)YAML (Kubernetes-nativ)
Lernkurve2-4 Wochen fuer Rego1-2 Tage fuer K8s-erfahrene Teams
ValidationJaJa
MutationJa (seit v3.14)Ja (ausgereift, Kernfeature)
GenerationNeinJa (z.B. auto NetworkPolicies)
Image VerificationNein (extern)Ja (Cosign/Notary integriert)
Audit/ReportingGatekeeper AuditPolicy Reports (PolicyReport CRD)
CLI Testingopa test + gatorkyverno apply (lokal testen)
CNCF StatusGraduated (OPA)Incubating
Community-GroesseGroesserSchnell wachsend
Cluster-externe NutzungJa (OPA ist universell)Nein (nur Kubernetes)

Empfehlung

Fuer die meisten Mittelstands-Teams ist Kyverno die bessere Wahl:

  • Niedrigere Einstiegshuerde (kein Rego lernen)
  • Mutation und Generation sind Kernfeatures
  • Image Verification ist integriert
  • PolicyReports sind standardisiert und audit-freundlich

OPA/Gatekeeper lohnt sich, wenn:

  • Bereits OPA-Erfahrung im Team vorhanden ist
  • Policies ueber Kubernetes hinaus eingesetzt werden sollen (z.B. Terraform, CI/CD Pipelines)
  • Sehr komplexe, organisationsweite Policy-Frameworks benoetigt werden

Audit-Reporting: Compliance nachweisbar machen

Fuer NIS2-Audits und BSI-Pruefungen reicht es nicht, Policies zu haben. Man muss nachweisen, dass sie durchgesetzt werden und dass bestehende Ressourcen geprueft wurden.

Kyverno Policy Reports

Kyverno generiert automatisch PolicyReport-Objekte im Cluster:

# Alle Policy Reports anzeigen
kubectl get polr -A

# Beispiel-Output:
# NAMESPACE    NAME                     PASS   FAIL   WARN   ERROR   SKIP
# produktion   polr-ns-produktion       142    3      0      0       0
# staging      polr-ns-staging          89     12     0      0       0

# Details zu einem Report
kubectl get polr polr-ns-produktion -n produktion -o yaml

# Policy Reports als JSON exportieren fuer Audit-Dokumentation
kubectl get polr -A -o json > policy-audit-report-$(date +%Y%m%d).json

Gatekeeper Audit

Gatekeeper prueft periodisch alle bestehenden Ressourcen gegen die Constraints und speichert Verstoesse im Constraint-Objekt:

# Alle Constraint-Violations anzeigen
kubectl get constraints -o json | \
  jq '.items[] | {name: .metadata.name, violations: .status.totalViolations}'

# Beispiel-Output:
# {"name": "nur-interne-registries", "violations": 3}
# {"name": "require-resource-limits", "violations": 7}

# Detail-Violations fuer einen Constraint
kubectl get k8sallowedregistries nur-interne-registries -o json | \
  jq '.status.violations[]'

Schrittweise Einfuehrung: Von Audit zu Enforce

Eine sofortige Enforcement aller Policies wuerde bestehende Workloads brechen. Der richtige Weg ist eine schrittweise Einfuehrung:

Phase 1: Audit Mode (Wochen 1-4)

Policies werden deployed, aber nur beobachtet. Verstoesse werden geloggt, aber nicht blockiert.

# Kyverno: Audit Mode
spec:
  validationFailureAction: Audit  # Nicht Enforce
  background: true                # Bestehende Ressourcen pruefen

In dieser Phase sammeln Sie Daten: Welche Teams, welche Namespaces, welche Workloads verstossen gegen die Policies? Diese Informationen sind die Grundlage fuer die Kommunikation mit den Entwicklerteams.

Phase 2: Warn Mode (Wochen 5-8)

Entwickler sehen Warnungen bei kubectl apply, Deployments werden aber nicht blockiert:

# Kyverno: Warn Mode fuer spezifische Namespaces
spec:
  validationFailureAction: Audit
  rules:
    - name: require-resource-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: >-
          WARNUNG: Ab dem 01.04.2026 werden Pods ohne Resource Limits
          in Produktion blockiert. Bitte fuegen Sie requests und limits hinzu.
          Dokumentation: https://wiki.unternehmen.de/k8s/resource-limits
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"
                  requests:
                    memory: "?*"
                    cpu: "?*"

Phase 3: Enforce (ab Woche 9)

Nach ausreichender Vorwarnzeit wird auf Enforce umgestellt. Neue Deployments, die gegen Policies verstossen, werden abgelehnt.

Phase 4: Continuous Compliance

Policies werden wie Code behandelt: Git-versioniert, per Pull Request reviewed, in CI getestet und automatisch deployed. Das ist der staerkste Audit-Nachweis, den Sie liefern koennen.


BSI IT-Grundschutz: Policies fuer APP.4.4

Der BSI-Baustein APP.4.4 (Kubernetes) definiert konkrete Anforderungen, die sich direkt in Policies uebersetzen lassen. Mehr zu den BSI-Anforderungen finden Sie im Artikel zu Security Hardening.

BSI-AnforderungPolicy-Umsetzung
APP.4.4.A3 Sichere KonfigurationPod Security Standards enforce: restricted
APP.4.4.A5 RBACPruefe: keine ClusterRoleBindings an system:anonymous
APP.4.4.A9 NetzwerksegmentierungPruefe: Jeder Namespace hat eine Default-Deny NetworkPolicy
APP.4.4.A14 Supply ChainPruefe: Nur signierte Images aus erlaubten Registries
APP.4.4.A15 SecretsPruefe: Keine Secrets in Environment-Variablen
APP.4.4.A17 LoggingPruefe: Audit-Logging aktiviert, Log-Retention konfiguriert

Integration in CI/CD Pipelines

Policy-Pruefungen sollten nicht nur im Cluster stattfinden, sondern bereits in der CI/CD-Pipeline. Damit erfahren Entwickler von Verstoessen, bevor der Code das Cluster erreicht.

# GitHub Actions: Kyverno CLI fuer Pre-Deployment-Check
name: Policy Check
on:
  pull_request:
    paths:
      - 'k8s/**'

jobs:
  kyverno-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Kyverno CLI installieren
        run: |
          curl -LO https://github.com/kyverno/kyverno/releases/download/v1.12.0/kyverno-cli_v1.12.0_linux_x86_64.tar.gz
          tar -xzf kyverno-cli_v1.12.0_linux_x86_64.tar.gz
          sudo mv kyverno /usr/local/bin/

      - name: Policies gegen Manifeste pruefen
        run: |
          kyverno apply policies/ --resource k8s/manifeste/ \
            --detailed-results \
            --output policy-results.json

      - name: Ergebnis pruefen
        run: |
          FAILURES=$(jq '[.results[] | select(.result == "fail")] | length' policy-results.json)
          if [ "$FAILURES" -gt 0 ]; then
            echo "Policy-Verstoesse gefunden:"
            jq '.results[] | select(.result == "fail") | {policy: .policy, resource: .resource, message: .message}' policy-results.json
            exit 1
          fi
          echo "Alle Policies bestanden."

Monitoring und Alerting fuer Policy Violations

Policy Violations sollten im bestehenden Monitoring-Stack sichtbar sein:

MetrikQuelleAlert-Schwelle
gatekeeper_violationsGatekeeper Prometheus ExporterJeder neue Violation
kyverno_policy_results_totalKyverno Metricsresult=fail ueber Schwellenwert
kyverno_admission_requests_totalKyverno MetricsUngewoehnlich hohe Deny-Rate
Policy Report FAIL countPolicyReport CRDAnstieg gegenueber Vortag

Fazit

Policy Automation ist kein optionales Nice-to-have. Fuer Unternehmen mit Compliance-Anforderungen -- und das betrifft mit NIS2 mittlerweile die meisten Mittelstaendler -- ist es eine Notwendigkeit. Manuelle Checklisten sind langsam, fehleranfaellig und nicht skalierbar.

Kyverno bietet den schnellsten Einstieg fuer Kubernetes-Teams. OPA/Gatekeeper die groesste Flexibilitaet fuer komplexe Organisationen. Beide liefern den Audit-Nachweis, den Pruefer sehen wollen: nachweisbar durchgesetzte, versionierte, getestete Compliance-Regeln.

Starten Sie mit drei bis fuenf Policies im Audit-Mode. Messen Sie die Verstoesse. Kommunizieren Sie mit den Teams. Und schalten Sie dann schrittweise auf Enforce um. In drei Monaten haben Sie ein Policy-Framework, das jeden Auditor ueberzeugt.

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