Accessing Host’s Resources through hostPath Volumes
Learn about hostPath Volume type and try to access the host's resources through it.
Building docker images#
Sooner or later, we’ll have to build our images. A simple solution would be to execute the docker image build
command directly from a server. However, that might cause problems. Building images on a single host means that there is an uneven resource utilization and that there is a single point of failure. Wouldn’t it be better if we could build images anywhere inside a Kubernetes cluster?
Instead of executing the docker image build
command, we could create a Pod based on the docker
image. Kubernetes will make sure that the Pod is scheduled somewhere inside the cluster, thus distributing resource usage much better.
Creating a pod with docker image#
Let’s start with an elementary example. If we can list the images, we’ll prove that running docker
commands inside containers works. Since, from Kubernetes’ point of view, Pods are the smallest entity, that’s what we’ll run.
We created a Pod named docker
and based it on the official docker
image. Since we want to execute a one-shot command, we specified that it should Never
restart. Finally, the container command is docker image ls
. The second command lists all the Pods in the cluster (including failed ones).
The output of the latter command is as follows.
The output should show that the status is Error
, thus indicating that there is a problem with the container we’re running. If, in your case, the status is not yet Error
, Kubernetes is probably still pulling the image. In that case, please wait a few moments, and re-execute the kubectl get pods
command.
Let’s take a look at the logs of the container.
The output is as follows.
Docker consists of two main pieces. There is a client, and there is a server. When we executed docker image ls
, we invoked the client which tried to communicate with the server through its API. The problem is that Docker server is not running in that container. What we should do is tell the client (inside a container) to use Docker server that is already running on the host.
By default, the client sends instructions to the server through the socket located in /var/run/docker.sock
. We can accomplish our goal if we mount that file from the host into a container.
Before we try to enable communication between a Docker client in a container and Docker server on a host, we’ll delete the Pod we created a few moments ago.
Part of the definition closely mimics the kubectl run
command we executed earlier. The only significant difference is in the volumeMounts
and volumes
sections.
Line 9-10: We changed the command and the arguments to sleep 100000
. That will give us more freedom since we’ll be able to create the Pod, enter inside its only container, and experiment with different commands.
Line 11: The volumeMounts
field is relatively straightforward and is the same no matter which type of Volume we’re using. In this section, we’re specifying the mountPath
and the name
of the volume. The former is the path we expect to mount inside this container. You’ll notice that we are not specifying the type of the volume nor any other specifics inside the VolumeMounts
section. Instead, we simply have a reference to a volume called docker-socket
.
Line 14: The Volume configuration specific to each type is defined in the volumes
section. In this case, we’re using the hostPath
Volume type.
The hostPath volume#
hostPath
allows us to mount a file or a directory from a host to Pods and, through them, to containers. Before we discuss the usefulness of this type, we’ll have a short discussion about use-cases when this is not a good choice.
Do not use
hostPath
to store a state of an application. Since it mounts a file or a directory from a host into a Pod, it is not fault-tolerant. If the server fails, Kubernetes will schedule the Pod to a healthy node, and the state will be lost.
For our use case, hostPath
works just fine. We’re not using it to preserve state, but to gain access to Docker server running on the same host as the Pod.
Line 15-18: The hostPath
type has only two fields. The path
represents the file or a directory we want to mount from the host. Since we want to mount a socket, we set the type
accordingly. There are other types we could use.
Types of mounts in hostPath#
-
The
Directory
type will mount a directory from the host. It must exist on the given path. If it doesn’t, we might switch toDirectoryOrCreate
type which serves the same purpose. The difference is thatDirectoryOrCreate
will create the directory if it does not exist on the host. -
The
File
andFileOrCreate
are similar to theirDirectory
equivalents. The only difference is that this time we’d mount a file, instead of a directory. -
The other supported types are
Socket
,CharDevice
, andBlockDevice
. They should be self-explanatory. If you don’t know what character or block devices are, you probably don’t need those types.
These were the types of mounts supported by the hostPath.
Try it yourself#
A list of all the commands used in the lesson is given below.
You can practice the commands in the following terminal by pressing the Click to Connect button and waiting for the cluster to set up.