Veröffentlicht am

DSGVO-konforme Kubernetes-Cluster richtig konfigurieren

Teilen:
Authors

DSGVO-konforme Kubernetes-Cluster: Encryption, RBAC und Audit-Logging richtig umsetzen

TL;DR

  • Kubernetes bringt von Haus aus keine DSGVO-Compliance mit -- die muss bewusst konfiguriert werden
  • Encryption at Rest fuer etcd, strikte RBAC-Regeln und Network Policies bilden das technische Fundament
  • Audit-Logging muss aktiviert und so konfiguriert werden, dass personenbezogene Daten nicht ungefiltert in Logs landen
  • Node Affinity stellt sicher, dass Workloads mit personenbezogenen Daten nur auf EU-Nodes laufen
  • Automatisierte Compliance-Checks per CronJob ersetzen keine rechtliche Beratung, machen das Leben aber deutlich einfacher

Warum DSGVO bei Kubernetes kein Selbstlaeufer ist

Wer einen Kubernetes-Cluster aufsetzt, bekommt erstmal gar keine Datenschutz-Compliance geschenkt. Secrets liegen standardmaessig Base64-kodiert (nicht verschluesselt) in etcd. Pods koennen ohne Network Policies mit dem gesamten Cluster kommunizieren. Audit-Logging ist deaktiviert.

Das ist kein Bug, sondern Design: Kubernetes ist ein generisches Orchestrierungssystem. Die DSGVO-Anforderungen muessen bewusst implementiert werden. Dieser Artikel zeigt die konkreten Schritte.

Die drei Saeulen der DSGVO-Compliance in Kubernetes

Datenschutz in Kubernetes laesst sich auf drei technische Saeulen reduzieren:

SaeuleKubernetes-MechanismusDSGVO-Bezug
VerschluesselungEncryption at Rest, mTLSArt. 32 - Sicherheit der Verarbeitung
ZugriffskontrolleRBAC, Network Policies, Pod Security StandardsArt. 25 - Data Protection by Design
NachvollziehbarkeitAudit Logging, AnnotationsArt. 30 - Verzeichnis der Verarbeitungstaetigkeiten

Alle drei muessen zusammenspielen. Encryption ohne RBAC ist nutzlos, wenn jeder ServiceAccount Secrets lesen kann. RBAC ohne Audit-Logging macht Verstaesse unsichtbar.

Saeule 1: Encryption at Rest fuer etcd konfigurieren

etcd speichert den gesamten Cluster-State -- inklusive Secrets, ConfigMaps und Custom Resources. Standardmaessig liegen diese Daten unverschluesselt vor.

Die EncryptionConfiguration wird als Datei auf den Control-Plane-Nodes abgelegt und per API-Server-Flag referenziert:

# /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
      - configmaps
    providers:
      - aescbc:
          keys:
            - name: key-2026-q1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

Der API-Server muss mit dem Flag --encryption-provider-config=/etc/kubernetes/encryption-config.yaml gestartet werden. Bei Managed-Kubernetes-Diensten (EKS, AKS, GKE) ist Encryption at Rest ueber den jeweiligen KMS-Service konfigurierbar.

Nach der Aktivierung muessen bestehende Secrets neu geschrieben werden, damit sie verschluesselt abgelegt werden:

# Alle bestehenden Secrets neu verschluesseln
kubectl get secrets --all-namespaces -o json | \
  kubectl replace -f -

# Pruefen, ob Encryption aktiv ist
kubectl get secret test-secret -n default -o yaml
# Der Wert im etcd sollte jetzt mit k8s:enc:aescbc:v1:key-2026-q1 beginnen

# Fuer Managed Services: KMS-Verschluesselung pruefen (AWS EKS Beispiel)
aws eks describe-cluster --name my-cluster \
  --query 'cluster.encryptionConfig'

Wichtig: Die Encryption Keys selbst muessen sicher verwaltet werden. Idealerweise ueber einen externen KMS (AWS KMS, Azure Key Vault, HashiCorp Vault). Den Key im Klartext auf der Control Plane zu haben, ist nur eine Zwischenloesung.

Saeule 2: RBAC und Network Policies

RBAC regelt, wer was im Cluster tun darf. Fuer DSGVO-relevante Workloads gilt das Prinzip der minimalen Berechtigung konsequent.

