Secrets und ConfigMaps

KubernetesBeginner
Jetzt üben

Einführung

In Software ist es keine gute Praxis, Einstellungen wie Datenbank-URLs oder Passwörter fest in den Anwendungscode einzubauen. Dadurch werden Änderungen schwieriger, und das Sicherheitsrisiko steigt.

Kubernetes bietet dafür zwei Objekte:

  1. ConfigMap: Stellen Sie sich darunter ein öffentliches schwarzes Brett vor. Sie hinterlegen hier Informationen wie „Die Hintergrundfarbe ist blau“ oder „Die Datenbankadresse lautet 10.0.0.1“. Jeder im Büro (also jeder Pod) kann diese Informationen lesen.
  2. Secret: Dieses Objekt wird für vertrauliche Werte wie Passwörter oder Tokens verwendet.

Die Trennung von Anwendungscode und Laufzeitkonfiguration ist ein wichtiges Prinzip beim Plattformdesign und nicht nur eine Kubernetes-Funktion.

In diesem Lab werden Sie:

  • eine Notiz am schwarzen Brett (ConfigMap) hinterlegen,
  • ein Passwort im Safe (Secret) speichern,
  • einem Pod beibringen, beides zu lesen.

ConfigMap erstellen

Erstellen Sie eine Konfigurationsdatei für einen Webserver. Statt sie in das Image einzubauen, speichern Sie sie in einer ConfigMap.

Dieses Vorgehen ist Teil eines übergeordneten Prinzips beim Containerdesign: Erstellen Sie ein wiederverwendbares Image und stellen Sie die umgebungsspezifische Konfiguration erst zur Laufzeit bereit. Dadurch bleibt das Image portabler, weil Entwicklung, Staging und Produktion denselben Container mit unterschiedlichen Einstellungen verwenden können.

Erstellen Sie zunächst eine einfache Nginx-Konfigurationsdatei mit dem Namen nginx.conf:

echo 'events {} http { server { listen 80; location / { return 200 "Hello from ConfigMap!"; } } }' > nginx.conf

Erstellen Sie nun aus dieser Datei eine ConfigMap mit dem Namen nginx-config. Damit hinterlegen Sie die Datei praktisch am schwarzen Brett des Kubernetes-Clusters.

kubectl create configmap nginx-config --from-file=nginx.conf

Überprüfen Sie, ob die ConfigMap vorhanden ist:

kubectl describe configmap nginx-config

Unter dem Abschnitt „Data“ sollte der Inhalt Ihrer nginx.conf angezeigt werden.

Secret erstellen

Speichern Sie nun etwas Vertrauliches. Ein Secret funktioniert ähnlich wie eine ConfigMap, wird von Kubernetes aber besonders behandelt: Die Daten werden im Speicher verschleiert.

Dabei ist eine genaue Einordnung wichtig: Ein Secret ist sicherer, als Passwörter fest in Manifeste oder Images einzubauen. Base64-Kodierung ist jedoch keine echte Verschlüsselung. In Produktionsumgebungen wird die Verwaltung von Secrets häufig mit Verschlüsselung ruhender Daten, strengerem RBAC und externen Systemen zur Secret-Verwaltung kombiniert.

Erstellen Sie ein Secret mit dem Namen app-secret, um ein Beispielpasswort zu speichern:

kubectl create secret generic app-secret --from-literal=password=SuperSecretPass123

Überprüfen Sie, ob das Secret vorhanden ist:

kubectl get secret app-secret

Wenn Sie sich die Details ansehen, wird das Passwort nicht direkt angezeigt. Es ist verborgen, also kodiert.

kubectl get secret app-secret -o yaml

Beachten Sie, dass das Feld password aus einer Zeichenfolge scheinbar zufälliger Zeichen besteht. Dabei handelt es sich um Base64-Kodierung. Sie soll verhindern, dass jemand die Daten beim Blick auf den Bildschirm mitliest oder sie versehentlich in Protokollen angezeigt werden.

ConfigMap als Datei einbinden

