
Ursprünglich veröffentlicht auf LinkedIn am 2023-05-24.
HashiCorp Vault#
In Vault Enterprise gibt es eine integrierte Lösung, um Backups in S3-kompatible Speicher hochzuladen. In der Open-Source-Version von Vault fehlt diese Funktion, also musste ich eine Lösung dafür erstellen.
Meistens verwende ich den integrierten Raft-Speicher innerhalb des Vault-Clusters in Kubernetes. Die Daten dieses StatefulSets werden in PersistentVolumeClaims gespeichert. (Wo ich auch die Standard-PersistentVolumeReclaimPolicy auf Retain gepatcht habe, um das Löschen des StatefulSets zu verhindern, aber das ist eine andere Geschichte.)
Also habe ich im Internet nach Inspiration gesucht und einige Quellen gefunden, denen ich mehr oder weniger gefolgt bin.
Erstellen eines Vault-Backup-Containers#
Ich habe mich entschieden, einen Container basierend auf Alpine 3.18 zu erstellen. Es gibt aktuelle Vault- und aws-cli-Pakete, die in meinem Fall gut funktioniert haben. Der Speicherplatz des Images beträgt etwa 90 MB. Und wir haben bereits GitLab-Pipelines, um Container zu erstellen und zu testen. Also war der Aufwand minimal.
FROM alpine:3.1
LABEL version="1.0.0" \
maintaner="Gerhard Sulzberger <********@*****>" \
description="Image used for vault-backups"
RUN apk --no-cache add \
vault=1.13.2-r0 \
aws-cli=2.11.21-r0 \
libcap=2.69-r0 \
&& addgroup vaultbackup \
&& adduser -G vaultbackup -g "Backup User" -s /bin/ash -D vaultbackup \
&& setcap cap_ipc_lock= /usr/sbin/vault
USER vaultbackup
WORKDIR /home/vaultbackup
COPY backupVault.sh /home/vaultbackup/backupVault.sh
ENTRYPOINT ["/bin/sh", "-e", "/home/vaultbackup/backupVault.sh"]Die Hauptmagie passiert im backupVault.sh-Skript.
#!/bin/sh
VAULT_TOKEN=$(vault write -field=token auth/approle/login role_id="$VAULT_APPROLE_ROLE_ID" secret_id="$VAULT_APPROLE_SECRET_ID")
export VAULT_TOKEN
DATE=$(date +%Y%m%d-%H%M%S)
vault operator raft snapshot save /tmp/vault-raft-"$DATE".snap
/usr/bin/aws --endpoint-url "$AWS_ENDPOINT_URL" s3 cp /tmp/vault-raft-"$DATE".snap s3://"$AWS_BUCKET"/vault/
rm /tmp/vault-raft-"$DATE".snap
echo "Completed the backup - " "$DATE"Die Vault-CLI erstellt ein kurzlebiges Token über die AppRole-Authentifizierung. Es erstellt das Snapshot und mit der aws-cli wird das Snapshot in den Objektspeicher hochgeladen. Was in meinem Fall kein Standard-AWS-S3 ist.
Das Skript muss auf jeden Fall verbessert werden, weil es keine Sicherheit gibt, falls ein Fehler auftritt. Aber es ist ein Startpunkt, den ich mit einigen TRY/CATCH-Funktionalitäten erweitern kann.
Kubernetes CronJob#
Die Kubernetes CronJob-Ressource kann verwendet werden, um zu planen, wann der Vault-Backup-Pod ausgeführt werden soll.
apiVersion: batch/v1
kind: CronJob
metadata:
name: vault-snapshot-cronjob
spec:
schedule: "15 */12 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: vault-backup
image: registry******/******/vault-backup:1.0.0
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: vault-snapshot-agent-token
- secretRef:
name: vault-snapshot-s3
env:
- name: VAULT_ADDR
value: https://vault-active.vault.svc.cluster.local:8200
imagePullSecrets:
- name: registry-cred
restartPolicy: Never
backoffLimit: 4Es gibt etwas Magie in der Art und Weise, wie die Geheimnisse verwaltet werden. Der External-Secrets-Operator verwaltet die Geheimnisse, die als Umgebungsvariablen verwendet werden. Auch die imagePullSecrets werden auf diese Weise verwaltet. Der External-Secrets-Operator verwendet die Vault-Kubernetes-Authentifizierung und erstellt, wenn er die richtige Richtlinie und Berechtigung hat, ein Kubernetes-Geheimnis aus einem Vault-Geheimnis.
Eine gute Dokumentation, wie dies funktioniert, finden Sie hier.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: vault-snapshot-s3
spec:
dataFrom:
- extract:
# AWS_ACCESS_KEY_ID
# AWS_BUCKET
# AWS_ENDPOINT_URL
# AWS_SECRET_ACCESS_KEY
key: kvstorage/path/to/secret/vault-snapshot-s3
conversionStrategy: Default
refreshInterval: 30s
secretStoreRef:
kind: ClusterSecretStore
name: secrets
target:
creationPolicy: Owner
deletionPolicy: RetainVault ist der perfekte Ort, um Anmeldedaten zu speichern.
Antipattern?
Ich habe es ein bisschen für andere Umgebungsvariablen missbraucht. Ich habe es jetzt bemerkt und werde das später ändern müssen und die AWS_ENDPOINT_URL- und AWS_BUCKET-Variablen entfernen.

Sie sollten wahrscheinlich wie jede andere Umgebungsvariable im Manifest wie VAULT_ADDR konfiguriert werden.
Bereitstellung#
Die Bereitstellung erfolgt mit ArgoCD nach dem App-of-Apps-Muster. Dadurch kann ich einfach alles in Git einchecken und ArgoCD erledigt die Arbeit.

Wiederherstellung#
Fazit#
Mit etwas Aufwand ist es möglich, Backups der Open-Source-Vault innerhalb von Kubernetes zu S3-Objektspeichern zu automatisieren.
Es gibt noch todos und Dinge, die in diesem Artikel nicht erwähnt werden.
- Backup-Skript und EntryPoint verbessern
- Eine tägliche Routine zum Testen von Wiederherstellungsverfahren
- Überwachung und Warnungen mit dem kube-prometheus-Operator
Es wäre interessant zu wissen, wie andere IT-Leute das Backup der HashiCorp-Vaults-Open-Source-Version gelöst haben. Wenn Sie bereit sind, Einblicke oder Kritik zu teilen, fügen Sie bitte einen Kommentar hinzu.
Offtopic#
Da wir viel hinter Bildschirmen arbeiten, werden wir manchmal müde und denken im Kreis. Dann ist es Zeit für eine Pause. So sehr ich Technik auch mag, ich werde immer die uralte Technologie genießen, Gras mit einer Sense zu mähen.
Haben Sie einen schönen Tag und vergessen Sie nicht, das Leben zu genießen.

