New to KubeDB? Please start here.
Initializing with Snapshot
This guide will show you how to create database and initialize snapshot with MongoDB Schema Manager
using Schema Manager Operator
.
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 kind.Install
KubeDB
in your cluster following the steps here.Install
KubeVault
in your cluster following the steps here.You should be familiar with the following concepts:
Note: YAML files used in this tutorial are stored in docs/guides/mongodb/schema-manager/initializing-with-snapshot/yamls directory of kubedb/doc repository.
Create Namespace
We are going to create two different namespaces, in db
namespace we will deploy MongoDB and Vault Server and in demo
namespacae we will deploy Schema Manager
. Let’s create those namespace using the following yaml,
apiVersion: v1
kind: Namespace
metadata:
name: db
labels:
kubernetes.io/metadata.name: db
---
apiVersion: v1
kind: Namespace
metadata:
name: demo
labels:
kubernetes.io/metadata.name: demo
Let’s save this yaml configuration into namespace.yaml
Then create those above namespaces.
$ kubectl apply -f namespace.yaml
namespace/db created
namespace/demo created
Deploy MongoDB Server and Vault Server
Here, we are going to deploy a MongoDB Server
by using KubeDB
operator. Also, we are deploying a Vault Server
using KubeVault
Operator.
Deploy MongoDB Server
In this section, we are going to deploy a MongoDB Server. Let’s deploy it using this following yaml,
apiVersion: kubedb.com/v1
kind: MongoDB
metadata:
name: mongodb
namespace: db
spec:
allowedSchemas:
namespaces:
from: All
version: "4.4.26"
replicaSet:
name: "replicaset"
podTemplate:
spec:
containers:
- name: mongo
resources:
requests:
cpu: "100m"
memory: "100Mi"
replicas: 3
storageType: Durable
storage:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
deletionPolicy: WipeOut
Here,
spec.version
is the name of the MongoDBVersion CR. Here, we are using MongoDB version4.4.26
.spec.storageType
specifies the type of storage that will be used for MongoDB. It can beDurable
orEphemeral
. The default value of this field isDurable
. IfEphemeral
is used then KubeDB will create the MongoDB usingEmptyDir
volume.spec.storage
specifies the StorageClass of PVC dynamically allocated to store data for this database. This storage spec will be passed to the PetSet created by KubeDB operator to run database pods. So, each members will have a pod of this storage configuration. You can specify any StorageClass available in your cluster with appropriate resource requests.spec.allowedSchemas
specifies the namespace and selectors of allowedSchema Manager
.spec.deletionPolicy
specifies what KubeDB should do when a user try to delete the operation of MongoDB CR. Wipeout means that the database will be deleted without restrictions. It can also be “Halt”, “Delete” and “DoNotTerminate”. Learn More about these HERE.
Let’s save this yaml configuration into mongodb.yaml
Then create the above MongoDB
CR
$ kubectl apply -f mongodb.yaml
mongodb.kubedb.com/mongodb created
Deploy Vault Server
In this section, we are going to deploy a Vault Server. Let’s deploy it using this following yaml,
apiVersion: kubevault.com/v1alpha1
kind: VaultServer
metadata:
name: vault
namespace: demo
spec:
version: 1.8.2
replicas: 3
allowedSecretEngines:
namespaces:
from: All
secretEngines:
- mongodb
unsealer:
secretShares: 5
secretThreshold: 3
mode:
kubernetesSecret:
secretName: vault-keys
backend:
raft:
path: "/vault/data"
storage:
storageClassName: "standard"
resources:
requests:
storage: 1Gi
authMethods:
- type: kubernetes
path: kubernetes
terminationPolicy: WipeOut
Here,
spec.version
is a required field that specifies the original version of Vault that has been used to build the docker image specified inspec.vault.image
field.spec.replicas
specifies the number of Vault nodes to deploy. It has to be a positive number.spec.allowedSecretEngines
defines the types of Secret Engines & the Allowed namespaces from where aSecretEngine
can be attached to theVaultServer
.spec.unsealer
is an optional field that specifiesUnsealer
configuration.Unsealer
handles automatic initializing and unsealing of Vault.spec.backend
is a required field that specifies the Vault backend storage configuration. KubeVault operator generates storage configuration according to thisspec.backend
.spec.authMethods
is an optional field that specifies the list of auth methods to enable in Vault.spec.deletionPolicy
is an optional field that gives flexibility whether to nullify(reject) the delete operation of VaultServer crd or which resources KubeVault operator should keep or delete when you delete VaultServer crd.
Let’s save this yaml configuration into vault.yaml
Then create the above VaultServer
CR
$ kubectl apply -f vault.yaml
vaultserver.kubevault.com/vault created
Create Repository Secret
Here, we are using local backend for storing data snapshots. It can be a cloud storage like GCS bucket, AWS S3, Azure Blob Storage, NFS etc. or a Kubernetes native resources like HostPath, PersistentVolumeClaim etc. For more information check HERE
Let’s, create a Secret for our Repository,
$ echo -n 'changeit' > RESTIC_PASSWORD
$ kubectl create secret generic -n demo repo-secret --from-file=./RESTIC_PASSWORD
secret/repo-secret created
Let’s save this yaml configuration into repo-secret.yaml
Then create the secret,
$ kubectl apply -f repo-secret.yaml
secret/repo-secret created
Create Repository
apiVersion: stash.appscode.com/v1alpha1
kind: Repository
metadata:
name: repo
namespace: demo
spec:
backend:
local:
mountPath: /hello
persistentVolumeClaim:
claimName: snapshot-pvc
storageSecretName: repo-secret
usagePolicy:
allowedNamespaces:
from: All
This repository CRO specifies the repo-secret
that we’ve created before and specifies the name and path to the local storage PVC
.
Note: Here, we are using local storage
PVC
. MyPVC
name issnapshot-pvc
. Don’t forget to changebackend.local.persistentVolumeClaim.claimName
to yourPVC
name.
Let’s save this yaml configuration into repo.yaml
Lets create the repository,
$ kubectl apply -f repo.yaml
repository.stash.appscode.com/repo created
After creating the repository we’ve backed up one of our MongoDB database with some sample data via Stash. So, now our repository contains some sample data inside it.
Configure Snapshot Restore
Now, We are going to create a ServiceAccount, ClusterRole and ClusterRoleBinding. Stash does not grant necessary RBAC permissions to the restore job for taking restore from a different namespace. In this case, we have to provide the RBAC permissions manually. This helps to prevent unauthorized namespaces from getting access to a database via Stash. You can configure this process through this Documentation
Deploy Schema Manager Initialize with Snapshot
Here, we are going to deploy Schema Manager
with the demo
namespace that we have created above. Let’s deploy it using the following yaml,
apiVersion: schema.kubedb.com/v1alpha1
kind: MongoDBDatabase
metadata:
name: schema-restore
namespace: demo
spec:
database:
serverRef:
name: mongodb
namespace: db
config:
name: products
vaultRef:
name: vault
namespace: demo
accessPolicy:
subjects:
- name: "saname"
namespace: db
kind: "ServiceAccount"
apiGroup: ""
defaultTTL: "5m"
maxTTL: "200h"
init:
initialized: false
snapshot:
repository:
name: repo
namespace: demo
deletionPolicy: Delete
Here,
spec.database
is a required field specifying the database server reference and the desired database configuration.spec.vaultRef
is a required field that specifies which KubeVault server to use for user management.spec.accessPolicy
is a required field that specifies the access permissions like which service account or cluster user have the access and also for how long they can access through it.spec.init
is an optional field, containing the information of a script or a snapshot using which the database should be initialized during creation.spec.deletionPolicy
is an optional field that gives flexibility whether tonullify
(reject) the delete operation.
Let’s save this yaml configuration into schema-restore.yaml
and apply it,
$ kubectl apply -f schema-restore.yaml
mongodbdatabase.schema.kubedb.com/schema-restore created
Let’s check the STATUS
of Schema Manager
,
$ kubectl get mongodbdatabase -A
NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE
demo schema-restore mongodb products Current 56s
Here,
In
STATUS
section,Current
means that the currentSecret
ofSchema Manager
is vaild, and it will automaticallyExpired
after it reaches the limit ofdefaultTTL
that we’ve defined in the above yaml.
Also, check the STATUS
of restoresession
$ kubectl get restoresession -n demo
NAME REPOSITORY PHASE DURATION AGE
schema-restore-mongo-rs repo Succeeded 5s 21s
Now, let’s get the secret name from schema-manager
, and the login credentials for connecting to the database,
$ kubectl get mongodbdatabase schema-restore -n demo -o=jsonpath='{.status.authSecret.name}'
schema-restore-mongo-req-98k0ch
$ kubectl view-secret -n demo schema-restore-mongo-req-98k0ch -a
password=6ykdBljJ7D8agXeoSp-f
username=v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843
Verify Initialization
Here, we are going to connect to the database with the login credentials and verify the database initialization,
$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash
root@mongodb-0:/# mongo --authenticationDatabase=products --username='v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843' --password='6ykdBljJ7D8agXeoSp-f' products
MongoDB shell version v4.4.26
...
replicaset:PRIMARY> show dbs
products 0.000GB
replicaset:PRIMARY> show collections
products
replicaset:PRIMARY> db.products.find()
{ "_id" : ObjectId("631b3139187d1588626fb80b"), "name" : "kubedb" }
replicaset:PRIMARY> exit
bye
Now, Let’s check the STATUS
of Schema Manager
again,
$ kubectl get mongodbdatabase -A
NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE
demo schema-restore mongodb products Expired 7m
Here, we can see that the STATUS
of the schema-manager
is Expired
because it’s exceeded defaultTTL: "5m"
, which means the current Secret
of Schema Manager
isn’t vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from schema-manager
, it won’t work.
$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash
root@mongodb-0:/# mongo --authenticationDatabase=products --username='v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843' --password='6ykdBljJ7D8agXeoSp-f' products
MongoDB shell version v4.4.26
connecting to: mongodb://127.0.0.1:27017/initdb?authSource=initdb&compressors=disabled&gssapiServiceName=mongodb
Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:374:17
@(connect):2:6
exception: connect failed
exiting with code 1
root@mongodb-0:/# exit
exit
We can’t connect to the database with the login credentials, which is
Expired
. We will not be able to access the database even though we’re in the middle of a connected session.
Cleaning Up
To clean up the Kubernetes resources created by this tutorial, run:
$ kubectl delete ns db
$ kubectl delete ns demo
Next Steps
- Detail concepts of MongoDBDatabase object.
- Go through the concepts of KubeVault.
- Detail concepts of MongoDB object.
- Detail concepts of MongoDBVersion object.