Logical MongoDB Backup
If it hasn't been done already, the bitnami
Helm repository needs to
be added to your local configuration:
# Add bitnami helm repo
$ helm repo add bitnami https://charts.bitnami.com/bitnami
Install the MongoDB chart from the bitnami
Helm repository:
$ kubectl create namespace mongodb-logical
$ helm install mongo-logical bitnami/mongodb --namespace mongodb-logical \
--set architecture="replicaset"
Next create a file mongo-blueprint.yaml
with the following contents
apiVersion: cr.kanister.io/v1alpha1
kind: Blueprint
metadata:
name: mongodb-blueprint
actions:
backup:
outputArtifacts:
mongoBackup:
# Capture the kopia snapshot information for subsequent actions
# The information includes the kopia snapshot ID which is essential for restore and delete to succeed
# `kopiaOutput` is the name provided to kando using `--output-name` flag
kopiaSnapshot: "{{ .Phases.takeConsistentBackup.Output.kopiaOutput }}"
phases:
- func: MultiContainerRun
name: takeConsistentBackup
objects:
mongosecret:
kind: Secret
name: '{{ .StatefulSet.Name }}'
namespace: "{{ .StatefulSet.Namespace }}"
args:
namespace: "{{ .StatefulSet.Namespace }}"
sharedVolumeMedium: Memory
initImage: '{{if index .Options "kanisterImage" }} {{- .Options.kanisterImage -}} {{else -}} ghcr.io/kanisterio/kanister-tools:0.113.0 {{- end}}'
initCommand: ["bash", "-o", "errexit", "-o", "pipefail", "-c", "mkfifo /tmp/data; chmod 666 /tmp/data"]
backgroundImage: bitnami/mongodb:7.0-debian-12
backgroundCommand:
- bash
- -o
- errexit
- -o
- pipefail
- -c
- |
host='{{ .StatefulSet.Name }}-0.{{ .StatefulSet.Name }}-headless.{{ .StatefulSet.Namespace }}.svc.cluster.local'
dbPassword='{{ index .Phases.takeConsistentBackup.Secrets.mongosecret.Data "mongodb-root-password" | toString }}'
dump_cmd="mongodump --oplog --gzip --archive --host ${host} -u root -p ${dbPassword}"
${dump_cmd} > /tmp/data
outputImage: '{{if index .Options "kanisterImage" }} {{- .Options.kanisterImage -}} {{else -}} ghcr.io/kanisterio/kanister-tools:0.113.0 {{- end}}'
outputCommand:
- bash
- -o
- errexit
- -o
- pipefail
- -c
- |
backup_file_path='rs_backup.gz'
cat /tmp/data | kando location push --profile '{{ toJson .Profile }}' --path "${backup_file_path}" --output-name "kopiaOutput" -
restore:
inputArtifactNames:
# The kopia snapshot info created in backup phase can be used here
# Use the `--kopia-snapshot` flag in kando to pass in `mongoBackup.KopiaSnapshot`
- mongoBackup
phases:
- func: MultiContainerRun
name: pullFromStore
objects:
mongosecret:
kind: Secret
name: '{{ .StatefulSet.Name }}'
namespace: "{{ .StatefulSet.Namespace }}"
args:
namespace: "{{ .StatefulSet.Namespace }}"
sharedVolumeMedium: Memory
initImage: '{{if index .Options "kanisterImage" }} {{- .Options.kanisterImage -}} {{else -}} ghcr.io/kanisterio/kanister-tools:0.113.0 {{- end}}'
initCommand: ["bash", "-o", "errexit", "-o", "pipefail", "-c", "mkfifo /tmp/data; chmod 666 /tmp/data"]
backgroundImage: '{{if index .Options "kanisterImage" }} {{- .Options.kanisterImage -}} {{else -}} ghcr.io/kanisterio/kanister-tools:0.113.0 {{- end}}'
backgroundCommand:
- bash
- -o
- errexit
- -o
- pipefail
- -c
- |
backup_file_path='rs_backup.gz'
kopia_snap='{{ .ArtifactsIn.mongoBackup.KopiaSnapshot }}'
kando location pull --profile '{{ toJson .Profile }}' --path "${backup_file_path}" --kopia-snapshot "${kopia_snap}" - > /tmp/data
outputImage: bitnami/mongodb:7.0-debian-12
outputCommand:
- bash
- -o
- errexit
- -o
- pipefail
- -c
- |
host='{{ .StatefulSet.Name }}-0.{{ .StatefulSet.Name }}-headless.{{ .StatefulSet.Namespace }}.svc.cluster.local'
dbPassword='{{ index .Phases.pullFromStore.Secrets.mongosecret.Data "mongodb-root-password" | toString }}'
restore_cmd="mongorestore --gzip --archive --oplogReplay --drop --host ${host} -u root -p ${dbPassword}"
cat /tmp/data | ${restore_cmd}
delete:
inputArtifactNames:
# The kopia snapshot info created in backup phase can be used here
# Use the `--kopia-snapshot` flag in kando to pass in `mongoBackup.KopiaSnapshot`
- mongoBackup
phases:
- func: KubeTask
name: deleteFromStore
args:
namespace: "{{ .Namespace.Name }}"
image: '{{if index .Options "kanisterImage" }} {{- .Options.kanisterImage -}} {{else -}} ghcr.io/kanisterio/kanister-tools:0.113.0 {{- end}}'
command:
- bash
- -o
- errexit
- -o
- pipefail
- -c
- |
backup_file_path='rs_backup.gz'
kopia_snap='{{ .ArtifactsIn.mongoBackup.KopiaSnapshot }}'
kando location delete --profile '{{ toJson .Profile }}' --path "${backup_file_path}" --kopia-snapshot "${kopia_snap}"
And then apply the file using:
$ kubectl apply -f mongo-blueprint.yaml --namespace kasten-io
The MongoDB backup example above serves as a blueprint template for logical backups. Please note that these examples may need to be modified for specific production environments and setups. As a result, it is highly recommended to carefully review and modify the blueprints as needed before deploying them for production use.
Alternatively, use the Blueprints page on Veeam Kasten Dashboard to create the Blueprint resource.
If MongoDB chart is installed specifying existing secret by setting
parameter --set auth.existingSecret=<mongo-secret-name>
, secret name
in the blueprint mongo-blueprint.yaml
needs to be modified at
following places:
actions.backup.phases[0].objects.mongosecret.name:
<mongo-secret-name>
actions.restore.phases[0].objects.mongosecret.name:
<mongo-secret-name>
Once the Blueprint is created, we will have to annotate the StatefulSet
with the correct annotation to instruct Veeam Kasten to use the
Blueprint while performing operations on this MongoDB instance. The
following example demonstrates how to annotate the MongoDB StatefulSet
with the mongodb-logical
Blueprint.
$ kubectl annotate statefulset mongo-logical-mongodb kanister.kasten.io/blueprint='mongodb-blueprint' \
--namespace=mongodb-logical
Finally, use Veeam Kasten to backup and restore the application.