Tuesday, November 2, 2021

Kubernetes for Developers #23: Kubernetes Volume emptyDir in-detail

Containers are ephemeral. It means, any container generated data gets stored into its own filesystem and will be deleted automatically if the container is deleted or restarted.

In Docker world, docker volumes provide a way to store container data into the host machine as permanent storage. However, it is less managed and limited for multi-node cluster.

Kubernetes volumes provide a way for containers to access external disk storage or share storage among containers.

Kubernetes volumes are not top-level object as like Pod, Deployment etc., however these are component of a pod and defined as part of pod YAML specification. K8 Volumes are available to all containers in the pod and must be mounted in each container specific file location.

Kubernetes supports many types of volumes like, 

  • emptyDir: Used for mounting temporary empty directory from worker node Disk/RAM
  • awsElasticBlockStore: Used for mounting AWS EBS volume into the pod
  • azureDisk: Used for mounting Microsoft Azure data disk into the pod
  • azureFile: Used for mounting Microsoft Azure File volume into the pod
  • gcePersistentDisk: Used for mounting Google PD into the pod
  • hostPath: Used for mounting Worker node filesystem into the pod
  • nfs: Used for mounting existing NFS (Network file system) into the pod
  • configMap/secret: Used for mounting these values into the pod
  • persistentVolumeClaim: Used for mounting dynamically provisioned storage into the pod

A Pod can use any number of volume types simultaneously to persist container data.

emptyDir volume


An empty directory created when a Pod is assigned to a node and remains active until pod is running. All containers in the pod can read/write the contents to the emptyDir volume. An emptyDir volume will be erased automatically once the pod is terminated from the node.

A container crashing does not remove a Pod from a node. The data in an emptyDir volume is safe across container crashes. It only erased when Pod is deleted from the node.

  • It is useful for sharing files between containers which are running in the same pod
  • It is useful for doing disk-based merge sort on large dataset where memory is low
  • It is useful when container filesystem is read-only and wants to write data temporarily.

apiVersion: v1
kind: Pod
metadata:
  name: volume-emptydir
spec:
  containers:
    - name: alpine
      image: alpine
      command:
        [
          "sh",
          "-c",
          'mkdir var/mydoc; while true; do echo "random message text `date`" >> var/mydoc/index.html;sleep 10;done',
        ]
      volumeMounts:
        - name: vol-emptydir
          mountPath: /var/mydoc
    - name: nginx
      image: nginx:alpine
      ports:
        - containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: vol-emptydir
          mountPath: /usr/share/nginx/html
  volumes:
    - name: vol-emptydir
      emptyDir: {}

As per above yaml ,
  1. A multi-container pod gets created with volume type “emptyDir” named as “vol-emptydir”
  2. “vol-emptydir” volume gets created automatically when a pod is assigned to a worker-node.
  3. As name says, volume contains empty files/directories at initial stage.
  4. First “alpine” container creates random text message for every 10 seconds and appends to /var/mydoc/index.html file.
  5. First “alpine” container mounted a volume at ‘/var/mydoc’. So, all the files under this directory copied into volume (i.e., index.html file).
  6. Second “nginx” container mounted a same volume at ‘/usr/share/nginx/html’ (this is the default directory for nginx to serve index.html file ). As we mounted same volume which has “index.html”, nginx web server serves the file (i.e., index.html) which is created by the first container.
  7. As first container adds new random message to index.html file for every 10 seconds, we see different message each time when we request index.html from nginx webserver.
  8. Volume and its contents get deleted automatically when the Pod is deleted
  9. By default, Volume contents get stored on the worker node disk. However, “emptyDir” volume contents can be stored into the memory (RAM) by setting “medium” attribute

save above yaml content as "pod-vol-emptydir.yaml" and run the following kubectl command

// create pod
$ kubectl apply -f pod-vol-emptydir.yaml
pod/pod-vol-emptydir created

// display pods
$ kubectl get po
NAME                    READY   STATUS      RESTARTS   AGE
pod-vol-emptydir        2/2     Running     0          2m39s

run the following kubectl command to forward a port from local machine to the pod
// syntax
// kubectl port-forward <pod-name> <local-port>:<container-port>
$ kubectl port-forward pod-vol-emptydir 8081:80
Forwarding from 127.0.0.1:8081 -> 80
Forwarding from [::1]:8081 -> 80

run the following curl command to check random messages which are appending after every 10 seconds
$ curl http://localhost:8081
random message text Tue Nov  2 15:48:50 UTC 2021

$ curl http://localhost:8081
random message text Tue Nov  2 15:48:50 UTC 2021
random message text Tue Nov  2 15:49:00 UTC 2021
random message text Tue Nov  2 15:49:10 UTC 2021

An emptyDir volume does not persist data after pod termination. So, delete the Pod and recreate all above steps to check any existing data is printing while doing curl command
// delete pod
$ kubectl delete pod/pod-vol-emptydir
pod/pod-vol-emptydir deleted

// create pod
$ kubectl apply -f pod-vol-emptydir.yaml
pod/pod-vol-emptydir created

// display pods
$ kubectl get po
NAME                    READY   STATUS      RESTARTS   AGE
pod-vol-emptydir        2/2     Running     0          1m10s

// syntax
// kubectl port-forward <pod-name> <local-port>:<container-port>
$ kubectl port-forward pod-vol-emptydir 8081:80
Forwarding from 127.0.0.1:8081 -> 80
Forwarding from [::1]:8081 -> 80

$ curl http://localhost:8081
random message text Tue Nov  2 16:01:50 UTC 2021
It is confirmed that only new data is printing after pod recreation when using emptyDir volume.

By default, Volume contents get stored on the worker node disk. However, “emptyDir” volume contents can be stored into the memory (RAM) by setting “medium” attribute

volumes:
 - name: vol-emptydir
   emptyDir:
   medium: Memory

Kubernetes for Developers Journey.
Happy Coding :)

No comments:

Post a Comment