Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Kubernetes und Secrets Management in der Cloud

By Alexei LedenevDec 26, 20195 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

1 yhminsd3pkjvkscqdxvpgq

Secrets sind für den Betrieb vieler Produktionssysteme unverzichtbar. Ihre versehentliche Offenlegung gehört zu den größten Risiken und muss konsequent abgesichert werden. Entwickler sollten alles daran setzen, Application Secrets zu schützen.

Richtig knifflig wird es, sobald ein Unternehmen auf eine Microservice-Architektur umstellt und mehrere Services Zugriff auf unterschiedliche Secrets brauchen, um sauber zu funktionieren. Daraus ergibt sich eine neue Herausforderung: Wie verteilt, verwaltet, überwacht und rotiert man Application Secrets, ohne sie versehentlich preiszugeben?

Kubernetes Secrets

Kubernetes stellt ein Objekt namens Secret bereit, in dem Sie sensible Anwendungsdaten wie Passwörter, SSH-Schlüssel, API-Keys, Tokens und Ähnliches ablegen können. Ein Kubernetes Secret lässt sich entweder als Umgebungsvariable in einen Pod-Container einbringen oder als Datei einhängen. So lassen sich sensible Daten und Konfiguration sauber vom Application Deployment trennen.

Ein Kubernetes Secret lässt sich beispielsweise mit dem Befehl kubectl create secret anlegen:

https://gist.github.com/02c582490747681776f1f480ec2f4165

oder über eine Kubernetes-Datei db-credentials.yaml, die dasselbe Secret beschreibt:

https://gist.github.com/09d76dd562fb9c5bb6fbaefd9afe377ehttps://gist.github.com/f0de7aa6fa86e29f25a06d78dfeeae5e

Wichtig: Sensible Daten in einem Kubernetes Secret abzulegen, macht sie nicht automatisch sicher. Standardmäßig liegen alle Daten in Kubernetes Secrets im Klartext vor – lediglich base64-codiert.

Seit Version 1.13 unterstützt Kubernetes die Verschlüsselung von Secrets at rest über das Objekt EncryptionConfiguration – wahlweise mit einem integrierten oder externen Encryption Provider.

Aktuell unterstützte Encryption Provider:

Built-in Provider: aescbc, aesgsm, secretbox

KMS Provider:

Allerdings ist die Verschlüsselung at rest standardmäßig nicht aktiviert. Und selbst wenn sie eingeschaltet ist, reicht sie für sich genommen nicht aus und ersetzt keine vollwertige Secrets-Management-Lösung.

Eine vollwertige Secrets-Management-Lösung deckt zusätzlich Verteilung und Rotation der Secrets ab, dazu feingranulare Zugriffskontrolle, Audit Log, Nutzungs-Monitoring, Versionierung, eine stark verschlüsselte Ablage, eine komfortable API samt Client-SDK(s) – und meist noch einige weitere nützliche Funktionen.

Cloud Secrets Management

Mehrere Cloud-Anbieter haben Secrets-Management-Services im Portfolio, mit denen Sie genau die Secrets schützen, die für den Zugriff auf Anwendungen, Services und APIs nötig sind. Damit entfällt es, sensible Informationen im Klartext fest in den Code zu schreiben oder einen eigenen Lifecycle für das Secrets Management aufzubauen. Über Secrets-Management-Services steuern Sie den Zugriff auf Application Secrets per feingranularer Berechtigungen und protokollieren ihn lückenlos.

Kubernetes mit Secrets-Management-Services integrieren

Grundsätzlich kann jede Anwendung über das anbieterspezifische SDK bzw. die API auf Secrets zugreifen, die in einem Secrets-Management-Service liegen. In der Regel bedeutet das jedoch Anpassungen am Anwendungscode oder den Einsatz von Bootstrap-Skripten bzw. Init Containers in Verbindung mit Client-CLI-Tools oder Web-APIs.

Einfacher mit dem secrets-init-Tool

Heute veröffentlichen wir doitintl/secrets-init – ein Open-Source-Tool (Apache License 2.0), das die Anbindung cloud-nativer Secrets-Management-Services an containerisierte workloads auf cloud-managed oder selbst betriebenen Kubernetes-Clustern deutlich vereinfacht.

Im Kern ist secrets-init ein minimalistisches init-System, das als PID 1 in der Container-Umgebung läuft – ähnlich wie dumb-init – und sich nahtlos in verschiedene cloud-native Secrets-Management-Services einfügt, darunter:

Warum braucht man im Docker-Container überhaupt ein init-System?

Lesen Sie dazu die Erklärung im Yelp-dumb-init-Repo.

Kurz zusammengefasst:

  • Korrektes Weiterreichen von Signalen
  • Aufräumen verwaister Zombie-Prozesse

Was secrets-init tut

