I have a kubernetes cluster and I have a simple deployment for mongodb with NFS persistent volume set. It works fine, but since resources like databases are stateful I thought of using Statefulset for the mongodb, but now the problem is, when I go through the documentation, statefulset has volumeClaimTemplates instead of volumes (in deployments).
But now the problem comes.
in a deployment do it like this:
PersistentVolume -> PersistentVolumeClaim -> Deployment
But how can we do this in Statefulset ?
Is it like:
volumeClaimTemplates -> StatefulSet
How can I set a PersistentVolume for the volumeClaimTemplates. If we don't use PersistentVolume for StatefulSet, how does it create he volume and WHERE does it create the volumes? Is in host machines (i.e. kubernetes worker nodes)?
Because I have a separate NFS provisioner I am using for the mongodb deployment (with replicasset=1), how can I use the same setup with StatefulSet ?
Here's the my mongo-deployment.yaml -> which I am going to transform into a statefulset as shown in the second code snippet (mongo-stateful.yaml)
mongo-deployment.yaml
<omitted>
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
name: mynfs # name can be anything
spec:
storageClassName: manual # same storage class as pvc
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: <nfs-server-ip>
path: "/srv/nfs/mydata"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteMany # must be the same as PersistentVolume
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
name: mongodb
spec:
selector:
matchLabels:
app: mongodb
replicas: 1
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
... # omitted some parts for easy reading
volumeMounts:
- name: data
mountPath: /data/db
volumes:
- name: data
persistentVolumeClaim:
claimName: task-pv-claim
mongo-stateful.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
name: mynfs # name can be anything
spec:
storageClassName: manual # same storage class as pvc
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
nfs:
server: <nfs-server-ip>
path: "/srv/nfs/mydata"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb-statefulset
spec:
selector:
matchLabels:
name: mongodb-statefulset
serviceName: mongodb-statefulset
replicas: 2
template:
metadata:
labels:
name: mongodb-statefulset
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongodb
image: mongo:3.6.4
ports:
- containerPort: 27017
volumeMounts:
- name: db-data
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: db-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "manual"
resources:
requests:
storage: 2Gi
But this is not working (mongo-stateful.yaml) pods are in pending state as when I describe it shows:
default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 pod has unbound immediate PersistentVolumeClaims
PS: Deployment works fine without any errors, problem is with Statefulset
Can someone please help me, how to write a statefulset with volumes?
If your storage class does not support dynamic volume provisionning, you have to manually create PVs and associated PVCs, using yaml files, then the volumeClaimTemplates will allow to link existing PVCs with your statefulset's pods.
Here is a working example: https://github.com/k8s-school/k8s-school/blob/master/examples/MONGODB-install.sh
You should:
Here is what you will get on Kind:
And a dump of a PVC (generated here by
volumeClaimTemplatebecause odf kind dynamic volume provisionning):And the related PV: