Kubernetes — Storage Resources
Overview
Kubernetes abstractions for storage — Storage resource types
- Persistent Volumes (PVs)
- …represents a volume of storage in a storage system
- …information required by applications to consume a volume
- …different back-ends define what a “volume” represents
- Persistent Volume Claims (PVC)
- …request of an application for a volume
- …the PVC is bound to a suitable PV on a storage back-end
- …represents the connection from storage to the application
- Storage Classes (SC)
- …dynamically request some volume of storage
- …request a volume claim against a storage class
- …a corresponding PV is created on the storage back-end
Dynamic provisioning (otherwise an administrator needs to create PVs manually):
Architecture
Volumes1 — Share data with containers in a pod
- …many types of volumes …pods can use multiple types simultaneously
- …mount at the specified paths within the container
- Use-cases…
- …configuration files with
ConfigMap
&Secret
- …temporary scratch space
- …read-only access to data in a different container image
- …sharing a file-system between two container within a pod
- …sharing a file-system between two different pods
- …persistent storage (not bound to the pod life-cycle)
- …configuration files with
- Ephemeral volumes …have the lifetime of a pod
- Persistent volumes …exist beyond the lifetime of a pod
Persistent Volumes
Persistent Volumes2 (PV) …abstract representation of physical or networked storage
- Why use persistent volumes?
- Data persistence …vital to stateful applications and databases
- Abstraction from the back-end storage…
- …allows to manage storage resources independently
- …enables admins control utilization and optimization of storage hardware
- Access control …ensure data integrity and security
- There are two ways PVs may be provisioned: statically or dynamically
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-storage
spec:
capacity:
storage: 500Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
hostPath:
path: /srv
kubectl describe pv $pv_name
Lifecycle & Phases
Lifecycle …several stages
- …create …static or dynamic PV declaration
- …bind …occurs when a PVC requests storage
- …match …Kubernetes links PVC with suitable PV
- …access …pod granted access to the bound PV
- …using …pod(s) read and write data
- …reclaim …when PVC deleted (determined by policy)
PersistentVolume will be in one of the following phases
Available
…free resource that is not yet bound to a claimBound
…volume is bound to a claimReleased
…claim deleted …associated storage resource not reclaimed (yet)Failed
…volume has failed its (automated) reclamation
Parameters
capacity.storage
— Valid suffixMi
,Gi
,Ti
volumeModes
— How storage will be accessedFilesystem
(default) — Mounted to a directory- …if empty block device as back-end
- …file-system created automatically
Block
— Use a volume as a raw block device- …must match on both PV and PVC
- …present storage without a formatted file-system
- …useful for applications like databases
- …some storage back-ends may provide constant I/O performance & lower latency
persistentVolumeReclaimPolicy
3 — What to do with a volume after released
Retain
— Manual reclamation of the resource…- …remains in the
Released
state - …can be reclaimed using the same storage definition
- …remains in the
Delete
— Resource will be deleted automaticallyRecycle
— Volume scrubbed …storage available to new claims
Persistent Volume Claims
Used to specific requirements to the storage resource…
- …independent of the internals of the storage provider
- Ensures a volume ‘claim’ to be portable across numerous back-ends
- Isolates storage-related concerns from the workload
apiVersion: v1
kind: PersistentVolumeClaim
#…
spec:
storageClassName: local-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Mi
storageClassName
requests a particular storage classaccessModes
supports the following access modesReadWriteOnce
— read-write by a single podReadOnlyMany
— read-only by multiple podsReadWriteMany
— read-write by multiple pods
resources.requests.storage
…suffixMi
,Gi
,Ti
PVC stuck in terminating state:
# get the volume name (prefixed with pvc-*)
kubectl get pvc $name
# check if the volume is still attached to a node
kubectl get volumeattachment | grep pvc-$volume_id
# force the remove of the mount
kubectl patch pvc -p '{"metadata":{"finalizers":null}}' $name
# remove a PVC if stuck ...requires manual cleanup on the storage provider
kubectl delete pvc --grace-period=0 --force $name
Storage Classes
# list all storage classes
kubectl get sc
kubectl get storageclass
kubectl describe storageclass $name
# list installed CSI drivers
kubectl get csidriver
Storage Class4 — Define the “classes” of storage
- …includes storage provisioners & reclaim policies
- Facilitates dynamic provisioning of storage…
- …for on-demand deployment of stateful applications
- …by automating creation of persistent volumes
- Storage abstraction for underlying storage providers
- …automate storage management & hide storage provider details
- …enables portable and provider-agnostic storage claims
- …reduces manual intervention in storage allocation
- Implement storage policies…
- …automate storage reclaim policies (when storage is released)
- …define multiple storage tiers (SSD, HDD, etc)
CSI (Container Storage Interface) — Standard for Storage provider integration
- …enable storage vendors to create custom storage plugins
- …translating storage requests into platform-specific storage resources
Parameters that define specific settings for the storage provisioner:
# Storage provider to create the volume on…
# …name of the CSI driver
# …for example kubernetes.io/nfs
provisioner: csi-driver.example-vendor.example
# Lifecycle of a persistent volume (PV)
# …after its associated persistent volume claim (PVC) is deleted
reclaimPolicy: Retain
Examples
Commonly used volume types…
emptyDir
— Simple empty directory …for transient datahostPath
— Directory from the work nodenfs
— Mount of an NFS shareconfigMap
— Non-confidential configuration …key-value pairssecret
— Passwords, Oath tokens, SSH keys, etc.downwardAPI
— Access pod metadata & cluster contextpersistantVolumeClaim
— Use pre- & dynamic provisioned persistent storage
Mount other network storage for example cephfs
, rbd
, etc.
EmptyDir
An emptyDir
volume is created when a pod is assigned to a node…
- …on storage local to the worker node
- …deleted when the pod is removed …safe across container crashes
- Why use an
emptydir
?- User for temporary scratch space
- Share files between container running in the same pod
apiVersion: v1
kind: Pod
metadata:
name: test-emptydir
spec:
volumes:
- name: opt
emptyDir: {}
containers:
- name: container-one
volumeMounts:
- name: opt
mountPath: /opt
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 10000"]
- name: container-two
volumeMounts:
- name: opt
mountPath: /opt
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 10000"]
# write a file into the mounted volume from the first container
kubectl exec test-emptydir -c container-one -- cp /etc/hostname /opt
# read the file from the second container
kubectl exec test-emptydir -c container-two -- cat /opt/hostname
Use an tmpfs file-system in memory instead of local storage:
volumes:
- name: html
emptyDir:
medium: Memory
Host Path
kind: PersistentVolume
metadata:
name: project-storage
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
hostPath:
path: /data/project/ # absolute path on the host node
Mount the host node’s file-system into a pod
- Capacity is determined by the available space on the host node
- No Quotas or limits imposed …responsibility outside Kubernetes
- Data persistent as long as host node is operational
- Typical use-cases:
- Testing & development
- Access logs & configuration files on the host
- Share data between pods on the same host
ConfigMap
# create a ConfigMap directly from literal values
kubectl create configmap project-config \
--from-literal=key1=value1 --from-literal=key2=value2
# create a ConfigMap from a file
kubectl create configmap project-config \
--from-file=project-config.properties
kubectl create configmap project-config \
--from-file=/path/to/project-config/
Manage configuration settings for applications
- For non-confidential configuration only (cf. Kubernetes secrets)
- Values can be strings, numbers, JSON, YAML
- Version control configuration separate form application code & container images
Example of a configuration file nginx.conf
used by a pod:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |
user nginx;
worker_processes 1;
events {
worker_connections 10240;
}
http {
server {
listen 80;
server_name localhost;
location / {
root /srv/htdocs;
index index.html index.htm;
}
}
}
---
apiVersion: v1
kind: Pod
metadata:
name: website
spec:
containers:
- name: web-server
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /srv
readOnly: true
- name: nginx-conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
Footnotes
Kubernetes Volumes
https://kubernetes.io/docs/concepts/storage/volumes/↩︎Persistent Volumes, Kubernetes Documentation
https://kubernetes.io/docs/concepts/storage/persistent-volumes/↩︎Reclaiming, Kubernetes Documentation
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#reclaiming↩︎Storage Classes, Kubernetes Documentation
https://kubernetes.io/docs/concepts/storage/storage-classes↩︎