secrets-init läuft als PID 1 und übernimmt die Rolle eines schlanken init-Systems: Als ENTRYPOINT oder erster Container-Befehl startet es einen Kindprozess und reicht alle Systemsignale an die Session weiter, die in diesem Kindprozess wurzelt – genau das macht ein init-Prozess aus. Darüber hinaus reicht secrets-init nahezu alle Umgebungsvariablen unverändert durch und ersetzt dabei spezielle Secret-Variablen durch die Werte aus den Secrets-Management-Services.

Integration mit Docker

secrets-init ist eine statisch kompilierte Binary ohne externe Abhängigkeiten und lässt sich problemlos in jedes Docker-Image einbetten. Laden Sie die secrets-init-Binary herunter und nutzen Sie sie als ENTRYPOINT Ihres Docker-Containers.

Beispiel:

https://gist.github.com/7efe25155c034ee1b978a2477b3224e4

Integration mit Kubernetes

Wenn Sie secrets-init mit einem Kubernetes-Objekt (Pod/Deployment/Job/etc.) nutzen wollen, ohne das Docker-Image anzufassen, schleusen Sie secrets-init am besten über einen initContainer in den Ziel-Pod ein. Dafür können Sie das Docker-Image doitint/secrets-init verwenden oder ein eigenes bauen. Kopieren Sie die secrets-init-Binary aus dem Init-Container in ein gemeinsam genutztes Volume und passen Sie das command des Pods so an, dass secrets-init als erster Befehl ausgeführt wird.

Integration mit AWS Secrets Manager

Um secrets-init mit AWS Secrets Manager zu verwenden, hinterlegen Sie den ARN eines AWS Secret als Wert einer Umgebungsvariable. secrets-init löst diesen Wert anhand des angegebenen ARN in den tatsächlichen Secret-Wert auf.

Beispiel für die Nutzung von secrets-init mit einem Kubernetes Job:

https://gist.github.com/6ae6d57ed08b26c64f534f87fc1872df

Integration mit AWS Systems Manager Parameter Store

Über den AWS Systems Manager Parameter Store lassen sich Anwendungsparameter im Klartext oder verschlüsselt (eine Art Secrets) ablegen.

Wie im vorigen Beispiel hinterlegen Sie den ARN aus dem AWS Parameter Store als Wert einer Umgebungsvariable. secrets-init löst diesen Wert anhand des angegebenen ARN in den entsprechenden Parameter-Wert auf.

Beispiel für das Format im AWS Systems Manager Parameter Store:

https://gist.github.com/9a7a83ec1659c391412557e5af340f42

Damit AWS Secrets aus AWS Secrets Manager und Parameter Store aufgelöst werden können, muss secrets-init unter einer IAM-Rolle laufen, die Zugriff auf die gewünschten Secrets hat.

Das erreichen Sie, indem Sie die IAM-Rolle einem Kubernetes Pod oder einem ECS Task zuweisen. Mehr dazu im EKS-Blogpost Introducing fine-grained IAM roles for service accounts.

Alternativ lässt sich die IAM-Rolle auch der EC2-Instanz zuweisen, auf der der Container läuft – diese Variante ist allerdings deutlich unsicherer und nicht zu empfehlen.

Integration mit Google Secret Manager

Google Cloud hat kürzlich einen neuen Service für die Verwaltung von Secrets in der Cloud veröffentlicht: Google Secret Manager

Sie hinterlegen den Google-Secret-Namen mit dem von secrets-init erkannten Präfix (gcp:secretmanager:) und dem anschließenden Secret-Namen (projects/{PROJECT_ID}/secrets/{SECRET_NAME} oder projects/{PROJECT_ID}/secrets/{SECRET_NAME}/versions/{VERSION}) als Wert einer Umgebungsvariable. secrets-init löst diesen Wert anhand des angegebenen Namens in den tatsächlichen Secret-Wert auf.

https://gist.github.com/65d46eb2b1fe44417a9d91828c94712d

Damit Google Secrets aus dem Google Secret Manager aufgelöst werden können, muss secrets-init unter einer IAM-Rolle laufen, die Zugriff auf die gewünschten Secrets hat.

Das erreichen Sie, indem Sie einem Kubernetes Pod über Workload Identity eine IAM-Rolle zuweisen. Alternativ lässt sich die IAM-Rolle auch der GCE-Instanz zuweisen, auf der der Container läuft – diese Variante ist jedoch unsicherer.

(15.03.2020) Update: Kubernetes Admission Webhook

Das Projekt kube-secrets-init implementiert einen Kubernetes-Admission Webhook, der einen initContainer in jeden Pod einschleust, der explizit (per Umgebungsvariable) oder implizit (über Kubernetes Secrets und ConfigMaps) auf Cloud Secrets verweist.

Nützliche Links

Fazit

Ich hoffe, dieser Beitrag bringt Sie weiter. Über Kommentare und Fragen freue ich mich.

Lust auf mehr? Schauen Sie in unserem Blog vorbei oder folgen Sie Alexei auf Twitter.