Volumes

Module

Kubernetes volumes are an abstraction of external storage that can be attached and shared by multiple Pods.

Overview

At the end of this module, you will :

  • Learn to persist data thanks to external volumes

  • Learn to manage the volumes and the claim

  • Learn to access data within a container

Prerequisites

Create the directory data/volumes in your home folder to manage the YAML file needed in this module.

mkdir ~/data/volumes

Create

On-disk files in a container are ephemeral, which presents some problems for non-trivial applications when running in containers :

  • When a container crashes, they will automatically restart but the files will be lost. The container starts with a clean state.

  • When running containers together in a Pod it is often necessary to share files between those containers.

The Kubernetes Volume abstraction solves both of these problems.

The Kubernetes basic architecture can be schematized like this :

The create command can create a PersistentVolume / PersistentVolumeClaim object based on a yaml file definition.

EmptyDir

An EmptyDir Volume, as the name says, attach an empty volume to all the containers in a single Pods.

Containers in the Pod can all read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each Container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever.

An EmptyDir Volume does not require the definition of an external resource like PersistentVolume or PersistentVolumeClaim. The definition is done directly in the yaml file of the Pod.

Exercise n°1

Create an Nginx Pod and attach an EmptyDir volume to it.

~/data/volumes/01_pods.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myfirstemptydir
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: nginx-storage
      mountPath: /data/test
  volumes:
  - name: nginx-storage
    emptyDir: {}

Create the resource based on the previous yaml definition file.

kubectl create -f ~/data/volumes/01_pods.yaml

PersistentVolume

A PersistentVolume is a piece of storage in a Kubernetes cluster. It is a resource in the cluster just like a node is a cluster resource. PersistentVolumes have a lifecycle independent of any individual pod that uses volumes.

HostPath

Kubernetes supports hostPath for development and testing on a single-node cluster. A hostPath PersistentVolume uses a file or directory on the Node to emulate network-attached storage.

HostPath volumes should not be used in a production cluster. Instead a cluster administrator would provision a network resource like a Google Compute Engine persistent disk, an NFS share, or an Amazon Elastic Block Store volume. Cluster administrators can also use StorageClasses to set up dynamic provisioning.

Exercise n°1

Create an hostPath volume based on that directory :/data/nginx/conf

~/data/volumes/02_hostpath.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
  name: myfirsthostpathvolume
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/nginx/conf"

Create the resource based on the previous yaml definition file.

kubectl create -f ~/data/volumes/02_hostpath.yaml

Claim

A PersistentVolumeClaim is a request for storage by a user. It is similar to a pod. Pods consume node resources and PersistentVolumeClaim consume PersistentVolume resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g., can be mounted once read/write or many times read-only).

Exercise n°1

Create the PersistentVolumeClaim to claim the previous PersistentVolume provisioned.

~/data/volumes/03_persistentvolumeclaim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myfirsthostpathvolumeclaim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Create the resource based on the previous yaml definition file.

kubectl create -f ~/data/volumes/03_persistentvolumeclaim.yaml

Attach

Undependently on the PersistentVolume type used, attach a Volume to a Pod can be done in the yaml file definition of a Pod.

Exercise n°1

Attach the previous PersistentVolumeClaim to an Nginx Pod to consume the hostPath PersistentVolume provisioned before.

~/data/volumes/04_pods.yaml
kind: Pod
apiVersion: v1
metadata:
  name: myfirsthostpathpod
spec:
  volumes:
    - name: myfirsthostpathvolume
      persistentVolumeClaim:
       claimName: myfirsthostpathvolumeclaim
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: myfirsthostpathvolume

Create the resource based on the previous yaml definition file.

kubectl create -f ~/data/volumes/04_pods.yaml

Get

The get command list the object asked. It could be a single object or a list of multiple objects comma separated. This command is useful to get the status of each object. The output can be formatted to only display some information based on some json search or external tools like tr, sort, uniq.

PersistentVolume

The default output display some useful information about each services :

  • Name : the name of the newly created resource

  • Capacity : the storage capacity available in the volume

  • Access modes : the access modes available (read, write, owner)

  • Reclaim policy : the management of the resource when pod is deleted

  • Status : the status of the resource

  • Claim : the claim object associated

  • Storageclass : the storage class used to create the new resource

  • Reason : the reason of the resource creation

  • Age : the age since the creation resource

Exercise n°1

List all existing Volumes in the default namespace.

kubectl get persistentvolume

PersistentVolumeClaim

The default output display some useful information about each services :

  • Name : the name of the newly created resource

  • Status : is the resource bounded, mounted, etc

  • Volume : the PersitentVolume impacted by the newly created resource

  • Capacity : volume storage size claimed

  • Access mode : access mode of the newly created resource

  • Storageclass : the name of the StorageClass associated

  • Age : the age since the creation resource

Exercise n°1

List all existing Volume claims in the default namespace.

kubectl get persistentvolumeclaim

Describe

Once an object is running, it is inevitably a need to debug problems or check the configuration deployed.

The describe command display a lot of configuration information about the Volumes (labels, annotations, etc.) and the claim policy of each resources (storageclass, type, size, access, etc).

This command is really useful to introspect and debug an object deployed in a cluster.

Exercise n°1

Describe one of the existing PersistentVolume in the default namespace.

kubectl describe persistentvolume myfirsthostpathvolume

Exercise n°2

Describe one of the existing PersistentVolumeClaim in the default namespace.

kubectl describe persistentvolumeclaim myfirsthostpathvolumeclaim

Explain

Kubernetes come with a lot of documentation about his objects and the available options in each one. Those information can be fin easily in command line or in the official Kubernetes documentation.

The explain command allows to directly ask the API resource via the command line tools to display information about each Kubernetes objects and their architecture.

Exercise n°1

Get the documentation of a specific field of a resource.

kubectl explain persistentvolumes.spec

Add the --recursive flag to display all of the fields at once without descriptions.

Delete

The delete command delete resources by filenames, stdin, resources and names, or by resources and label selector.

A Volume can only be deleted if it is not attached to a Pod. Use with caution, a deleted volumes cannot be recover.

Note that the delete command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a delete, their update will be lost along with the rest of the resource.

Exercise n°1

Delete the previous volumes deployed in the default namespace.

# Delete the Pods previously created
kubectl delete pods myfirsthostpathpod myfirstemptydir

# Delete the PVC previously created
kubectl delete persistentvolumeclaim myfirsthostpathvolumeclaim

# Delete the volume previously created
kubectl delete persistentvolume myfirsthostpathvolume 

Module exercise

The purpose of this section is to manage each steps of the lifecycle of an application to better understand each concepts of the Kubernetes course.

The main objective in this module is to understand how to share a static storage object to persist and share data of Pods.

For more information about the application used all along the course, please refer to the Exercise App > Voting App link in the left panel.

Based on the principles explain in this module, try by your own to handle this steps. The development of a yaml file is recommended.

The file developed has to be stored in this directory : ~/data/votingapp/07_volumes

  1. On the node labelized type=database, create this directory : ~/data/votingapp/07_volumes/database/data

  2. Create a PersistentVolume based on that local directory previously created. The storage capacity of this volume has to be 10Gi.

  3. Create the PersistentVolumeClaim to consume the PersistentVolume previously created. Manage this object to claim only 5Gi of the PersistentVolume.

  4. Attach the volume to the database Pods

External documentation

Those documentations can help you to go further in this topic :

Last updated