Shared Volume in Kubernetes Pod: A fun experiment [ linux fortune, nginx ]

Sabuj Jana
6 min readApr 21, 2023

We all know that each container in a Kubernetes Pod gets its own filesystem. Also Pods are ephemeral i.e, they get restarted frequently. This will make you realise that any data that was written by the pod into its own filesystem will be lost once the container restarts, and the new container (even though in the same pod) will not see the data written by the previous container.

The code for this project is available in my Github repo:

Backdrop

We have a frequent usecase where a single container running in a pod will need supplementary help from another container in the same pod, usually called a sidecar container. These two (might be many more) containers will need to share data between them right ?

How do we achieve this ? In comes Kubernetes Volumes.

Volumes !

Volumes are a component of a K8s Pod and bound to the lifecycle of the Pod itself. They aren’t a standalone k8s object and cannot be created independently. They are created along with a Pod and individual containers inside it can access it by mounting it at their desired location.

  • We will use emptyDir volume (just a jargon) because it is the simplest volume that lets us share data between containers. The storage is empty by default and containers are free to dump data, as required.

Architecture !!

The architecture we want to achieve is shown below.

High Level Diagram

Everything you see above is happening inside a single Pod.

  1. nginx webserver — this container is running a nginx webserver and the html it is serving is fetched from the shared emptyDir volume. This container has mounted the volume at /usr/share/nginx/html. FYI, this is the directory from which nginx (by default) serves html pages.
  2. ubuntu fortune container — this container is running a bash script that periodically (time is configurable) uses the linux fortune command to fetch random quotations and dumps them into the shared volume (for the nginx webserver to read).

As a result, if you are viewing the nginx root webpage, it should be serving new quotes every 5s (if time period = 5s).

3. htmldump volume — it is a Kubernetes storage volume that is being used in tandem with the two containers.

Creating the ubuntu fortune image

Nginx image is publicly available. However, we need to create the fortune image according to our particular usecase.

Creating fortune folder -> fortune-fetcher.sh script
# fortune-fetcher.sh

#!/bin/bash
trap "exiting the fortune loop" SIGINT
mkdir /var/html

while :
do
echo $(date) Writing fortune to /var/html/index.html
/usr/games/fortune > /var/html/index.html
sleep 5
done

Script Logic

This script basically runs a while loop

  • that sleeps for 5s
  • Redirects the output from the fortune command to the /var/html/index.html file. This is the file which we plan on exposing to nginx for webpage rendering.

Dockerfile

Let us build a public image for this script.

Creating Dockerfile
# Dockerfile

FROM ubuntu:latest

RUN apt-get update; apt-get -y install fortune
ADD fortune-fetcher.sh /bin/fortune-fetcher.sh
RUN chmod +x /bin/fortune-fetcher.sh

ENTRYPOINT [ "/bin/fortune-fetcher.sh" ]

Dockerfile Logic

This Dockerfile builds on top of the ubuntu image

  • We apt install the fortune binary, which by default gets installed in /usr/bin/fortune path. Ref: https://linux.die.net/man/6/fortune
  • We copy our script to the path /bin/fortune-fetcher.sh in the container.
  • We add execution permission to the script binary.
  • The entrypoint is executing the script binary itself.

~ Building the image ~

> docker build -t sabujjana/fortune
Docker image being built

Now that we have the image built, let us push it to our public DockerHub -https://hub.docker.com/u/sabujjana.

> docker push sabujjana/fortune
Pushing locally built image to DockerHub

We can view the image here: https://hub.docker.com/r/sabujjana/fortune

Creating the Pod Manifest

Now that we have the container images in place, let us go ahead and write the Pod manifest. Naming it fortune-pod.yaml under manifests directory.

> mkdir manifests
> touch manifests/fortune-pod.yaml
# fortune-pod.yaml

apiVersion: v1
kind: Pod
metadata:
name: fortune
spec:
containers:
- image: sabujjana/fortune
name: fortunegenerator
volumeMounts:
- name: htmldump
mountPath: /var/html
- image: nginx:latest
name: webserver
volumeMounts:
- name: htmldump
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: htmldump
emptyDir: {}

Pod YAML Logic

  • We have named the pod fortune
  • Container 1 — fortunegenerator — runs our image sabujjana/fortune and mounts the emptyDir volume at /var/html path
  • Container 2 — webserver — runs the public image nginx:latest ; mounts the emptyDir volume at /usr/share/nginx/html path and exposes the web server at Port 80
  • Volume htmldump is the emptyDir volume

Deploying the Pod Manifest !

Will time
  • Let us create a namespace fortune-nginx where we will run our Pod.
Creating a ns and Deploying the Pod manifest
  • Now if we list the pods in the ns, we can see
Listing the pods

Our fortune pod is up and running successfully. If you look at the READY column, it says 2/2 which means that both the containers are up and running successfully.

Exposing the Pod to access the webpage

Let us use port-forwarding to expose the nginx server to localhost.

PF the fortune pod

Now if we hit localhost:8080 , we should see the page that nginx renders.

Random Quote 1 LOL
  • After 5s, if you refresh the page, you should see a new quote.
Quote 2
Quote 3

You can continue playing with this — who knows, maybe a quote will encourage you to change your life perspective !

Checking the Pod Logs

A good practice is to look at the Pod logs to ensure that our service is running perfectly.

Pod logs

You can see that the logs are the echo messages we had used in our fortune-generator.sh script.

Wrapping up

  • For more such reads, consider following my Medium Space !
One from Kate

--

--

Sabuj Jana

Building software @Flipkart . ex-Amazon, Wells Fargo | Follow me for linux, k8s, go, elb, istio, cilium and other intriguing tech | https://janasabuj.github.io