Volumes in Kubernetes

When a container crashes, kubelet will attempt to restart it, but any files that existed in the container before will be lost. In addition, sharing files between multiple containers within a Pod is often necessary. Kubernetes provides a Volume abstraction to address these problems.

Volume Lifecycle

A Volume’s lifecycle is tied to the Pod it belongs to. When a Pod stops, its Volumes stop as well.
Volumes outlive any individual container in the Pod. If a container exits unexpectedly, it may be automatically restarted without losing the data stored in the Volume.

How to Use Volumes

Use the .spec.volumes field to specify a set of Volumes for a Pod.
Use .spec.containers[*].volumeMounts to mount a set of Volumes into a specific container.

Example: Create an Nginx Deployment and expose it as a Service. When accessed in a browser, the service should display “Hello World!”

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
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx-app
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx-app
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: web-dir
initContainers:
- name: busybox
image: busybox
command:
- "sh"
- "-c"
- "echo 'Hello World!'> /web/index.html"
volumeMounts:
- mountPath: /web
name: web-dir
volumes:
- name: web-dir
emptyDir: {}

Run the following commands:

1
2
kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/volumes/example-01.yaml
kubectl proxy --port 8081

Open http://localhost:8081/api/v1/namespaces/default/services/nginx-service/proxy/ in your browser and you should see Hello World!

Types of Volumes

Kubernetes supports many types of Volumes. For the full list, see https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes.

I broadly classify them into the following four categories:

  1. Cloud provider storage resources: awsElasticBlockStore, azureDisk, azureFile, gcePersistentDisk, vsphereVolume (vSphere), and cinder (OpenStack).
  2. Kubernetes objects and in-cluster storage resources: configMap, secret, downwardAPI, emptyDir, projected, local, hostPath, and persistentVolumeClaim.
  3. Other external storage resources: cephfs, fc (fibre channel), flocker, gitRepo (deprecated), glusterfs, iscsi, nfs, portworxVolume, quobyte, rbd, scaleIO, and storageos.
  4. Plugins: Container Storage Interface (CSI) and FlexVolume

emptyDir

This Volume type provides a temporary scratch space, primarily used for short-lived data storage. When a Pod is deleted (evicted by kubelet, manually deleted, etc.), all data stored in an emptyDir Volume is permanently erased.
The example above uses this Volume type. It can also be used to share data between different containers within the same Pod.

configMap, secret, and downwardAPI

ConfigMap and Secret are Kubernetes objects.
ConfigMap is used to store configuration data, while Secret is used to store sensitive information (such as passwords). Both can be mounted onto a Pod as Volumes.
A downwardAPI Volume allows applications to consume data from the Downward API.

If an application requires a large number of configuration values and secrets, mounting each one individually onto the Pod can become unwieldy. projected Volumes solve this by mapping multiple volumes into a single directory.