You are looking at the documentation of a prior release. To read the documentation of the latest release, please
visit here.
New to KubeDB? Please start here.
Database Snapshots
This tutorial will show you how to take snapshots of a KubeDB managed MySQL database.
Note: The yaml files used in this tutorial are stored in docs/examples/mysql folder in GitHub repository kubedb/cli.
Before You Begin
At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube.
Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps here.
StorageClass is required to run KubeDB. Check the available StorageClass in cluster.
$ kubectl get storageclasses NAME PROVISIONER AGE standard (default) k8s.io/minikube-hostpath 4h
A
MySQL
database is needed to take snapshot for this tutorial. To keep things isolated, this tutorial uses a separate namespace calleddemo
throughout this tutorial. Run the following command to prepare your cluster for this tutorial:$ kubectl create ns demo namespace "demo" created $ kubectl get ns NAME STATUS AGE demo Active 1m $ kubedb create -f https://raw.githubusercontent.com/kubedb/cli/0.9.0/docs/examples/mysql/snapshot/demo-1.yaml mysql.kubedb.com/mysql-infant created
Instant Backups
You can easily take a snapshot of MySQL
database by creating a Snapshot
object. When a Snapshot
object is created, KubeDB operator will launch a Job that runs the mysql dump
command and uploads the output bson file to various cloud providers S3, GCS, Azure, OpenStack Swift and/or locally mounted volumes using osm.
In this tutorial, snapshots will be stored in a Google Cloud Storage (GCS) bucket. To do so, a secret is needed that has the following 2 keys:
Key | Description |
---|---|
GOOGLE_PROJECT_ID | Required . Google Cloud project ID |
GOOGLE_SERVICE_ACCOUNT_JSON_KEY | Required . Google Cloud service account json key |
$ echo -n '<your-project-id>' > GOOGLE_PROJECT_ID
$ mv downloaded-sa-json.key > GOOGLE_SERVICE_ACCOUNT_JSON_KEY
$ kubectl create secret generic my-snap-secret -n demo \
--from-file=./GOOGLE_PROJECT_ID \
--from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY
secret/my-snap-secret created
$ kubectl get secret my-snap-secret -n demo -o yaml
apiVersion: v1
data:
GOOGLE_PROJECT_ID: PHlvdX....1pZD4=
GOOGLE_SERVICE_ACCOUNT_JSON_KEY: ewogICJ0eXBlIjogInN...9tIgp9Cg==
kind: Secret
metadata:
creationTimestamp: 2018-02-09T12:02:08Z
name: my-snap-secret
namespace: demo
resourceVersion: "30349"
selfLink: /api/v1/namespaces/demo/secrets/my-snap-secret
uid: 0dccee80-0d91-11e8-9091-08002751ae8c
type: Opaque
To lean how to configure other storage destinations for Snapshots, please visit here. Now, create the Snapshot object.
apiVersion: kubedb.com/v1alpha1
kind: Snapshot
metadata:
name: snap-mysql-infant
namespace: demo
labels:
kubedb.com/kind: MySQL
spec:
databaseName: mysql-infant
storageSecretName: my-snap-secret
gcs:
bucket: kubedb
$ kubedb create -f https://raw.githubusercontent.com/kubedb/cli/0.9.0/docs/examples/mysql/snapshot/demo-2.yaml
snapshot.kubedb.com/snap-mysql-infant created
$ kubedb get snap -n demo
NAME DATABASENAME STATUS AGE
snap-mysql-infant mysql-infant Running 13s
$ kubedb get snap -n demo snap-mysql-infant -o yaml
apiVersion: kubedb.com/v1alpha1
kind: Snapshot
metadata:
creationTimestamp: 2018-09-27T06:12:37Z
finalizers:
- kubedb.com
generation: 1
labels:
kubedb.com/kind: MySQL
kubedb.com/name: mysql-infant
name: snap-mysql-infant
namespace: demo
resourceVersion: "1754"
selfLink: /apis/kubedb.com/v1alpha1/namespaces/demo/snapshots/snap-mysql-infant
uid: 54efc1fe-c21c-11e8-850e-080027517bbf
spec:
databaseName: mysql-infant
gcs:
bucket: kubedb
storageSecretName: my-snap-secret
status:
completionTime: 2018-09-27T06:18:41Z
phase: Succeeded
startTime: 2018-09-27T06:12:38Z
Here,
metadata.labels
should include the type of databasekubedb.com/kind: MySQL
whose snapshot will be taken.spec.databaseName
points to the database whose snapshot is taken.spec.storageSecretName
points to the Secret containing the credentials for snapshot storage destination.spec.gcs.bucket
points to the bucket name used to store the snapshot data.
You can also run the kubedb describe
command to see the recent snapshots taken for a database.
$ kubedb describe my -n demo mysql-infant
Name: mysql-infant
Namespace: demo
CreationTimestamp: Thu, 27 Sep 2018 12:12:10 +0600
Labels: <none>
Annotations: <none>
Replicas: 1 total
Status: Running
StorageType: Durable
Volume:
StorageClass: standard
Capacity: 50Mi
Access Modes: RWO
StatefulSet:
Name: mysql-infant
CreationTimestamp: Thu, 27 Sep 2018 12:12:11 +0600
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-infant
Annotations: <none>
Replicas: 824641842156 desired | 1 total
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Service:
Name: mysql-infant
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-infant
Annotations: <none>
Type: ClusterIP
IP: 10.109.47.223
Port: db 3306/TCP
TargetPort: db/TCP
Endpoints: 172.17.0.5:3306
Database Secret:
Name: mysql-infant-auth
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-infant
Annotations: <none>
Type: Opaque
Data
====
password: 16 bytes
user: 4 bytes
Snapshots:
Name Bucket StartTime CompletionTime Phase
---- ------ --------- -------------- -----
snap-mysql-infant gs:kubedb Thu, 27 Sep 2018 12:12:38 +0600 Thu, 27 Sep 2018 12:18:41 +0600 Succeeded
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Successful 17m MySQL operator Successfully created Service
Normal Starting 17m Job Controller Backup running
Normal Successful 14m MySQL operator Successfully created StatefulSet
Normal Successful 14m MySQL operator Successfully created MySQL
Normal Successful 14m MySQL operator Successfully patched StatefulSet
Normal Successful 14m MySQL operator Successfully patched MySQL
Normal Successful 14m MySQL operator Successfully patched StatefulSet
Normal Successful 14m MySQL operator Successfully patched MySQL
Normal SuccessfulSnapshot 11m Job Controller Successfully completed snapshot
Once the snapshot Job is complete, you should see the output of the mysql dump
command stored in the GCS bucket.
From the above image, you can see that the snapshot output is stored in a folder called {bucket}/kubedb/{namespace}/{mysql-object}/{snapshot}/
.
Restore from Snapshot
You can create a new database from a previously taken Snapshot. Specify the Snapshot name in the spec.init.snapshotSource
field of a new MySQL object. See the example mysql-recovered
object below:
Note: MySQL
mysql-recovered
must have same superuser credentials as MySQLmysql-infant
.
apiVersion: kubedb.com/v1alpha1
kind: MySQL
metadata:
name: mysql-recovered
namespace: demo
spec:
version: "8.0-v1"
databaseSecret:
secretName: mysql-infant-auth
storage:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
init:
snapshotSource:
name: snap-mysql-infant
namespace: demo
$ kubedb create -f https://raw.githubusercontent.com/kubedb/cli/0.9.0/docs/examples/mysql/snapshot/demo-3.yaml
mysql.kubedb.com/mysql-recovered created
Here,
spec.init.snapshotSource.name
refers to a Snapshot object for a MySQL database in the same namespaces as this newmysql-recovered
MySQL object.
Now, wait several seconds. KubeDB operator will create a new StatefulSet. Then KubeDB operator launches a Kubernetes Job to initialize the new database using the data from snap-mysql-infant
Snapshot.
$ kubedb get my -n demo
NAME VERSION STATUS AGE
mysql-infant 8.0-v1 Running 27m
mysql-recovered 8.0-v1 Initializing 5m
$ kubedb get my -n demo
NAME VERSION STATUS AGE
mysql-infant 8.0-v1 Running 31m
mysql-recovered 8.0-v1 Running 9m
$ kubedb describe my -n demo mysql-recovered
Name: mysql-recovered
Namespace: demo
CreationTimestamp: Thu, 27 Sep 2018 12:34:07 +0600
Labels: <none>
Annotations: kubedb.com/initialized=
Replicas: 1 total
Status: Running
StorageType: Durable
Volume:
StorageClass: standard
Capacity: 50Mi
Access Modes: RWO
StatefulSet:
Name: mysql-recovered
CreationTimestamp: Thu, 27 Sep 2018 12:34:09 +0600
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-recovered
Annotations: <none>
Replicas: 824640109500 desired | 1 total
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Service:
Name: mysql-recovered
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-recovered
Annotations: <none>
Type: ClusterIP
IP: 10.99.66.59
Port: db 3306/TCP
TargetPort: db/TCP
Endpoints: 172.17.0.6:3306
Database Secret:
Name: mysql-infant-auth
Labels: kubedb.com/kind=MySQL
kubedb.com/name=mysql-infant
Annotations: <none>
Type: Opaque
Data
====
password: 16 bytes
user: 4 bytes
No Snapshots.
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Successful 9m MySQL operator Successfully created Service
Normal Successful 9m MySQL operator Successfully created MySQL
Normal Successful 9m MySQL operator Successfully created StatefulSet
Normal Initializing 9m MySQL operator Initializing from Snapshot: "snap-mysql-infant"
Normal Successful 8m MySQL operator Successfully patched StatefulSet
Normal Successful 8m MySQL operator Successfully patched MySQL
Normal SuccessfulInitialize 3m Job Controller Successfully completed initialization
Cleaning up
To cleanup the Kubernetes resources created by this tutorial, run:
kubectl patch -n demo mysql/mysql-infant mysql/mysql-recovered -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge"
kubectl delete -n demo mysql/mysql-infant mysql/mysql-recovered
kubectl patch -n demo drmn/mysql-infant drmn/mysql-recovered -p '{"spec":{"wipeOut":true}}' --type="merge"
kubectl delete -n demo drmn/mysql-infant drmn/mysql-recovered
kubectl delete ns demo
Next Steps
- See the list of supported storage providers for snapshots here.
- Take Scheduled Snapshot of MySQL databases using KubeDB.
- Initialize MySQL with Script.
- Initialize MySQL with Snapshot.
- Monitor your MySQL database with KubeDB using out-of-the-box CoreOS Prometheus Operator.
- Monitor your MySQL database with KubeDB using out-of-the-box builtin-Prometheus.
- Use private Docker registry to deploy MySQL with KubeDB.
- Detail concepts of MySQL object.
- Detail concepts of MySQLVersion object.
- Want to hack on KubeDB? Check our contribution guidelines.