Persistent Volumes (PV)#
Instead of simply adding a volume to a deployment, a persistent volume is a cluster-level resource that is created separately from the pod and then attached to the pod. It’s similar to a ConfigMap in that way.
PVs can be created statically or dynamically.
- Static PVs are created manually by a cluster admin
- Dynamic PVs are created automatically when a pod requests a volume that doesn’t exist yet
Generally speaking, and especially in the cloud-native world, we want to use dynamic PVs. It’s less work and more flexible.
Persistent Volume Claims (PVC)#
A persistent volume claim is a request for a persistent volume. When using dynamic provisioning, a PVC will automatically create a PV if one doesn’t exist that matches the claim.
The PVC is then attached to a pod, just like a volume would be.
Assignment#
Create a new file called api-pvc.yaml and add the following:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: xxx
spec:
accessModes:
- xxx
resources:
requests:
storage: xxxAdd the following properties:
metadata/name:synergychat-api-pvcspec/accessModes: An array with one entry:ReadWriteOnce
spec/resources/requests/storage:1Gi
This creates a new PVC called synergychat-api-pvc. ReadWriteOnce means the volume is mounted read-write by a single node at a time - multiple pods on that same node can share it, but pods on other nodes cannot. (The full access-mode story - ReadOnlyMany, ReadWriteMany - lives in storage-classes.) It also requests 1GB of storage.
Apply the PVC.
Run both of these commands:
kubectl get pvc
kubectl get pvYou should see that a new PV was created automatically!
Now delete the PVC:
kubectl delete pvc <pvc-name>Make sure both the PVC and PV are gone:
kubectl get pvc
kubectl get pvAttach Persistence#
So far all we’ve done is create an empty persistent volume. Let’s get the api application to use it.
Assignment#
Use your crawler deployment and the docs as a reference. Create a new volume in the api-deployment referencing your pvc:
volumes:
- name: synergychat-api-volume
persistentVolumeClaim:
claimName: synergychat-api-pvcThen mount it in the container under the /persist directory:
volumeMounts:
- name: synergychat-api-volume
mountPath: /persistUpdate the API_DB_FILEPATH environment variable you added earlier to instead use the new mount path: /persist/db.json
Apply the changes, then check to make sure all your pods are healthy:
kubectl get podsWith your tunnel running (minikube tunnel -c), open http://synchat.internal/ in your browser.
- Send some messages.
- Delete the
apipod. - Once the new pod is running, refresh the page and make sure your messages are still there. If they are, your persistent volume is working!
api-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: synergychat-api
labels:
app: synergychat-api
spec:
replicas: 1
selector:
matchLabels:
app: synergychat-api
template:
metadata:
labels:
app: synergychat-api
spec:
containers:
- name: synergychat-api
image: bootdotdev/synergychat-api:latest
volumeMounts:
- name: synergychat-api-volume
mountPath: /persist
env:
- name: API_PORT
valueFrom:
configMapKeyRef:
name: synergychat-api-configmap
key: API_PORT
- name: API_DB_FILEPATH
valueFrom:
configMapKeyRef:
name: synergychat-api-configmap
key: API_DB_FILEPATH
volumes:
- name: synergychat-api-volume
persistentVolumeClaim:
claimName: synergychat-api-pvc
---api-configmap.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: synergychat-api-configmap
data:
API_PORT: "8080"
API_DB_FILEPATH: /persist/db.json
---for more storage-classes