How to K8s: Sharing Data Between Containers in a Pod

By Jeff Vincent|

June 26, 2020

Kubernetes is a complex system that allows you to manage a variety of ephemeral resources that are aimed at managing the Docker containers running therein. These containers will likely be distributed across several physical machines, and if so, Kubernetes intelligently distributes the workload across these machines. Moreover, should a given container fail, Kubernetes will likely spin up a new container in its place.

This is clearly super powerful, but one of the problems that such a system presents is the storage of data that must be consistently accessed from different containers throughout a given, running pod. This can create a problem, because there is always the possibility that a given container could crash, and thus (if you’re using a ReplicaSet or a Deployment) need to be spun up again, which would result in the loss of any data that had been stored in said container while it was running.

The solution to this problem lies in the mounting of a volume  – a Kubernetes abstraction that allows for the storage of data that can be accessed from any container running in the pod  – whether it’s just been spun up or not. There are a slew of different types of volumes, and each type offers varying degrees of data permanence so that the Kubernetes system can be precisely tailored to a given workflow.

Today we’ll take a look at emptyDir, a volume that is mounted when a container is first assigned to a pod. However, unlike the newly spun up container, which won’t reflect any changes that may have been made programmatically in its predecessor, the emptyDir will retain all data that had been written to it. Additionally, the emptyDir will be mounted to the newly spun up container upon its creation. This means that all containers, new or old, will have access to any data written to the volume for the full life-cycle of the pod.

In order to add a volume to a Kubernetes environment, you simply need to define it in your YAML file, like so:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: chef-boy-r-dk
spec:
 replicas: 1
 selector:
   matchLabels:
     app: chef-boy-r-dk
 template:
   metadata:
     labels:
       app: chef-boy-r-dk
   spec:
     containers:
     - name: chef-boy-r-dk
       image: chef/chefdk
       ports:
       - containerPort: 8080
       volumeMounts:
       - name: tmp
         mountPath: /tmp
       command: ["/bin/sh"]
       args: ["-c", "echo Hello from the Chef container > /tmp/hello.txt; sleep 1000"]
     - name: ubuntu
       image: ubuntu:18.04
       ports:
       - containerPort: 8080
       volumeMounts:
       - name: tmp
         mountPath: /tmp
       command: ["/bin/sh"]
       args: ["-c", "echo Hello from the Ubuntu container >> /tmp/hello.txt; sleep 1000"]
     securityContext:
       runAsUser: 1
     volumes:
     - name: tmp
       emptyDir: {}

In the above file, we have defined our entire pod, which will consist of a deployment consisting of two Docker containers (chef-boy-r-dk and ubuntu) with a volume of the type emptyDir mounted at ~/tmp in both containers. We’ve also passed a separate bash script to both of the two containers that will write to the file hello.txt, which will live in the shared volume.

daemon@chef-boy-r-dk-7cb674c7db-scpnn:/$ ls
bin   dev  home  lib64 mnt  proc  run srv  tmp  var
boot  etc  lib media opt  root  sbin  sys  usr
daemon@chef-boy-r-dk-7cb674c7db-scpnn:/$ cd tmp
daemon@chef-boy-r-dk-7cb674c7db-scpnn:/tmp$ ls
hello.txt
daemon@chef-boy-r-dk-7cb674c7db-scpnn:/tmp$ cat hello.txt
Hello from the Chef container
Hello from the Ubuntu container
daemon@chef-boy-r-dk-7cb674c7db-scpnn:/tmp$

We can see that both containers have access to the same emptyDir by executing into either container, navigating to the ~/tmp directory, and taking a peek at the hello.txt file we just created. Lines 8 and 9 above show the contents of hello.txt, which consists of output we defined in lines 24 and 33 in our YAML file above. If either container should fail, the new container that will be spun up in its place will have access to all the data that had previously been written to the ~/tmp directory.

Takeaway:

Kubernetes' emptyDir is just one of many varieties of volumes for storage. It behaves like most volumes in that it provides shared access to data that has been written during runtime from one or more containers in a given pod. Moreover, should one or more containers fail and need to be spun up again, that data will not be lost.

With Orka, you can utilize Kubernetes to control Mac VMs on genuine Apple hardware. MacStadium also provides multiple storage connections that allow you to persist data as required. If you’d like to try Orka yourself, you can use it right now in the Orka demo. Never heard of Orka? Learn more about MacStadium’s Kubernetes-powered Mac virtualization layer.

Share this article

Logo

Orka, Orka Workspace and Orka Pulse are trademarks of MacStadium, Inc. Apple, Mac, Mac mini, Mac Pro, Mac Studio, and macOS are trademarks of Apple Inc. The names and logos of third-party products and companies shown on the website are the property of their respective owners and may also be trademarked.

©2024 MacStadium, Inc. is a U.S. corporation headquartered at 3525 Piedmont Road, NE, Building 7, Suite 700, Atlanta, GA 30305. MacStadium, Ltd. is registered in Ireland, company no. 562354.