skip to content

Ephemeral Volume Types

The volumes that live and die with the pod: emptyDir and its memory-backed tmpfs medium, hostPath and why it is a last resort, projected and downwardAPI volumes, and generic ephemeral volumes. Interviewers use them to check what survives a restart.

part ofKubernetesoverview, primer and where to startread it →
on this pageshow

questions

4

How do two containers in the same Kubernetes pod share files through an emptyDir volume, and does that data survive a container crash?

level: juniorimportance: must knowfreq 72%

answer

  1. one directory, many mounts
  2. lifetime of the pod, not container
  3. kubelet creates it at pod setup
  4. restart keeps it, reschedule wipes it
  5. sizeLimit, else the node disk fills

basics

~20 s

An emptyDir is an empty directory the kubelet creates when the pod starts on a node. Every container that mounts it sees the same files. It lasts as long as the pod, so a container crash and restart keeps the data.

solid answer

~40 s

You declare the volume once under `spec.volumes` with `emptyDir: {}`, and each container that needs it lists it in `volumeMounts`, at any `mountPath` it likes. The kubelet creates the directory when the pod is set up on the node, and every container, init containers included, reads and writes the same files. Its lifetime is the **pod's**, not the container's. If a container crashes and the kubelet restarts it under the pod's `restartPolicy`, the files are still there. The directory is removed only when the pod leaves the node: it is deleted, evicted or rescheduled. It is scratch space and a hand-off point between containers, such as an init container that downloads input for the main container. It is not a place for data that must outlive the pod.

code

yaml · 28 lines
yaml
apiVersion: v1
kind: Pod
metadata:
  name: ocr-worker-7f3k
spec:
  initContainers:
  - name: fetch-scan
    image: registry.example.com/ocr/fetcher:2.4.1
    args: ["--out", "/work/in"]
    volumeMounts:
    - name: work
      mountPath: /work
  containers:
  - name: ocr
    image: registry.example.com/ocr/engine:5.3.0
    volumeMounts:
    - name: work
      mountPath: /work
  - name: uploader
    image: registry.example.com/ocr/uploader:1.8.2
    volumeMounts:
    - name: work
      mountPath: /work
      readOnly: true
  volumes:
  - name: work
    emptyDir:
      sizeLimit: 6Gi

go deeper

for a junior

Remember three facts: the volume is declared once and mounted by many containers, it starts empty, and it lives exactly as long as the pod. A container restart keeps it; deleting the pod removes it.

for a middle

Explain why the directory is keyed to the pod UID, so a Deployment's replacement pod always starts empty, and how init containers use the volume to hand input to the app containers.

for a senior

Show you size it: sizeLimit and ephemeral-storage requests so one pod's scratch cannot fill a node disk, read-only mounts for consumer containers, and apps that tolerate their own partial files after a restart.

for a principal

Frame emptyDir as a platform default: a writable scratch mount that lets teams keep read-only root filesystems. Set the limits and guidance that stop it from quietly becoming a place where durable data is stored.