Ein typisches Setup fuer ein Team, das nur Deployments in einem bestimmten Namespace verwalten soll:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: customer-data
  name: app-deployer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  # Explizit KEIN Zugriff auf Secrets
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: customer-data
  name: app-deployer-binding
subjects:
  - kind: Group
    name: app-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: app-deployer
  apiGroup: rbac.authorization.k8s.io
---
# Network Policy: customer-data Namespace nur intern erreichbar
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  namespace: customer-data
  name: restrict-external-access
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              access-customer-data: "true"
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: database
      ports:
        - protocol: TCP
          port: 5432
    - to:  # DNS erlauben
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53

Ein Fehler, den ich immer wieder sehe: ClusterRoleBindings, die cluster-admin an ServiceAccounts vergeben, die es nicht brauchen. Ein schnelles Audit:

# ClusterRoleBindings mit cluster-admin finden
kubectl get clusterrolebindings -o json | \
  jq -r '.items[] | select(.roleRef.name=="cluster-admin") |
  .metadata.name + " -> " +
  (.subjects[]? | .kind + "/" + .name)'

# RBAC-Berechtigungen eines ServiceAccounts pruefen
kubectl auth can-i --list \
  --as=system:serviceaccount:customer-data:default

Saeule 3: Audit-Logging aktivieren und konfigurieren

Kubernetes kann jeden API-Call loggen, tut es aber standardmaessig nicht. Fuer DSGVO-Compliance brauchen wir nachvollziehbare Logs, wer wann auf welche Ressourcen zugegriffen hat.

Die Audit Policy definiert, welche Events in welchem Detail geloggt werden:

# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # Secrets: nur Metadaten loggen, nicht den Inhalt
  - level: Metadata
    resources:
      - group: ""
        resources: ["secrets"]
  # DSGVO-relevante Namespaces: Request + Response loggen
  - level: RequestResponse
    namespaces: ["customer-data", "personal-data"]
    resources:
      - group: ""
        resources: ["pods", "services", "configmaps"]
      - group: "apps"
        resources: ["deployments"]
  # Alles andere: Metadata-Level
  - level: Metadata
    omitStages:
      - RequestReceived

Der API-Server wird mit diesen Flags gestartet:

kube-apiserver \
  --audit-policy-file=/etc/kubernetes/audit-policy.yaml \
  --audit-log-path=/var/log/kubernetes/audit.log \
  --audit-log-maxage=90 \
  --audit-log-maxbackup=10 \
  --audit-log-maxsize=100

Achtung: level: Request oder level: RequestResponse bei Secrets wuerde den Secret-Inhalt im Audit-Log speichern. Das waere ein DSGVO-Verstoss, wenn darin personenbezogene Daten stehen. Deshalb immer nur level: Metadata fuer Secrets.

Data Residency: Workloads an EU-Regionen binden

Wenn der Cluster ueber mehrere Regionen verteilt ist (oder Nodes in nicht-EU-Regionen laufen), muss sichergestellt werden, dass Pods mit personenbezogenen Daten nur auf EU-Nodes landen:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: customer-api
  namespace: customer-data
spec:
  replicas: 3
  selector:
    matchLabels:
      app: customer-api
  template:
    metadata:
      labels:
        app: customer-api
        data-classification: personal
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: topology.kubernetes.io/region
                    operator: In
                    values:
                      - eu-central-1
                      - eu-west-1
      containers:
        - name: api
          image: customer-api:v2.4.1
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
          securityContext:
            runAsNonRoot: true
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]

Automatisierte Compliance-Checks

Manuelle Pruefungen skalieren nicht. Ein CronJob, der die wichtigsten DSGVO-relevanten Konfigurationen taeglich prueft:

#!/bin/bash
# compliance-check.sh -- taeglicher Check der DSGVO-Basics

VIOLATIONS=0

# 1. Unverschluesselte Secrets pruefen
echo "=== Pruefe Encryption ==="
UNENCRYPTED=$(kubectl get secrets -A -o json | \
  jq '[.items[] | select(.metadata.annotations["encryption-status"] != "encrypted")] | length')
if [ "$UNENCRYPTED" -gt 0 ]; then
  echo "WARNUNG: $UNENCRYPTED Secrets ohne Verschluesselungs-Annotation"
  VIOLATIONS=$((VIOLATIONS + 1))
fi

