12 · Volumes
Container filesystems are temporary. When a container restarts, its filesystem is reset to the image state. Volumes provide storage that outlasts container restarts — and in some cases, outlasts the Pod itself.
Why Containers Need Volumes
A container's writable layer is destroyed when the container exits. Two scenarios make this a problem:
- Data that must survive a crash: a container writing to disk (logs, uploads, database files) loses that data if the container restarts without a volume.
- Sharing data between containers: two containers in the same Pod cannot directly share files — they need a volume as a common mount point.
Volume Lifetime
A critical distinction in Kubernetes: pod-scoped volumes exist as long as the Pod exists. Cluster-scoped volumes (PersistentVolumes) exist independently of any Pod.
Most volume types in Kubernetes are pod-scoped. This means they survive container restarts within the same Pod, but are destroyed when the Pod is deleted.
Common Volume Types
emptyDir
Created when the Pod starts, deleted when the Pod is deleted. Both containers in a multi-container Pod can mount the same emptyDir to share files.
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: writer
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
volumeMounts:
- name: shared-data
mountPath: /input
Use cases: - Scratch space for temporary computation - Passing files between an init container and the main container - Caching data that can be regenerated if lost
By default, emptyDir uses the node's disk. Setting emptyDir.medium: Memory makes it a RAM-backed tmpfs — faster, but counts against the Pod's memory limit.
hostPath
Mounts a file or directory from the node's filesystem into the Pod.
hostPath is dangerous
A Pod with a hostPath mount has access to the node's filesystem. A misconfigured or compromised container can read /etc/passwd, write to system directories, or escape the container. Avoid hostPath in production except for DaemonSets that explicitly need host-level access (e.g., log collectors, node monitoring agents).
configMap and secret
Mount a ConfigMap or Secret as files in the container's filesystem. Covered in depth in the ConfigMaps and Secrets post.
PersistentVolumeClaim (PVC)
Mount a persistent volume — network-attached storage that outlives the Pod. This is the standard for anything that needs to survive Pod deletion. Covered in depth in the next post.
Init Containers and Volumes
A common pattern: an init container prepares data in an emptyDir volume, and the main container consumes it.
initContainers:
- name: fetch-config
image: curlimages/curl
command: ["curl", "-o", "/init/config.json", "http://config-service/config"]
volumeMounts:
- name: init-data
mountPath: /init
containers:
- name: app
volumeMounts:
- name: init-data
mountPath: /config
readOnly: true
volumes:
- name: init-data
emptyDir: {}
The init container runs to completion before the main container starts, guaranteeing the config file is present.
Volume Summary
| Type | Lifetime | Use case |
|---|---|---|
emptyDir |
Pod lifetime | Scratch space, inter-container sharing |
hostPath |
Node lifetime | DaemonSet agents (use carefully) |
configMap |
Until ConfigMap is deleted | Config files |
secret |
Until Secret is deleted | Certificates, passwords as files |
persistentVolumeClaim |
Independent of Pod | Databases, uploads, anything persistent |
emptyDir (Memory) |
Pod lifetime | High-speed temporary storage |
For anything that needs to survive Pod deletion — databases, user uploads, application state — use a PersistentVolumeClaim. Ephemeral volumes are for transient data only.