## What an emptyDir is A Kubernetes **volume** is a directory that is declared in the pod spec and mounted into one or more containers. An **emptyDir** is the simplest kind: - It starts **empty** when the pod is set up on a node. - The **kubelet** creates it, by default on the node's disk under the kubelet's working directory. - Every container in the pod that lists it in `volumeMounts` sees **the same directory**. Each container can mount it at a different `mountPath`. That shared directory is how containers in one pod pass files to each other. A container's own root filesystem is private to that container, and another container cannot see what was written into it. ## A worked example: a document-OCR worker pod Take a document-OCR pipeline in which each worker pod handles one scanned batch: 1. An **init container** `fetch-scan` downloads the scanned PDF pages into `/work/in` and exits. 2. The main `ocr` container reads `/work/in` and writes recognised text to `/work/out`. 3. A second long-running container, `uploader`, mounts the same volume **read-only** and ships `/work/out` to the results store. All three mount one emptyDir named `work`. The init container's files are still there when the app containers start, because the volume belongs to the pod and not to any single container. ## What survives what The key point for interviews is that the volume's lifetime equals the **pod's lifetime on its node**. | Event | emptyDir contents | |---|---| | A container crashes and the kubelet restarts it | **Kept**: the pod is the same pod | | A container is OOM-killed and restarted | **Kept** | | The pod is deleted, for example by `kubectl delete pod` or a rollout | **Removed** | | The pod is evicted or rescheduled to another node | **Removed**: the replacement is a new pod with a new, empty directory | | The data was on a memory-backed (`medium: Memory`) emptyDir and the node reboots | **Lost** with the node's RAM | A Deployment's replacement pod is a **new pod** with a new UID, so it always starts with an empty directory, even if the scheduler places it on the same node. ## How it compares with the other ephemeral volume kinds emptyDir is one of several volume kinds whose lifetime is tied to the pod or to the node rather than to a PersistentVolume: | Kind | Where the bytes live | Typical use | |---|---|---| | `emptyDir` | Node disk, or RAM with `medium: Memory` | Scratch space, hand-off between containers | | `hostPath` | An existing path on the node itself | Node agents that must read the host; a last resort for apps | | `projected` / `downwardAPI` | Files the kubelet writes from API data | Tokens, config files, pod metadata | | Generic ephemeral (`ephemeral.volumeClaimTemplate`) | A dynamically provisioned volume, deleted with the pod | Large per-pod scratch space served by a storage driver | **hostPath** looks similar but works differently. It exposes an existing node directory, so its data outlives the pod and a pod on a different node sees different data. Mounting parts of the host into a container also lets that container reach node files, which is why platform teams restrict it. ## Practical rules - Set `sizeLimit` on disk-backed emptyDirs. If usage goes over it, the kubelet evicts the pod. Without it, one pod's scratch can fill the node's disk. - Declare `resources.requests.ephemeral-storage` on containers that write heavily so the scheduler accounts for that disk. - Mount the volume `readOnly: true` in containers that only consume the files. - Anything that must survive the pod, such as results or checkpoints, belongs in a PersistentVolumeClaim or an external store, not in an emptyDir. - An emptyDir is the usual fix for a read-only root filesystem: mount one at `/tmp` or at the app's cache path. ```yaml apiVersion: v1 kind: Pod metadata: name: ocr-worker-7f3k spec: volumes: - name: work emptyDir: sizeLimit: 6Gi ```

  • The OCR container is OOM-killed halfway through a batch. What does it find in the emptyDir when it restarts?
    It finds everything written before the kill: the input pages from the init container and any partial output. The kubelet restarted the container inside the **same pod**, and an emptyDir lives as long as the pod. The app should therefore handle leftovers from its own earlier attempt, for example by writing to a temporary name and renaming when done. Otherwise a restart can pick up a half-written file.
  • Why does a replacement pod created by a Deployment start with an empty emptyDir, even if it lands on the same node?
    The replacement is a **new pod object** with a new UID, and the kubelet keys emptyDir directories by pod. When the old pod was removed, its directory was cleaned up with it. Same-node placement does not matter, because the volume never belonged to the node or to the Deployment.

An emptyDir is a whiteboard in a meeting room that is booked for one meeting. People can step out and come back and the notes are still there, but the room is wiped once the booking ends.

saying these in an interview costs you the question

  • Says each container gets its own separate copy of an emptyDir
  • Believes emptyDir data is wiped every time a container restarts
  • Expects a rescheduled pod to find its emptyDir data on the new node
  • Uses emptyDir for data that must outlive the pod, such as results
  • Thinks emptyDir is a directory shared with the host like hostPath
  • Never sets sizeLimit, so one pod's scratch can fill the node disk
open as a page

In Kubernetes, what does an emptyDir volume with medium: Memory give you, and how do sizeLimit and memory limits bound it?

level: middleimportance: should knowfreq 46%

basics

~20 s

medium: Memory mounts the emptyDir as RAM-backed tmpfs, which is fast and never touches the node disk. The kubelet caps it at the smallest of sizeLimit, the pod's memory limit and node allocatable, and every byte written counts as memory use.

open as a page

What does a Kubernetes projected volume do, and why would a pod project a serviceAccountToken with its own audience and expirationSeconds?

level: middleimportance: should knowfreq 41%

basics

~20 s

A projected volume merges Secrets, ConfigMaps, downward API fields and service account tokens into one read-only directory. A projected serviceAccountToken is short-lived, scoped to one audience and rotated by the kubelet, so it is safer to hand to an external service.

open as a page

A document-OCR pipeline on a Kubernetes cluster that autoscales between 20 and 80 nodes needs 140Gi of per-pod scratch. When would you choose a generic ephemeral volume over emptyDir, and what can go wrong?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Choose a generic ephemeral volume when per-pod scratch is too large for the node disk. A storage driver provisions a PVC for each pod, and it is deleted with the pod. The costs are provisioning latency, name collisions, quota and attach limits.

open as a page