How to K8s: Sharing Data Between Containers in a Pod
In part three of our How to K8s series, we take you through emptyDir and volume, and how to share data between containers in a pod.
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.