Velero (preview)
lionbackup wordt een opslagdoel voor Velero, het
back-uptool voor Kubernetes. Daarvoor is er een plugin die lionbackup als
BackupStorageLocation-provider registreert, en een kleine controller in het
cluster die elke voltooide back-up als één versleuteld bestand naar een
lionbackup-project uploadt. Beide zijn beschikbaar als bèta
0.2.0-beta.1: om uit te proberen in een testcluster, nog niet als uw enige
back-up.
Wat bij lionbackup aankomt, is de spool: Kubernetes-manifests, metadata en logs van de back-up. De inhoud van volumes (PVC's) wordt nog niet geback-upt; een PVC komt als definitie terug, maar leeg. Blijf voor volumedata op een andere weg vertrouwen.
Wat de preview vandaag doet, en wat niet
| Werkt vandaag | Ontbreekt nog |
|---|---|
Velero draait volledig tegen een spool in het cluster: back-up en herstel van manifests, sync, GC, backup delete | Volumedata: PVC-inhoud wordt niet vastgelegd (de node-agent van Velero kent alleen s3, azure, gcs en bestandssysteem) |
Ondertekende URL's: velero backup logs en describe --details werken, back-ups eindigen Completed | Herstelimport: de bundel komt van buiten het cluster terug in de spool (client met leestoken) |
Upload: de controller bundelt backups/<naam>/ tot één .lbk, uploadt die met een schrijftoken en annoteert de back-up met de file_id | Capture- en hersteljobs voor volumes; herhaling alleen als "over 10 minuten opnieuw" |
Een Failed back-up betekent dat er niets is geschreven; meestal klopt dan de
eigenaar van de spoolmap niet (zie stap 1). Een PartiallyFailed komt alleen
nog voor als de controller of het gedeelde URL-geheim ontbreekt (stap 4).
Uitproberen
U hebt een testcluster nodig, kubectl, de Velero-CLI (getest met Velero
1.18.3), een lionbackup-project met een schrijftoken en de
lionbackup-client op uw werkstation voor het sleutelpaar. De plugin-image is
zonder aanmelding op te halen.
1. De spoolmap aanmaken
Velero schrijft naar een map op de node die als hostPath (of als PVC) in de
Velero-pod wordt gemount. De officiële Velero-image draait als gebruikers-ID
1002; fsGroup geldt niet voor een hostPath, dus de map moet van dat ID
zijn. Anders mislukt elke back-up met permission denied, terwijl alle
objecten toch als geback-upt worden gemeld; de fout staat alleen in
status.failureReason.
mkdir -p /var/lib/lionbackup/spool
chown -R 1002:1002 /var/lib/lionbackup/spool
chmod 775 /var/lib/lionbackup/spool
2. Velero met de plugin installeren
velero install \
--provider lionbackup.cloud/lionbackup \
--plugins git.prod.lionbackup.cloud/lionbackup/velero-plugin-lionbackup:0.2.0-beta.1 \
--bucket spool \
--no-secret \
--use-volume-snapshots=false \
--backup-location-config spoolPath=/var/lib/lionbackup/spool \
--wait
--no-secret is juist: de plugin zelf heeft geen inloggegevens nodig. Het
schrijftoken hoort in het Secret van de controller (stap 4), nooit op de
BackupStorageLocation.
3. De spool in de Velero-pod mounten
kubectl -n velero patch deployment velero --type=json -p '[
{"op":"add","path":"/spec/template/spec/volumes/-","value":{"name":"lionbackup-spool","hostPath":{"path":"/var/lib/lionbackup/spool","type":"DirectoryOrCreate"}}},
{"op":"add","path":"/spec/template/spec/containers/0/volumeMounts/-","value":{"name":"lionbackup-spool","mountPath":"/var/lib/lionbackup/spool"}}
]'
kubectl -n velero rollout status deploy/velero --timeout=180s
kubectl -n velero get backupstoragelocation default
Zonder deze stap leeft de spool in het bestandssysteem van de pod en is hij
na de volgende herstart weg. De BackupStorageLocation hoort daarna
Available te melden.
4. Controller en Secret
De controller draait in dezelfde image als gebruiker 1002, met de spool
alleen-lezen gemount en het Secret onder /etc/lionbackup. Hij heeft drie
dingen nodig: het schrijftoken van het project, een willekeurig URL-geheim dat
hij met de Velero-pod deelt, en de publieke sleutel voor de versleuteling.
Genereer het sleutelpaar op uw werkstation; de privésleutel komt nooit in het
cluster, en zonder die is er geen herstel.
lionbackup --generate-key --key-name ./velero
kubectl -n velero create secret generic lionbackup-velero \
--from-literal=token=<WRITE-TOKEN> \
--from-literal=url-secret="$(head -c 32 /dev/urandom | base64)" \
--from-file=key.pub=./velero.pub
Sla het volgende manifest op als controller.yaml. Het bevat ServiceAccount,
Role, RoleBinding, Service en Deployment; de werkmap /work moet de grootste
back-upmap van de spool kunnen bevatten.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: lionbackup-velero-controller
namespace: velero
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: lionbackup-velero-controller
namespace: velero
rules:
- apiGroups: ["velero.io"]
resources: ["backups"]
verbs: ["get", "list", "watch", "patch"]
- apiGroups: ["velero.io"]
resources: ["backupstoragelocations"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: lionbackup-velero-controller
namespace: velero
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: lionbackup-velero-controller
subjects:
- kind: ServiceAccount
name: lionbackup-velero-controller
namespace: velero
---
apiVersion: v1
kind: Service
metadata:
name: lionbackup-velero-controller
namespace: velero
spec:
selector:
app.kubernetes.io/name: lionbackup-velero-controller
ports:
- name: http
port: 8080
targetPort: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lionbackup-velero-controller
namespace: velero
labels:
app.kubernetes.io/name: lionbackup-velero-controller
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: lionbackup-velero-controller
template:
metadata:
labels:
app.kubernetes.io/name: lionbackup-velero-controller
spec:
serviceAccountName: lionbackup-velero-controller
securityContext:
runAsUser: 1002
runAsGroup: 1002
runAsNonRoot: true
containers:
- name: controller
image: git.prod.lionbackup.cloud/lionbackup/velero-plugin-lionbackup:0.2.0-beta.1
command: ["/plugins/velero-plugin-lionbackup"]
args: ["controller"]
ports:
- name: http
containerPort: 8080
env:
- name: VELERO_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LIONBACKUP_SPOOL_PATH
value: /var/lib/lionbackup/spool
- name: LIONBACKUP_KEYFILE
value: /etc/lionbackup/key.pub
- name: LIONBACKUP_WORKDIR
value: /work
- name: LIONBACKUP_TOKEN
valueFrom:
secretKeyRef:
name: lionbackup-velero
key: token
- name: LIONBACKUP_VELERO_URL_SECRET
valueFrom:
secretKeyRef:
name: lionbackup-velero
key: url-secret
readinessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 3
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: "2"
memory: 1Gi
volumeMounts:
- name: lionbackup-spool
mountPath: /var/lib/lionbackup/spool
readOnly: true
- name: lionbackup-secret
mountPath: /etc/lionbackup
readOnly: true
- name: work
mountPath: /work
volumes:
- name: lionbackup-spool
hostPath:
path: /var/lib/lionbackup/spool
type: Directory
- name: lionbackup-secret
secret:
secretName: lionbackup-velero
items:
- key: key.pub
path: key.pub
- name: work
emptyDir:
sizeLimit: 10Gi
Pas het daarna toe, geef het URL-geheim ook aan de Velero-deployment en zet
project en zone op de BackupStorageLocation:
kubectl apply -f controller.yaml
kubectl -n velero set env deployment/velero \
LIONBACKUP_VELERO_URL_SECRET="$(kubectl -n velero get secret lionbackup-velero -o jsonpath='{.data.url-secret}' | base64 -d)"
kubectl -n velero patch backupstoragelocation default --type=merge -p \
'{"spec":{"config":{"lbProject":"<PROJECT-UUID>","lbZone":"de01-1","lbEnvironment":"prod"}}}'
kubectl -n velero rollout status deploy/velero --timeout=180s
kubectl -n velero rollout status deploy/lionbackup-velero-controller --timeout=180s
Zonder token of sleutel logt de controller alleen wat hij zou uploaden
(observe-only). Verdere config-sleutels van de BackupStorageLocation:
lbCompressionMethod (ZSTD), lbCompressionLevel (5), lbChunksizeMb
(64), lbUploadRateLimitMbit (0 = onbeperkt).
De ondertekende URL's wijzen naar de controller-Service in het cluster, dus
velero backup logs en describe --details werken waar die Service
bereikbaar is. Draait de Velero-CLI buiten het cluster, stuur dan de poort
door (kubectl -n velero port-forward svc/lionbackup-velero-controller 8080:8080) en zet controllerURL op de BackupStorageLocation op
http://localhost:8080; de handtekening dekt alleen pad en vervaltijd, niet
de host.
5. Back-up
velero backup create demo-1 --include-namespaces demo-app --wait
velero backup logs demo-1 | tail -n 3
kubectl -n velero get backup demo-1 \
-o jsonpath='{.status.phase} {.metadata.annotations.lionbackup\.cloud/file-id}{"\n"}'
Verwacht Completed, en velero backup logs levert het log via de
ondertekende URL van de controller. Kort daarna draagt het Backup-object de
annotatie lionbackup.cloud/file-id: de identificatie van het geüploade
bestand in het project, dezelfde die --list van de client toont. Mislukt de
upload, dan staat de reden in het log van de controller en probeert hij het na
tien minuten opnieuw.
6. Herstel vanuit lionbackup
De weg terug begint buiten het cluster, met een leestoken en de
privésleutel; beide blijven zo buiten het cluster. De client haalt de bundel
op, u kopieert de back-upmap naar de spool van het doelcluster en Velero pikt
hem op bij de volgende sync van de BackupStorageLocation:
lionbackup --config read.yaml --list
lionbackup --config read.yaml --restore <FILE-ID> --identity ./velero.key --target ./restored
# ./restored/…/backups/demo-1/ -> <spoolPath>/spool/backups/demo-1/ des Zielclusters
velero restore create demo-restore --from-backup demo-1 --wait
Manifests, deployments, ConfigMaps en PVC-definities komen terug. De data in de volumes niet; dat is de gedocumenteerde grens van de preview.
Wat volgt
De volgende stap back-upt de inhoud van volumes: een job per PVC op de node
van de pod streamt het volume als archief naar de spool, een bijbehorende
hersteljob vult het terug, en een init-container houdt de applicatie vast tot
het volume er weer is. Daar komt een controller-endpoint bij dat een bundel
via file_id rechtstreeks in de spool terughaalt. Tot dan geldt de opmerking
bovenaan deze pagina.