k8up icon indicating copy to clipboard operation
k8up copied to clipboard

Annotation k8up.io/restorecommand

Open ThomasSteinbach opened this issue 2 years ago • 2 comments

Summary

As "DevOp / Admin"
I want "to restore application-aware backups as easy as pvc backups"
So that "I does not bother with boilerplate code to restore my databases."

Context

K8up can restore PVC backups defined by restore objects. However it should also be possible to restore application-aware backups - exactly the other way around as those backups were made. See my implementation idea below

Implementation Ideas

For making an application-aware backup you have to annotate your pods with (for instance):

k8up.syn.tools/backupcommand: /bin/bash -c 'mysqldump -uroot -p"${MARIADB_ROOT_PASSWORD}" --all-databases'

K8up will then gather the stdout and process it with restic. However the other way around should also be possible:

k8up.syn.tools/restorecommand: /bin/bash -c 'mysql -uroot --password="${MARIADB_ROOT_PASSWORD}"'

K8up only needs to push the restic output to the restorecommand. K8up only needs to create a restore job, which executes the restic restore command and pushes the output with kubectl to the target pod. I tried this approach sucessfully with the official tutorial setup. The restore job should look like following:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubectl
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: kubectl
rules:
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - list
  - apiGroups:
      - ""
    resources:
      - pods/exec
    verbs:
      - create
  - apiGroups:
      - apps
    resources:
      - deployments
    verbs:
      - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubectl
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubectl
subjects:
  - kind: ServiceAccount
    name: kubectl
---
apiVersion: batch/v1
kind: Job
metadata:
  name: restore-wordpress-mariadb
spec:
  backoffLimit: 1
  template:
    spec:
      restartPolicy: Never
      serviceAccountName: kubectl
      containers:
        - name: mariadb-restore
          image: thomass/restic-kubectl
          command:
            - /bin/sh
            - -c
            - restic dump "${DB_SNAPSHOT_ID}" /default-mariadb | kubectl exec -i deployment/mariadb -- /bin/bash -c 'mysql -uroot --password="${MARIADB_ROOT_PASSWORD}"'
          env:
            - name: RESTIC_REPOSITORY
              value: s3:http://minio-api:9000/backups/
            - name: RESTIC_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: backup-repo
                  key: password
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: minio-credentials
                  key: username
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: minio-credentials
                  key: password

It would be nice when K8up could wrap this functionality into its existing CRD "k8up.io/restore".

ThomasSteinbach avatar Apr 06 '22 18:04 ThomasSteinbach

Hi @ThomasSteinbach

That's a pretty neat idea!

We're currently overthinking the whole pre-backup handling for K8up v3, as it's a bit finicky. See #585. So it's possible that we integrate Kanister into K8up in the future, as it provides pretty flexible handling of such scripts. This would allow to define various hook scripts for the various backup and restore stages.

Kidswiss avatar Apr 07 '22 06:04 Kidswiss

Cool. Looking forward to v3 :)

ThomasSteinbach avatar Apr 07 '22 15:04 ThomasSteinbach