Kubernetes Persistent Volumes: Examples & Best Practices

An outcropping of brown rocks against a blue sea

What are Persistent Volumes (PVs)?

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0005
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2

Features of Persistent Volumes

Volume Modes

Access Modes

  • ReadOnlyMany(ROX) allows being mounted by multiple nodes in read-only mode.
  • ReadWriteOnce(RWO) allows being mounted by a single node in read-write mode.
  • ReadWriteMany(RWX) allows multiple nodes to be mounted in read-write mode.

Reclaim Policy

  • Retain - meaning the PV, until deleted, is kept alive.
  • Recycle - meaning the data can be restored later after getting scrubbed.
  • Delete - associated storage assets (such as AWS EBS, GCE PD, Azure Disk, and OpenStack Cinder volumes) are deleted.

Mount Options

  • gcePersistentDisk
  • awsElasticBlockStore
  • AzureDisk
  • NFS
  • RBD (Rados Block Device)
  • CephFS
  • Cinder (OpenStack volume storage)
  • Glusterfs

What are Persistent Volume Claims (PVCs)?

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv0004
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi

Expanding Persistent Volume Claims

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: pv0003
provisioner: kubernetes.io/glusterfs
parameters:
resturl: “http://192.168.10.100:8080”
restuser: “”
secretNamespace: “”
secretName: “”
allowVolumeExpansion: true

Lifecycle of PV and PVC

  • Provisioning - the creation of the PV, either directly (static) or dynamically using StorageClass.
  • Binding - assigning the PV to the PVC.
  • Using - Pods use the volume through the PVC.
  • Reclaiming - the PV is reclaimed, either by keeping it for the next use or by deleting it directly from the cloud storage.
  • Available - this state shows that the PV is ready to be used by the PVC.
  • Bound - this state shows that the PV has been assigned to a PVC.
  • Released - the claim has been deleted, but the cluster has not yet reclaimed the resource.
  • Failed - this state shows that an error has occurred in the PV.

Provisioning

Static

Dynamic

Binding

Reclaiming

Common Use Cases

Example 1

apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim

Example 2

apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim

Example 3

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi

Example 4

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

Example 5

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

Best Practices

  1. To reduce management overhead and enable scaling, avoid statically creating and assigning persistent volumes. Instead, use dynamic provisioning. In your storage class, define the appropriate reclaim policy to minimize storage costs once Pods are deleted.
  2. A maximum number of sizes is supported by each node; therefore, different amounts of local storage and capacity are provided by different node sizes. Plan appropriately for your application demands to deploy the right size of nodes.
  3. The persistent volume (PV) lifecycle is independent of any particular container in the cluster. Persistent volume claims (PVC) are a request made by a container user or application for a specific type of storage. When creating a PV, Kubernetes documentation recommends the following:
  • Always include PVCs in the container configuration.
  • Never include PVs in container configuration, as this will tightly couple a container to a specific volume.
  • Always have a default StorageClass; otherwise, PVCs that don’t specify a specific class will fail.
  • Give StorageClasses meaningful names.

Conclusion

--

--

--

>> www.loft.sh << Build Your Internal Kubernetes Platform With Virtual Clusters, Namespace Self-Service & Secure Multi-Tenancy

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Options to Transfer Files to AWS S3

How do CDNs work? | what does CDN stand for?

Why does (25)(25) = 2(2+1)(100)+25? An explanation.

Spring Boot: Create CRUD operation using Spring Boot within minutes by exposing REST END POINTS…

https://start.spring.io/

Bug Bounty tip Automating SSRF

APPlan — — Sinatra Web App

How I got started with Kubernetes on GKE

Level Up Your Mobile Developer Interviews With CodeSignal

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Loft Labs

Loft Labs

>> www.loft.sh << Build Your Internal Kubernetes Platform With Virtual Clusters, Namespace Self-Service & Secure Multi-Tenancy

More from Medium

Using Kubernetes Ephemeral Containers for Troubleshooting

A time lapse picture of blue and red streaks of light

Kubernetes volume backup for disaster recovery

How I scored 100/100 in CKAD

Build Container Images with Jenkins and Podman — Part 2