# 2. Namespaces ohne Network Policies
echo "=== Pruefe Network Policies ==="
for ns in customer-data personal-data; do
  NP_COUNT=$(kubectl get networkpolicy -n "$ns" --no-headers 2>/dev/null | wc -l)
  if [ "$NP_COUNT" -eq 0 ]; then
    echo "WARNUNG: Namespace $ns hat keine Network Policies"
    VIOLATIONS=$((VIOLATIONS + 1))
  fi
done

# 3. Pods ohne Security Context
echo "=== Pruefe Pod Security ==="
INSECURE_PODS=$(kubectl get pods -A -o json | \
  jq '[.items[] |
    select(.spec.containers[].securityContext.runAsNonRoot != true) |
    .metadata.namespace + "/" + .metadata.name] | unique | length')
if [ "$INSECURE_PODS" -gt 0 ]; then
  echo "WARNUNG: $INSECURE_PODS Pods ohne runAsNonRoot"
  VIOLATIONS=$((VIOLATIONS + 1))
fi

# 4. Ergebnis
echo "=== Compliance Score ==="
echo "Violations: $VIOLATIONS"
if [ "$VIOLATIONS" -gt 0 ]; then
  echo "Status: NON-COMPLIANT"
  exit 1
else
  echo "Status: COMPLIANT"
  exit 0
fi

Dieses Script laesst sich als Kubernetes CronJob deployen und mit Alertmanager verknuepfen, sodass bei Violations automatisch das zustaendige Team benachrichtigt wird.

Vergleich: Managed vs. Self-Managed DSGVO-Compliance

AspektManaged (EKS/AKS/GKE)Self-Managed
Encryption at RestKMS-Integration vorhandenManuell konfigurieren
Audit LoggingUeber Cloud-Logging verfuegbarManuell einrichten
Control Plane SecurityVom Provider verwaltetEigene Verantwortung
Data ResidencyRegion waehlbarVolle Kontrolle
ZertifizierungenSOC2, ISO 27001 vom ProviderEigene Zertifizierung noetig
AufwandMittelHoch
KostenHoehere ServicekostenHoeherer Personalaufwand

Fuer die meisten Unternehmen ist Managed Kubernetes der pragmatischere Weg. Die grossen Provider haben die Basis-Compliance bereits implementiert. Was bleibt, ist die anwendungsspezifische Konfiguration: RBAC, Network Policies, Audit Policies und die korrekte Annotation von Workloads.

Haeufige Fehler, die ich in der Praxis sehe

Fehler 1: Secrets im Git-Repository. Auch wenn sie Base64-kodiert sind -- das ist keine Verschluesselung. Loesung: Sealed Secrets, External Secrets Operator oder direkt Vault.

Fehler 2: Default ServiceAccount ueberall. Jeder Pod bekommt standardmaessig den default ServiceAccount seines Namespace. Wenn dieser zu viele Rechte hat, erbt sie jeder Pod. Loesung: automountServiceAccountToken: false als Default setzen.

Fehler 3: Audit-Logs mit PII. Wenn Audit-Logging auf RequestResponse-Level fuer alle Ressourcen steht, landen Request Bodies (potenziell mit personenbezogenen Daten) im Log. Das ist ein DSGVO-Verstoss. Loesung: Differenzierte Audit Policy wie oben gezeigt.

Fehler 4: Network Policies nur fuer Ingress. Viele Teams vergessen Egress-Regeln. Ein kompromittierter Pod kann dann beliebige externe Endpunkte erreichen und Daten exfiltrieren. Loesung: Egress immer mitdenken.

Weitergehende Themen

Dieser Artikel deckt die technischen Grundlagen ab. Fuer tiefergehende Themen empfehle ich:

Fazit

DSGVO-Compliance in Kubernetes ist kein einmaliges Projekt, sondern eine fortlaufende Aufgabe. Die technischen Werkzeuge sind da: Encryption, RBAC, Network Policies, Audit Logging. Die Herausforderung liegt darin, sie konsistent und korrekt einzusetzen.

Wer die drei Saeulen -- Verschluesselung, Zugriffskontrolle und Nachvollziehbarkeit -- sauber implementiert, hat eine solide Basis. Automatisierte Checks helfen, Drift zu erkennen, bevor er zum Problem wird.

Falls Sie Unterstuetzung bei der DSGVO-konformen Konfiguration Ihrer Kubernetes-Infrastruktur brauchen, melden Sie sich gerne unter /kontakt.

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