These examples demonstrate how to use backup and restore hooks in Tanzu Mission Control.

Example 1: MongoDB Backup Hook

Note: To run backups and restores, you must be associated with the cluster.admin role in the cluster.
  1. Install mongodb via the Bitnami Helm chart (version 13.15.4 is used in this example).
    $ kubectl create ns my-mongodb-app
    $ helm repo add bitnami https://charts.bitnami.com/bitnami
    $ helm install my-mongodb-app bitnami/mongodb --namespace=my-mongodb-app --set replicaSet.enabled=true
    
  2. Exec into the created pod and enter some data into the database.
    % kubectl -n my-mongodb-app exec -it my-mongodb-app-<random suffix> -- bash
    $ mongosh --authenticationDatabase admin -u root -p "${MONGODB_ROOT_PASSWORD}"
    examples> db.movies.insertMany([
    ...    {
    ...       title: 'Titanic',
    ...       year: 1997,
    ...       genres: [ 'Drama', 'Romance' ],
    ...       rated: 'PG-13',
    ...       languages: [ 'English', 'French', 'German', 'Swedish', 'Italian', 'Russian' ],
    ...       released: ISODate("1997-12-19T00:00:00.000Z"),
    ...       awards: {
    ...          wins: 127,
    ...          nominations: 63,
    ...          text: 'Won 11 Oscars. Another 116 wins & 63 nominations.'
    ...       },
    ...       cast: [ 'Leonardo DiCaprio', 'Kate Winslet', 'Billy Zane', 'Kathy Bates' ],
    ...       directors: [ 'James Cameron' ]
    ...    },
    ...    ...
    ... ])
    
  3. Log in to the Tanzu Mission Control console, and then navigate to the cluster detail page for the cluster that you want to back up.
  4. Click the Data Protection tab.
  5. Create a namespace backup for Mongodb and create a backup pre-hook to flush all pending write operations to disk and lock the entire Mongodb instance to prevent additional writes. The post-hook then releases the lock once the backup has been completed.

    Use the following settings to define the hooks in the Tanzu Mission Control console.
    • For the hook name, enter mongodb-hook.
    • Click Included namespaces and select my-mongodb-app.
    • Click Use label selector to enable label selection.
    • In the key field, enter app.kubernetes.io/name.
    • For the operator, specify = (equal sign).
    • Enter mongodb for the value.
    • Configure the backup pre-hook 1, specifying the container name as mongodb, a timeout value of 30 seconds, and set to Fail on error. Configure the command as follows:
      /bin/bash
      -o
      errexit
      -o
      pipefail
      -c
      mongosh --authenticationDatabase admin -u root -p "${MONGODB_ROOT_PASSWORD}" --eval="db.fsyncLock()"
      
    • Configure the backup post-hook 1, specifying the container name as mongodb, with a timeout value of 30 seconds and set to Fail on error. Configure the command as follows:
      /bin/bash
      -o
      errexit
      -o
      pipefail
      -c
      mongosh --authenticationDatabase admin -u root -p "${MONGODB_ROOT_PASSWORD}" --eval="db.fsyncUnlock()"
      
  6. Delete the namespace and all the pods and persistent volumes in order to test the restore.
    % kubectl delete ns my-mongodb-app
    
  7. Restore the created backup (no restore hooks required). After the restore completes, exec into the restore pod to verify that the data is as expected.

    % kubectl -n my-mongodb-app exec -it my-mongodb-app-<random suffix> -- bash
    $ mongosh --authenticationDatabase admin -u root -p "${MONGODB_ROOT_PASSWORD}"
    test> use examples
    switched to db examples
    examples> db.movies.find( { } )
    [
      {
        _id: ObjectId("64abe5d779ad9a6eaa4f456f"),
        title: 'Titanic',
        year: 1997,
        genres: [ 'Drama', 'Romance' ],
        rated: 'PG-13',
        languages: [ 'English', 'French', 'German', 'Swedish', 'Italian', 'Russian' ],
        released: ISODate("1997-12-19T00:00:00.000Z"),
        awards: {
          wins: 127,
          nominations: 63,
          text: 'Won 11 Oscars. Another 116 wins & 63 nominations.'
        },
        cast: [
          'Leonardo DiCaprio',
          'Kate Winslet',
          'Billy Zane',
          'Kathy Bates'
        ],
        directors: [ 'James Cameron' ]
      },
    ...
    ]
    

Example 2: Wordpress/MariaDB Backup and Restore Exec Hook