Bringen Sie nun einem Pod bei, wie er das schwarze Brett liest.

Die häufigste Verwendung einer ConfigMap besteht darin, sie als Datei einzubinden. Im Container erscheint sie wie eine normale Datei auf dem Datenträger.

Dieser dateibasierte Ansatz ist nützlich, wenn eine Anwendung bereits erwartet, dass sich eine Konfigurationsdatei an einem bestimmten Pfad befindet. Kubernetes stellt die Daten der ConfigMap im Dateisystem des Containers bereit, sodass die Anwendung weiterhin wie gewohnt Dateien lesen kann.

Erstellen Sie eine Datei mit dem Namen pod-config.yaml:

nano pod-config.yaml

Fügen Sie den folgenden Inhalt ein. Dieser Pod bindet die ConfigMap nginx-config unter /etc/nginx/nginx.conf ein.

apiVersion: v1
kind: Pod
metadata:
  name: config-pod
spec:
  containers:
    - name: nginx
      image: nginx:alpine
      volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
  volumes:
    - name: config-volume
      configMap:
        name: nginx-config

Speichern Sie die Datei und beenden Sie den Editor (Ctrl+X, Y, Enter).

Wenden Sie die Konfiguration an:

kubectl apply -f pod-config.yaml

Warten Sie einige Sekunden, bis der Pod gestartet ist. Sehen Sie anschließend im Container nach, ob die Datei vorhanden ist:

kubectl exec config-pod -- cat /etc/nginx/nginx.conf

Ihre benutzerdefinierte Konfiguration sollte angezeigt werden. Der Pod hat im Grunde das schwarze Brett „gelesen“ und diese Datei verwendet.

Secret als Umgebungsvariable injizieren

Sehen wir uns nun das Secret an. Eine häufige Methode, Passwörter zu übergeben, ist die Verwendung von Umgebungsvariablen.

Diese Methode ist praktisch, zeigt aber auch einen wichtigen Kompromiss. Anwendungen können Umgebungsvariablen leicht lesen. Sie können jedoch durch Diagnosebefehle oder die Untersuchung von Prozessen sichtbar werden. Kubernetes unterstützt sowohl die dateibasierte als auch die umgebungsvariablenbasierte Injektion, weil unterschiedliche Anwendungen und Risikoprofile unterschiedliche Vorgehensweisen erfordern.

Erstellen Sie eine Datei mit dem Namen pod-secret.yaml:

nano pod-secret.yaml

Fügen Sie den folgenden Inhalt ein. Dieser Pod liest das Feld password aus dem Secret app-secret und weist es einer Umgebungsvariablen mit dem Namen APP_PASSWORD zu.

apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
    - name: busybox
      image: busybox
      command: ["sleep", "3600"]
      env:
        - name: APP_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: password

Speichern Sie die Datei und beenden Sie den Editor (Ctrl+X, Y, Enter).

Wenden Sie die Konfiguration an:

kubectl apply -f pod-secret.yaml

Sobald der Pod läuft, überprüfen Sie die Umgebungsvariablen im Container:

kubectl exec secret-pod -- env | grep APP_PASSWORD

Sie sollten APP_PASSWORD=SuperSecretPass123 sehen.

Der entscheidende Punkt ist: Die Pod-Definition enthält das Passwort nicht. Das Passwort liegt im „Safe“ (Secret), und der Pod besitzt lediglich einen Schlüssel, mit dem er es zur Laufzeit abruft.

Zusammenfassung

In diesem Lab haben Sie geübt, Code und Konfiguration voneinander zu trennen.

Sie haben erfolgreich:

  1. eine ConfigMap (schwarzes Brett) verwendet, um eine Konfigurationsdatei in einen Server einzubinden;
  2. ein Secret (Safe) verwendet, um ein verborgenes Passwort in eine Anwendung zu injizieren.

Damit können Sie Ihre Konfiguration aktualisieren oder Passwörter austauschen, ohne Ihre Docker-Images neu erstellen zu müssen.