Volumes and volume types

What a volume is, which volume types to know by heart, and how two containers in one Pod share a folder.

30 min 2 hands-on tasksStorage · 10% of the exam

Key ideas in this lesson · tap one for a simple explanation

What you will be able to do

  • Write a Pod with emptyDir, hostPath and projected volumes, and put volumes and volumeMounts in the right place.
  • Share one volume between two containers and prove from inside the Pod that it works.
  • Say why hostPath is risky, where the control plane still uses it, and check its files on the node.

When a restarts, every file it wrote is lost. A volume is a folder that lives outside the container, so its files stay. Containers in the same can also share it.

Storage is 10% of the exam, the smallest part. Volume questions are quick points if you can type the from memory. Typical ones: an emptyDir shared by two containers, or a hostPath folder on one . They cost minutes if you have to look up where volumeMounts goes.

Why a container needs a volume

A container keeps its files only while it runs. Say your app saves uploaded photos in /data. The container crashes and Kubernetes restarts it. Without a volume, /data is empty again.

There is a second problem. Each container in a Pod has its own filesystem, so two containers cannot pass files through a normal folder. A volume solves both problems. It has two parts in the Pod YAML:

  • spec.volumes: you define the volume once, for the whole Pod. You give it a name and a type.
  • volumeMounts: each container that wants the volume lists its name and a mountPath, the folder where it appears inside that container.
One volume, mounted by two containers

writer container

writes index.html

mountPath: /​out

Volume: content

defined once in spec.volumes

emptyDir

web container

serves the file, read-only

mountPath: /​usr/​share/​nginx/​html

The volume is defined once for the Pod. Each container mounts it by name, at its own path. This is the shape of the first task.

Whether the data also outlives the Pod depends on the volume type:

Volume typeWhere the data livesHow long it lastsTypical use
emptyDirOn the node's disk, or in RAMUntil the Pod is deleted. It survives container restarts.Scratch files, a cache, files shared between containers
configMap, secret, projectedIn API objects. The copies them into files.As long as the or existsConfig files, certificates
hostPathIn a folder on one nodeUntil someone removes it from that nodeControl plane , node agents
persistentVolumeClaimIn a (next lesson)Longer than the PodDatabases, anything that must outlive the Pod

emptyDir

An emptyDir is an empty folder. The kubelet creates it when the Pod starts on a node, and deletes it when the Pod is removed. It survives container restarts, but not Pod deletion. Example: a web app that renders thumbnails into a scratch folder.

  • emptyDir: {} is the whole definition for the plain case. The folder is on the node's disk.
  • sizeLimit caps the size. If the volume grows past it, the kubelet evicts the Pod.
  • medium: Memory keeps the files in RAM. It is faster, but the files count as the container's memory use.
Two emptyDir volumes: one on disk with a cap, one in memory
apiVersion: v1
kind: Pod
metadata:
  name: scratch
  namespace: st-vol
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "sleep 3600"]
      volumeMounts:
        - name: scratch
          mountPath: /scratch
        - name: fast
          mountPath: /fast
  volumes:
    - name: scratch
      emptyDir:
        sizeLimit: 256Mi
    - name: fast
      emptyDir:
        medium: Memory
        sizeLimit: 64Mi

hostPath

A hostPath volume mounts a folder (or a file) from the node into the container. The files live on the node's own disk. The optional type says what the kubelet checks before it mounts the path:

typeWhat the kubelet does
(not set)No check. It mounts whatever is at the path.
DirectoryOrCreateCreates the folder if it is missing. The usual choice for a folder your Pod writes to.
DirectoryThe folder must already exist. If it does not, the Pod is stuck in ContainerCreating.

A few more types check for a file or a socket instead. You rarely need them.

hostPath data is node-local: it exists only on the node that wrote it. Say your Pod writes logs to /opt/logs on cka-worker. Tomorrow it starts on cka-worker2 and finds an empty folder. So pin such a Pod to one node, with nodeName or a nodeSelector.

To check the files, open a shell on that node. On the lab that is docker exec cka-worker ls /opt/node-writer. On the exam it is ssh cka-worker, then the same ls.

A Pod pinned to cka-worker that writes into a node directory
apiVersion: v1
kind: Pod
metadata:
  name: node-writer
  namespace: st-vol
spec:
  nodeName: cka-worker
  containers:
    - name: writer
      image: busybox:1.36
      command: ["sh", "-c", "date > /data/started; sleep 3600"]
      volumeMounts:
        - name: data
          mountPath: /data
  volumes:
    - name: data
      hostPath:
        path: /opt/node-writer
        type: DirectoryOrCreate

Volumes made from ConfigMaps and Secrets

A configMap or secret volume turns each key of that object into a file. Both are taught in ConfigMaps and Secrets.

A projected volume puts several sources into one folder. Example: your app wants its config file and its TLS certificate side by side in /etc/app. One projected volume gives it both:

The volumes block of a Pod with a projected volume
volumes:
  - name: bundle
    projected:
      sources:
        - configMap:
            name: app-settings
        - secret:
            name: app-tls

volumeMounts and sharing a volume

Four rules decide what a container sees:

  • Each mount names a volume from spec.volumes and gives a mountPath: the folder inside the container.
  • A mount hides whatever the image had at that path. In the first task, the volume hides nginx's default page in /usr/share/nginx/html. To add one file without hiding the folder, use subPath, shown in ConfigMaps and Secrets.
  • readOnly: true goes on the mount, not on the volume. So one container can write while another only reads.
  • Two containers share a volume when both mount the same name. Each one can use its own mountPath.

Containers in a Pod also share one network. So in the first task, the writer container can test nginx at http://localhost/. A helper container that works next to the main one is called a : see Pods, init containers and sidecars.

In the official docs· open on exam day too

Hands-on task 1 of 2st-vol-1
~7 min4% weightStorage

Two containers sharing an emptyDir

In namespace st-vol create a Pod named shared-web with two containers that share an emptyDir volume named content limited to 64Mi. Container writer uses image busybox:1.36, mounts the volume at /out and runs sh -c 'echo hello from writer > /out/index.html; while true; do sleep 3600; done'. Container web uses image nginx:1.27 and mounts the same volume read-only at /usr/share/nginx/html. When the Pod is running, a request to http://localhost/ from inside the writer container must return the line that writer wrote.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-1/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-1/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-1/cleanup | bash
Hands-on task 2 of 2st-vol-2
~6 min4% weightStorage

A hostPath volume on a specific node

Create a Pod named node-logger in namespace st-vol that runs on node cka-worker. Mount the node directory /opt/st-logs into the container at /host-logs through a hostPath volume named logs; the directory must be created on the node if it does not exist yet. The container uses image busybox:1.36 and runs sh -c 'echo node-logger was here > /host-logs/marker.txt; while true; do sleep 3600; done'. When you are done, /opt/st-logs/marker.txt must exist on cka-worker.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-2/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-2/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/st-vol-2/cleanup | bash

Finished this lesson?

0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.