- Authors

- Name
- Phillip Pham
- @ddppham
TL;DR
Der External Secrets Operator (ESO) holt Secrets aus externen Quellen wie AWS Secrets Manager, HashiCorp Vault oder Azure Key Vault und erstellt daraus native Kubernetes-Secrets. Die Synchronisierung läuft automatisch, Rotation wird ohne Pod-Restart möglich. Zwei CRDs reichen: SecretStore für die Verbindung, ExternalSecret für das Mapping.
Secrets gehören nicht ins Cluster
Kubernetes-Secrets sind Base64-kodiert, nicht verschlüsselt. Wer Secrets direkt in Manifesten oder Git speichert, hat ein Sicherheitsproblem. Der External Secrets Operator löst das: Secrets bleiben in einem dedizierten Secret-Manager, Kubernetes bekommt nur eine Referenz.
External Secrets Operator installieren
Die Installation läuft über Helm:
helm repo add external-secrets https://charts.external-secrets.io
helm repo update
helm install external-secrets external-secrets/external-secrets \
--namespace external-secrets \
--create-namespace \
--set installCRDs=true
Prüfe, ob die Pods laufen:
kubectl get pods -n external-secrets
kubectl get crd | grep external-secrets
Du solltest drei CRDs sehen: secretstores, clustersecretstores und externalsecrets.
Architektur im Überblick
Der Operator arbeitet mit zwei Haupt-Ressourcen:
| Ressource | Scope | Aufgabe |
|---|---|---|
SecretStore | Namespace | Verbindung zum externen Provider (Credentials, Endpoint) |
ClusterSecretStore | Cluster-weit | Wie SecretStore, aber namespace-übergreifend nutzbar |
ExternalSecret | Namespace | Definiert welche Secrets geholt und wie gemappt werden |
Der Ablauf: ExternalSecret referenziert einen SecretStore, der Operator holt den Wert vom Provider und erstellt ein Kubernetes-Secret. Bei Änderungen im Provider wird das Secret automatisch aktualisiert.
Provider 1: AWS Secrets Manager
Für AWS brauchst du IAM-Credentials mit Zugriff auf Secrets Manager.
SecretStore konfigurieren
# aws-secret-store.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-manager
namespace: production
spec:
provider:
aws:
service: SecretsManager
region: eu-central-1
auth:
secretRef:
accessKeyIDSecretRef:
name: aws-credentials
key: access-key-id
secretAccessKeySecretRef:
name: aws-credentials
key: secret-access-key
Das Bootstrap-Secret mit den AWS-Credentials muss einmalig manuell erstellt werden:
kubectl create secret generic aws-credentials \
--namespace production \
--from-literal=access-key-id=AKIAIOSFODNN7EXAMPLE \
--from-literal=secret-access-key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
kubectl apply -f aws-secret-store.yaml
ExternalSecret anlegen
# aws-external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: db-credentials
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: prod/database
property: username
- secretKey: password
remoteRef:
key: prod/database
property: password
Nach dem Apply erstellt der Operator ein Kubernetes-Secret namens db-credentials:
kubectl apply -f aws-external-secret.yaml
# Status prüfen
kubectl get externalsecret -n production
# STATUS sollte "SecretSynced" sein
# Erstelltes Secret ansehen
kubectl get secret db-credentials -n production -o jsonpath='{.data.username}' | base64 -d
Provider 2: HashiCorp Vault
Vault ist der Klassiker für Secrets Management. Der ESO unterstützt sowohl KV v1 als auch v2.
SecretStore für Vault
# vault-secret-store.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-store
namespace: production
spec:
provider:
vault:
server: "https://vault.example.com"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "external-secrets"
serviceAccountRef:
name: external-secrets-sa
Die Kubernetes-Auth-Methode ist die sauberste Variante — kein statisches Token nötig. Vault authentifiziert den ServiceAccount direkt:
# Vault-seitig: Kubernetes Auth konfigurieren
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443"
vault write auth/kubernetes/role/external-secrets \
bound_service_account_names=external-secrets-sa \
bound_service_account_namespaces=production \
policies=readonly-secrets \
ttl=1h
# ServiceAccount im Cluster erstellen
kubectl create serviceaccount external-secrets-sa -n production
kubectl apply -f vault-secret-store.yaml
ExternalSecret für Vault
# vault-external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-keys
namespace: production
spec:
refreshInterval: 30m
secretStoreRef:
name: vault-store
kind: SecretStore
target:
name: api-keys
data:
- secretKey: stripe-key
remoteRef:
key: secret/data/production/api-keys
property: stripe
- secretKey: sendgrid-key
remoteRef:
key: secret/data/production/api-keys
property: sendgrid
Provider 3: Azure Key Vault
Für Azure-Umgebungen bindet der ESO direkt an Key Vault an:
# azure-secret-store.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: azure-keyvault
namespace: production
spec:
provider:
azurekv:
tenantId: "00000000-0000-0000-0000-000000000000"
vaultUrl: "https://mein-keyvault.vault.azure.net"
authSecretRef:
clientId:
name: azure-credentials
key: client-id
clientSecret:
name: azure-credentials
key: client-secret
Das ExternalSecret folgt dem gleichen Muster — nur der remoteRef.key entspricht dem Secret-Namen in Azure:
# azure-external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: azure-db-secret
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
name: azure-keyvault
kind: SecretStore
target:
name: db-connection-string
data:
- secretKey: connection-string
remoteRef:
key: production-db-connection
Secret-Rotation in der Praxis
Der eigentliche Vorteil von External Secrets: automatische Rotation. Das refreshInterval steuert, wie oft der Operator den externen Provider abfragt. Ändert sich der Wert dort, wird das Kubernetes-Secret aktualisiert.
Damit Pods das neue Secret ohne Restart erhalten, gibt es zwei Ansätze:
# Option 1: Reloader-Annotation (erfordert stakater/Reloader)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
reloader.stakater.com/auto: "true"
spec:
template:
spec:
containers:
- name: app
envFrom:
- secretRef:
name: db-credentials
# Option 2: Rollout manuell triggern nach Rotation
kubectl rollout restart deployment/myapp -n production
Troubleshooting
Wenn ein ExternalSecret nicht synchronisiert:
# Status und Events prüfen
kubectl describe externalsecret database-credentials -n production
# Operator-Logs anschauen
kubectl logs -n external-secrets -l app.kubernetes.io/name=external-secrets
# SecretStore-Verbindung testen
kubectl get secretstore -n production
# STATUS: Valid = Verbindung funktioniert
FAQ
Was passiert, wenn der externe Provider nicht erreichbar ist?
Das bestehende Kubernetes-Secret bleibt erhalten. Der Operator versucht bei jedem refreshInterval erneut zu synchronisieren. Events am ExternalSecret zeigen den Fehler an.
Kann ich ein Secret in mehrere Namespaces synchronisieren?
Ja, verwende einen ClusterSecretStore statt eines SecretStore. Dann können ExternalSecrets aus beliebigen Namespaces darauf zugreifen. Alternativ: ein ExternalSecret pro Namespace, das denselben Store referenziert.
Ist External Secrets Operator Production-ready?
Ja, ESO ist ein CNCF-Projekt im Incubating-Status und wird von zahlreichen Unternehmen in Production eingesetzt. Die API ist seit v1beta1 stabil.
Wie unterscheidet sich ESO von Sealed Secrets?
Sealed Secrets verschlüsselt Secrets für Git-Storage — der Wert lebt im Repository. ESO holt Secrets zur Laufzeit aus einem externen Provider. ESO ist die bessere Wahl, wenn du bereits einen Secret-Manager betreibst und Rotation brauchst.
Nächster Schritt: Kombiniere External Secrets mit dem Trivy Operator, um neben Secrets auch Container-Images automatisiert auf Schwachstellen zu prüfen.
Kubernetes-Security & Compliance?
Security-Audits, Penetration Tests und Compliance-Beratung für Ihre Container-Infrastruktur. BSI-Grundschutz, DSGVO, ISO 27001.
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
Kubernetes Secrets mit HashiCorp Vault verwalten
HashiCorp Vault als zentralen Secrets Store für Kubernetes einrichten mit External Secrets Operator, Vault Agent und praxisnahen YAML-Beispielen.
Sealed Secrets Anleitung: Kubernetes Secrets in Git
Sealed Secrets verschlüsseln Kubernetes Secrets für Git-Repos. Installation, kubeseal-Nutzung und GitOps-Integration Schritt für Schritt erklärt.
Kubernetes Insider Threat Detection: Strategien für umfassende Clustersicherheit
Entdecke effektive Strategien für die umfassende Kubernetes Insider Threat Detection. Lerne, wie du Innentäter durch lückenloses Monitoring, Behavioral Analytics und fortschrittliche Runtime Security in deinen Kubernetes-Clustern frühzeitig erkennst und die Sicherheit sowie Compliance nachhaltig stärkst.
OPA Gatekeeper: Admission Controller für Kubernetes
OPA Gatekeeper setzt Policies im Kubernetes-Cluster durch und blockiert fehlerhafte Deployments vor dem Rollout. Praxisguide mit Rego-Beispielen.
API Server Hardening: Kubernetes absichern
Kubernetes API Server härten mit Audit-Logging, Encryption at Rest, OIDC und Rate Limiting. Praxisnahe Konfiguration für sichere Cluster.