In this article, we'll explore how to set up two MongoDB instances in a Kubernetes cluster, one with persistent storage and the other without. This exercise will not only help you understand how Kubernetes handles storage but also provide you with practical insights into the differences between persistent and non-persistent storage.
Setting Up the Environment
Step 1: Create Namespaces
First, we need to create two namespaces: persist for the MongoDB instance with persistent storage and non-persist for the instance without. You can create these namespaces using the following commands:
kubectl create namespace persist
kubectl create namespace non-persist
Step 2: Deploy MongoDB with Persistent Storage
To deploy MongoDB with persistent storage, we will need to create a Persistent Volume (PV) and a Persistent Volume Claim (PVC). Here’s how to do it:
Create a YAML file named mongodb-persist.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodb-pv
namespace: persist
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/mongodb # Adjust this path as needed
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc
namespace: persist
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb
namespace: persist
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
volumeMounts:
- mountPath: /data/db
name: mongodb-storage
volumes:
- name: mongodb-storage
persistentVolumeClaim:
claimName: mongodb-pvc
Apply the configuration:
kubectl apply -f mongodb-persist.yaml
Step 3: Deploy MongoDB without Persistent Storage
Next, we will deploy a MongoDB instance in the non-persist namespace without persistent storage.
Create a YAML file named mongodb-non-persist.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb
namespace: non-persist
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
Apply the configuration:
kubectl apply -f mongodb-non-persist.yaml
Step 4: Expose MongoDB Services
To interact with both MongoDB instances, we need to create services for them.
Create a service for the persistent MongoDB:
apiVersion: v1
kind: Service
metadata:
name: mongodb
namespace: persist
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
Create a service for the non-persistent MongoDB:
apiVersion: v1
kind: Service
metadata:
name: mongodb
namespace: non-persist
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
Apply both configurations:
kubectl apply -f mongodb-service-persist.yaml
kubectl apply -f mongodb-service-non-persist.yaml
Step 5: Create Sample Database and Collection
We can create a sample database and collection in both MongoDB instances using a temporary MongoDB client pod.
For the persistent MongoDB:
kubectl run -it --rm --namespace=persist mongo-client --image=mongo -- bash
Inside the mongo-client pod, run:
mongosh --host mongodb --eval 'db = db.getSiblingDB("testdb"); db.createCollection("testcollection"); db.testcollection.insertOne({"name": "sample", "value": 123});'
For the non-persistent MongoDB:
kubectl run -it --rm --namespace=non-persist mongo-client --image=mongo -- bash
Inside the mongo-client pod, run:
mongosh --host mongodb --eval 'db = db.getSiblingDB("testdb"); db.createCollection("testcollection"); db.testcollection.insertOne({"name": "sample", "value": 123});'
Step 6: Validate Persistence vs. Non-Persistence
To demonstrate the differences in data persistence, we can restart the MongoDB pods in both namespaces.
For the persistent MongoDB:
Get the pod name:
kubectl get pods -n persist
Delete the MongoDB pod:
kubectl delete pod <mongodb-pod-name> --namespace=persist
For the non-persistent MongoDB:
Get the pod name:
kubectl get pods -n non-persist
Delete the MongoDB pod:
kubectl delete pod <mongodb-pod-name> --namespace=non-persist
After restarting the pods, reconnect to MongoDB in both namespaces to check for data availability.
For Persistent MongoDB:
kubectl run -it --rm --namespace=persist mongo-client --image=mongo -- bash
Inside the mongo-client pod, check the data:
mongosh --host mongodb --eval 'db = db.getSiblingDB("testdb"); db.testcollection.find().pretty();'
You should see the document you inserted earlier.
For Non-Persistent MongoDB:
kubectl run -it --rm --namespace=non-persist mongo-client --image=mongo -- bash
Inside the mongo-client pod, check for the data:
mongosh --host mongodb --eval 'db = db.getSiblingDB("testdb"); db.testcollection.find().pretty();'
You should not see the document as it was lost when the pod restarted.
Conclusion
In this tutorial, we successfully demonstrated the differences between persistent and non-persistent storage in Kubernetes using MongoDB. The persistent instance retained its data even after a pod restart, while the non-persistent instance lost its data. This exercise is crucial for understanding how storage management works in Kubernetes, especially when deploying stateful applications. By grasping these concepts, you can make informed decisions on how to manage data in your Kubernetes environments.
Top comments (0)