In the following example we use hooks to take a consistent backup of the mariadb instance used by Wordpress, but not the wordpress volume itself, since that should be mostly static data.

  1. Install Wordpress via the Bitnami Helm chart (version 16.1.25 in this example).
    $ kubectl create ns wordpress
    $ helm repo add bitnami https://charts.bitnami.com/bitnami
    $ helm install --namespace wordpress wordpress bitnami/wordpress
    
  2. Exec into the pod and populate some data. This example adds data to the database directly but you may alternatively populate data using the wordpress frontend.

    $ kubectl -n wordpress exec -it wordpress-mariadb-0 -- bash
    $ mariadb -u 'root' -p"$MARIADB_ROOT_PASSWORD"
    MariaDB [(none)]> CREATE DATABASE my_db_name;
    Query OK, 1 row affected (0.000 sec)
    
    MariaDB [(none)]>    USE my_db_name;
    Database changed
    
    MariaDB [my_db_name]>    CREATE TABLE users (
        ->      id INT AUTO_INCREMENT PRIMARY KEY,
        ->      name VARCHAR(50),
        ->      email VARCHAR(50)
        ->    );
    Query OK, 0 rows affected (0.014 sec)
    
    MariaDB [my_db_name]>    INSERT INTO users (name, email) VALUES
        ->      ('John Doe', '[email protected]'),
        ->      ('Jane Smith', '[email protected]');
    Query OK, 2 rows affected (0.007 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    MariaDB [my_db_name]>    SELECT * FROM users;
    +----+------------+------------------+
    | id | name       | email            |
    +----+------------+------------------+
    |  1 | John Doe   | [email protected] |
    |  2 | Jane Smith | [email protected] |
    +----+------------+------------------+
    2 rows in set (0.000 sec)
    
  3. Log in to the Tanzu Mission Control console, and then navigate to the cluster detail page for the cluster that you want to back up.
  4. Click the Data Protection tab.
  5. Take a namespace backup. Specify a pre hook to use the mariadb-dump tool to take a dump of the db. Optionally, specify a post hook to get rid of the dump taken after it has been backed up.

    • For the hook name, enter wordpress-hook.
    • Click Included namespaces and select wordpress.
    • Click Use label selector to enable label selection.
    • In the key field, enter app.kubernetes.io/name.
    • For the operator, specify = (equal sign).
    • Enter mariadb for the value.
    • Configure the backup pre-hook 1, specifying the container name as mariadb, a timeout value of 5 minutes, and set to Fail on error. Configure the command as follows:
      /bin/bash
      -o
      errexit
      -o
      pipefail
      -c
      mariadb-dump -u 'root' -p"$MARIADB_ROOT_PASSWORD" --single-transaction --all-databases > /bitnami/mariadb/mybackup
      
    • Configure the backup post-hook 1, specifying the container name as mariadb, with a timeout value of 30 seconds and set to Fail on error. Configure the command as follows:
      /bin/bash
      -o
      errexit
      -o
      pipefail
      -c
      rm -f /bitnami/mariadb/mybackup
      
  6. Delete the namespace and all its resources to test the restore.

    % kubectl delete ns wordpress
  7. Perform a namespace restore. Specify an Exec restore hook that restores the database contents using the dump taken using the backup hook.

    • For the hook name, enter wordpress-hook.
    • Click Included namespaces and select wordpress.
    • Click Use label selector to enable label selection.
    • In the key field, enter app.kubernetes.io/name.
    • For the operator, specify = (equal sign).
    • Enter mariadb for the value.
    • Configure the restore Exec hook 1, specifying the container name as mariadb, a timeout value of 10 minutes, and set to Fail on error. Configure the command as follows:
      /bin/bash
      -o
      errexit
      -o
      pipefail
      -c
      sleep 1m && mariadb -u 'root' -p"$MARIADB_ROOT_PASSWORD" < /bitnami/mariadb/mybackup && rm -f /bitnami/mariadb/mybackup
      
  8. Exec into the restored pod to verify that the data was restored.

    $ kubectl -n wordpress exec -it wordpress-mariadb-0 -- bash
    $ mariadb -u 'root' -p"$MARIADB_ROOT_PASSWORD"
    MariaDB [(none)]>    USE my_db_name;
    Database changed
    MariaDB [my_db_name]>    SELECT * FROM users;
    +----+------------+------------------+
    | id | name       | email            |
    +----+------------+------------------+
    |  1 | John Doe   | [email protected] |
    |  2 | Jane Smith | [email protected] |
    +----+------------+------------------+
    2 rows in set (0.000 sec)
    
    Note:

    The above uses mariadb-dump to make a logical backup of the database. You may instead use mariabackup to take a physical backup, but this requires stopping the mariadb server while performing the restore.

Example 3: Init Container Restore Hooks

You can define init container hooks to perform necessary setup before the actual application containers start. The init container definition must be provided in YAML (as you would in a pod manifest). At a minimum, name, image and command must be populated. If you wish to define multiple init containers, place each YAML definition in a separate init container hook.

  • For the hook name, enter my-init-hook.
  • Click Included namespaces and select my-namespace.
  • Click Use label selector to enable label selection.
  • In the key field, enter app.kubernetes.io/name.
  • For the operator, specify = (equal sign).
  • Enter myapp for the value.
  • Define the init container hook 1:
    name: restore-hook-init1
    image: alpine:latest
     volumeMounts:
      - mountPath: /restores/pvc1-vm
        name: pvc1-vm
      command:
      - /bin/ash
      - -c
      - echo -n "FOOBARBAZ" >> /restores/pvc1-vm/foobarbaz
    
  • Define init container hook 2:
    - name: restore-hook-init2
      image: alpine:latest
      volumeMounts:
      - mountPath: /restores/pvc2-vm
        name: pvc2-vm
      command:
      - /bin/ash
      - -c
      - echo -n "DEADFEED" >> /restores/pvc2-vm/deadfeed
    
Note: The above example assumes volumes pvc1-vm and pvc2-vm are defined on the pods for which this hook will be applied.