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: /srvkubectl describe pv $pv_nameLifecycle & 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 claim
- Bound…volume is bound to a claim
- Released…claim deleted …associated storage resource not reclaimed (yet)
- Failed…volume has failed its (automated) reclamation
Parameters
- capacity.storage— Valid suffix- Mi,- Gi,- Ti
- volumeModes— How storage will be accessed- Filesystem(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
 
 
persistentVolumeReclaimPolicy3 — What to do with a volume after released
- Retain— Manual reclamation of the resource…- …remains in the Releasedstate
- …can be reclaimed using the same storage definition
 
- …remains in the 
- Delete— Resource will be deleted automatically
- Recycle— 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 - storageClassNamerequests a particular storage class
- accessModessupports the following access modes- ReadWriteOnce— read-write by a single pod
- ReadOnlyMany— read-only by multiple pods
- ReadWriteMany— read-write by multiple pods
 
- resources.requests.storage…suffix- Mi,- 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 $nameStorage Classes
# list all storage classes
kubectl get sc
kubectl get storageclass
kubectl describe storageclass $name
# list installed CSI drivers
kubectl get csidriverStorage 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: RetainExamples
Commonly used volume types…
- emptyDir— Simple empty directory …for transient data
- hostPath— Directory from the work node
- nfs— Mount of an NFS share
- configMap— Non-confidential configuration …key-value pairs
- secret— Passwords, Oath tokens, SSH keys, etc.
- downwardAPI— Access pod metadata & cluster context
- persistantVolumeClaim— 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/hostnameUse an tmpfs file-system in memory instead of local storage:
volumes:
  - name: html
    emptyDir:
      medium: MemoryHost Path
kind: PersistentVolume
metadata:
  name: project-storage
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 10Gi
  hostPath:
    path: /data/project/        # absolute path on the host nodeMount 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: trueFootnotes
- 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↩︎
