8th Week :- Build Rock-Solid Storage in Kubernetes: Static & Dynamic PVCs with NFS + MongoDB

Table of contents
- π¦ What are Volumes in Kubernetes?
- π‘ Why Use Volumes?
- π Types of Volumes in Kubernetes
- π§± Provisioning Methods: Static vs. Dynamic
- π¨ Static Provisioning with NFS
- π§° Static Provisioning Using NFS on a Cloud VM
- π Dynamic Provisioning using StorageClass (Automatic PV)
- β How to Check Volume is Working or Not
- π§ Pro Tips
- π Conclusion
π¦ What are Volumes in Kubernetes?
In Kubernetes, volumes are used to persist and share data across containers and pod restarts. By default, data inside a pod disappears when the container restarts or the pod is deleted. Volumes solve this issue by providing persistent storage outside the lifecycle of containers.
π‘ Why Use Volumes?
β Retain data after pod restarts.
β Share data between multiple containers in a pod.
β Use external storage (NFS, cloud storage, etc.)
β Store databases, logs, uploads, etc.
β Separate compute (pods) from storage.
π Types of Volumes in Kubernetes
1. Ephemeral Volumes
Lives and dies with the pod.
Example:
emptyDir
,configMap
,secret
,downwardAPI
Use case: Temporary cache, scratch space
volumes:
- name: temp-storage
emptyDir: {}
2. Persistent Volumes (PV)
An actual storage resource (disk, NFS, cloud block storage).
Lives beyond pod lifecycle.
3. PersistentVolumeClaim (PVC)
A userβs request for a PV.
Binds to an available PV that satisfies the claim.
π§± Provisioning Methods: Static vs. Dynamic
Type | Who creates the PV? | Use Case |
Static Provisioning | Admin manually creates PVs | On-prem or controlled environments |
Dynamic Provisioning | K8s auto-creates PVs via StorageClass | Cloud-native apps, automation |
π¨ Static Provisioning with NFS
Prerequisites:
NFS server running
Shared NFS directory (e.g.,
/srv/nfs/kubedata
)Exported in
/etc/exports
β€ NFS Server (Example)
sudo apt install nfs-kernel-server
sudo mkdir -p /srv/nfs/kubedata
sudo chmod -R 777 /srv/nfs/kubedata
echo "/srv/nfs/kubedata *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -rav
π§Ύ Step 1: Create Static PersistentVolume
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /srv/nfs/kubedata
server: <NFS-SERVER-IP>
π§Ύ Step 2: Create PVC to Use This PV
# nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
π§Ύ Step 3: Create Pod Using This PVC
# pod-using-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-app
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nfs-storage
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: nfs-pvc
π§° Static Provisioning Using NFS on a Cloud VM
Weβll now create a static NFS volume by setting up a remote NFS server on a cloud VM, such as AWS EC2, Google Compute Engine, or Azure VM.
βοΈ Step 1: Launch a VM (e.g., AWS EC2)
OS: Ubuntu 20.04
Open ports:
22
(SSH)2049
(NFS) β allow access from your Kubernetes nodes
π Step 2: SSH into the VM
ssh -i <your-key.pem> ubuntu@<EC2_PUBLIC_IP>
π Step 3: Install & Configure NFS Server
sudo apt update
sudo apt install nfs-kernel-server -y
sudo mkdir -p /srv/nfs/kubedata
sudo chmod -R 777 /srv/nfs/kubedata
Then edit /etc/exports
:
sudo nano /etc/exports
Add:
/srv/nfs/kubedata *(rw,sync,no_subtree_check,no_root_squash)
Apply changes:
sudo exportfs -rav
sudo systemctl restart nfs-kernel-server
π Note the private IP of this VM (use
hostname -I
). We'll use it next.
π§Ύ Step 4: Create PersistentVolume (PV)
# cloud-nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: cloud-nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /srv/nfs/kubedata
server: <VM-PRIVATE-IP> # replace with actual IP
π§Ύ Step 5: Create PVC and Pod
# cloud-nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloud-nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
# cloud-nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-app
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: cloud-nfs-storage
volumes:
- name: cloud-nfs-storage
persistentVolumeClaim:
claimName: cloud-nfs-pvc
π Dynamic Provisioning using StorageClass (Automatic PV)
π§Ύ Step 1: Define StorageClass
# storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs # use nfs or other provisioners based on environment
parameters:
type: gp2
reclaimPolicy: Retain
volumeBindingMode: Immediate
Note: For local testing with NFS, use nfs-subdir-external-provisioner
π§Ύ Step 2: Create PVC with StorageClass
# mongodb-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: fast-storage
π§Ύ Step 3: Create MongoDB Deployment
# mongodb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
persistentVolumeClaim:
claimName: mongodb-pvc
β How to Check Volume is Working or Not
π 1. Check PVC Binding
kubectl get pvc
kubectl describe pvc <pvc-name>
π 2. Check PV Status
kubectl get pv
kubectl describe pv <pv-name>
π 3. Verify Pod Logs / Shell
kubectl exec -it <pod-name> -- /bin/bash
# Inside pod
cd /data/db # or your mounted volume path
touch test.txt # Check if it persists
π 4. Delete and Recreate Pod
kubectl delete pod <pod-name>
kubectl apply -f pod.yaml
# Check if /data/db/test.txt is still there
π§ Pro Tips
Use
ReadWriteMany
for shared storage (e.g., NFS).Set
persistentVolumeReclaimPolicy: Retain
to keep data even after PVC deletion.Label your PVs to allow PVCs to match specific volumes.
For cloud providers, choose the right provisioner (
aws-ebs
,gce-pd
,csi-driver
, etc.)Monitor
Events:
section inkubectl describe
to troubleshoot storage binding.
π Conclusion
Kubernetes volumes are essential to run real-world applications with stateful data. Whether you're working with NFS static PVs or dynamic StorageClasses, understanding the role of PVCs and PVs is crucial. With these examples and verification tricks, youβre ready to deploy databases and other apps with robust storage backing.
Subscribe to my newsletter
Read articles from Lav kushwaha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
