Kubernetes - Volumes

Disk files for a container is ephemeral. To persist data over container restart, we need to use PersistentVolume

Kubernetes supports many Volume Types

  • emptyDir
  • azureDisk
  • awsElasticBlockStore
  • gcePersistentDisk

emptyDir

An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. It can be used for Pods to share files.

By default, emptyDir volumes are stored on whatever medium is backing the node - that might be disk or SSD or network storage, depending on your environment.

All containers in a pod can share an emptyDir. emptyDir volume can mount to the same or different path.

emptyDir volume is removed when a Pod is removed.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}

PersistentVolume

For persistent volume use PersistentVolume(PV) and PersistentVolumeClaim(PVC).

  • PersistentVolume is usually managed by administrators
  • PersistentVolume can be requested by PersistentVolumeClaim

There are three steps to use PersistentVolume.

  1. Administrator create PersistentVolume
  2. Developer create PersistentVolumeClaim that claims part of that PersistentVolume disk space
  3. Developer create pod that that uses PersistentVolumeClaim

Step1: Create PersistentVolume

mongo-pv.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolume
metadata:
labels:
type: local
name: mongo-pv
spec:
storageClassName: mongo-demo
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
hostPath:
path: /data/mongo_data

use kubectl get pv to display PersistentVolume resources. storageClassName is very important. It is used to tie PersistentVolume and PersistentVolumeClaim. The status is Available at this time. If a PersistentVolumeClaim is bound, the status will be Bound.

3 Access Modes

  • ReadWriteOnce: The Volume can be mounted as read-write by a single node.
  • ReadOnlyMany: The Volume can be mounted read-only by many nodes.
  • ReadWriteMany: The Volume can be mounted as read-write by many nodes. PersistentVolumes that are backed by Compute Engine persistent disks don’t support this access mode.

use kubectl get pv command to display the PersistentVolumes.

1
2
3
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mongo-pv 1Gi RWO Retain Available mongo-demo 6s

Step2: Create PersistentVolumeClaim

mongo-pvc.yml

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
spec:
storageClassName: mongo-demo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 250Mi

use kubectl get pvc to display PersistentVolumeClaim

1
2
3
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mongo-pv-claim Bound mongo-pv 1Gi RWO mongo-demo 8s

Step3: Create Pod that uses the PersistentVolumeClaim

mongo.yml: defines a service and statefulset that uses PersistentVolume.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
apiVersion: v1
kind: Service
metadata:
name: mongo
labels:
app: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: mongo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
spec:
selector:
matchLabels:
app: mongo
serviceName: "mongo"
replicas: 1
template:
metadata:
labels:
app: mongo
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongo
image: mongo
command:
- mongod
- "--bind_ip"
- 0.0.0.0
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-volume
mountPath: /data/db
volumes:
- name: mongo-volume
persistentVolumeClaim:
claimName: mongo-pvc

After the statefulset is created, use kubectl get statefulsets to check the statefulset status

1
2
3
$ kubectl get statefulsets
NAME READY AGE
mongo 1/1 11m

Use kubectl exec -it mongo-0 /bin/bash to get into the container and use the mongodb database. The data will persiste over pod restart.

References