Kubernetes Volumes
Internal container storage is ephemeral, which means that it exits only for the lifetime of the container. When the container is stopped any data written inside the container is lost. Volumes provide a means of storing data beyond the life of the container.
The Pod
definition below contains an emptyDir
Volume
An emptyDir
is an empty directory that is created when a Pod
is assigned to a Node
. All containers in a Pod
can read and write in the emptyDir
Volume
which makes useful for multi container Pod
use cases.
apiVersion: v1 kind: Pod metadata: name: pod-volume-1 spec: containers: - name: volume-container-1 image: busybox command: ['sh', '-c', 'while true; do sleep 3600; done'] imagePullPolicy: IfNotPresent volumeMounts: - name: demo-volume # matches volume[x].name mountPath: /tmp/storage # location inside container where storage is mounted - name: volume-container-2 image: busybox command: ['sh', '-c', 'while true; do sleep 3600; done'] imagePullPolicy: IfNotPresent volumeMounts: - name: demo-volume mountPath: /tmp/storage volumes: - name: demo-volume emptyDir: {} # creates an empty directory on node when Pod is created
The name
attribute in volumeMounts
must match name
in the volumes
definition.
The screenshot above shows that we can exec
into volume-container-1
and create a file in the VolumeMount
. We can then exit volume-container-1
and exec
into volume-container-2
and read the same file. This proves that the file exists on the volumeMount
and is accessible to all containers in the Pod
.
State Persistence
There may be circumstances where you want to retain state beyond the life of a container or Pod
. To do this you’ll need to store data in some kind of long term persistence storage outside of the container. Kubernetes allows you to do this using PersistentVolumes
and PersistentVolumeClaims
.
PersistentVolume
orPV
is a storage resourcePersistentVolumeClaim
orPVC
is a an abstraction between the storage resource and thePod
.PersistentVolumeClaims
will automatically bind themselves to aPeristentVolume
that has a compatibleStorageClass
andAccessMode
.
Defining a PersistentVolume
A sample PersistentVolume
is defined below.
apiVersion: v1 kind: PeristeneVolume metadata: name: demo-pv spec: storageClassName: local-storage capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"
storageClassName
defines which PersistentVolumeClaim
will be able to bind to this PersistentVolume
.
capacity
defines the amount of storage made available
accessMode
specifies what read/write modes can be used to access the volume. ReadWriteOnce
means this PersistentVolume
can be read from and written to by one Pod
at a time.
hostPath
– is a PersistentVolume
type specifically for development and testing on a single node. It uses a file or directory on the Node
to emulate network attached storage.
You wouldn’t use hostPath
in production. Instead you’d hook into some kind of cloud based storage, like an Amazon EBS Volume.
Defining a PersistentVolumeClaim
The sample PersistentVolumeClaim
below references the PersistnetVolume
defined above.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: demo-pvc spec: storageClassName: local-storage accessModes: - ReadWriteOnce resources: requests: storage: 512Mi
storageClassName
is used to bind to the PersistentVolume
we created above, which has a matching storageClass
local-storage
.
accessModes
specifies what read/write modes will be used to access the volume.
resource.requests.storage
– defines how much storage the PersistentVolumeClaim
needs, in this instance 512Mi
is half the total amount available in the PersistentVolume
we defined earlier.
After creating the PersistentVolume
and PersistentVolumeClaim
we can see that the Status of both is Bound
.
Using a PersistentVolumeClaim
The Pod
definition below uses a PersistentVolumeClaim
to reference the PersistentVolume
we created above.
apiVersion: v1 kind: Pod metadata: name: demo-pvc-pod spec: containers: - name: pvc-container image: busybox imagePullPolicy: IfNotPresent command: ['/bin/sh', '-c', 'while true; do sleep 3600; done'] volumeMounts: - name: demo-pvc mountPath: 'tmp/pvc-data' volumes: - name: demo-pvc persistentVolumeClaim: claimName: demo-pvc
We define a Volume
and specify persistentVolumeClaim.claimName
to reference the PersistentVolumeClaim
created earlier. The Volume
is mounted to the container the same way any other Volume
is mounted, by specifying the Volume
name and a mount path inside the container.
To prove that the PersistentVolume
persists data beyond the life of a Pod
, we can do the following.
- Create
demo-pvc-pod
defined above - Exec into the
Pods
container and create a file call hello.txt in/tmp/pvc-data
- Exit the container and delete the
Pod
- Create a new
demo-pvc-pod
and exec into its container. - The hello.txt file you created for the first
Pod
should still be visible.
The sample code for these notes is available on Github.
Leave A Comment