emptyDir Volumes: Sharing, Lifecycle, and Memory-Backed
Master emptyDir volumes for CKA/CKAD exam prep. Share data between containers, understand volume lifecycle across restarts vs Pod deletion, and configure
π‘ Quick Answer:
emptyDircreates a fresh empty directory when a Pod starts. Itβs shared across all containers in the Pod, survives container restarts, but is deleted permanently when the Pod is removed from the node. Usemedium: Memoryfor RAM-backed tmpfs when you need ultra-fast ephemeral storage.
The Problem
CKA/CKAD exams test your understanding of:
- How to share files between containers in the same Pod (sidecar patterns)
- What happens to data when a container crashes vs when a Pod is deleted
- How to use memory-backed storage for performance-sensitive temp files
- Resource limits for ephemeral storage (
sizeLimit,ephemeral-storagerequests)
The Solution
Basic emptyDir: Shared Between Containers
apiVersion: v1
kind: Pod
metadata:
name: shared-data
spec:
containers:
# Writer container β generates data
- name: writer
image: busybox:1.36
command: ["/bin/sh", "-c"]
args:
- |
while true; do
echo "$(date) - Log entry" >> /data/output.log
sleep 5
done
volumeMounts:
- name: shared
mountPath: /data
# Reader container β consumes data
- name: reader
image: busybox:1.36
command: ["/bin/sh", "-c"]
args:
- tail -f /data/output.log
volumeMounts:
- name: shared
mountPath: /data
volumes:
- name: shared
emptyDir: {} # Empty directory, shared between containers# Verify sharing works
kubectl exec shared-data -c reader -- cat /data/output.log
# Shows log entries written by the writer container
# Both containers see the same files
kubectl exec shared-data -c writer -- ls /data/
kubectl exec shared-data -c reader -- ls /data/
# Same output β same volumeLifecycle: Container Restart vs Pod Deletion
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-test
spec:
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c"]
args:
- |
echo "Pod started at $(date)" >> /cache/history.txt
cat /cache/history.txt
sleep 3600
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir: {}# Create the Pod
kubectl apply -f lifecycle-test.yaml
# Write some data
kubectl exec lifecycle-test -- sh -c 'echo "important data" > /cache/myfile.txt'
# Kill the container (simulates crash) β Pod restarts
kubectl exec lifecycle-test -- kill 1
# Wait for restart...
kubectl get pod lifecycle-test
# STATUS: Running (RESTARTS: 1)
# Data SURVIVES container restart β
kubectl exec lifecycle-test -- cat /cache/myfile.txt
# "important data" β still there!
# Now delete the Pod
kubectl delete pod lifecycle-test
# Recreate it
kubectl apply -f lifecycle-test.yaml
# Data is GONE after Pod deletion β
kubectl exec lifecycle-test -- cat /cache/myfile.txt
# cat: /cache/myfile.txt: No such file or directoryemptyDir Lifecycle Rules:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Event Data Survives? Why
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Container crash/restart β
Yes emptyDir tied to Pod, not container
Container OOMKill β
Yes Same β Pod still exists
Pod rescheduled β No New Pod = new emptyDir
Pod deleted β No emptyDir deleted with Pod
Node reboot β No Pod evicted, recreated elsewhere
kubectl rollout restart β No Creates new PodMemory-Backed emptyDir (tmpfs)
apiVersion: v1
kind: Pod
metadata:
name: memory-backed
spec:
containers:
- name: app
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: fast-cache
mountPath: /cache
resources:
requests:
memory: "256Mi"
ephemeral-storage: "100Mi"
limits:
memory: "512Mi"
ephemeral-storage: "200Mi"
volumes:
- name: fast-cache
emptyDir:
medium: Memory # RAM-backed tmpfs β‘
sizeLimit: 128Mi # Max size (counts against memory limit)# Verify it's tmpfs
kubectl exec memory-backed -- df -h /cache
# Filesystem Size Used Avail Use% Mounted on
# tmpfs 128M 0 128M 0% /cache
# ^^^ RAM-backed, not disk
# Verify mount type
kubectl exec memory-backed -- mount | grep cache
# tmpfs on /cache type tmpfs (rw,nosuid,nodev,noexec,relatime,size=131072k)
# Performance comparison:
# Disk emptyDir: ~500 MB/s (SSD) or ~100 MB/s (HDD)
# Memory emptyDir: ~10 GB/s (RAM speed)medium: Memory considerations:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β’ Data stored counts against container's MEMORY limit
β’ If sizeLimit exceeded β Pod evicted
β’ If container memory limit exceeded (including tmpfs) β OOMKill
β’ Data lost on Pod deletion (same as disk emptyDir)
β’ Use for: temp files, caches, scratch space needing speed
β’ Don't use for: large datasets that could OOM the containerSize Limiting (Disk-Based)
apiVersion: v1
kind: Pod
metadata:
name: size-limited
spec:
containers:
- name: app
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: bounded
mountPath: /tmp/work
resources:
requests:
ephemeral-storage: "500Mi" # Request from node
limits:
ephemeral-storage: "1Gi" # Hard limit
volumes:
- name: bounded
emptyDir:
sizeLimit: 500Mi # Volume-level limit# What happens when sizeLimit is exceeded?
kubectl exec size-limited -- dd if=/dev/zero of=/tmp/work/big bs=1M count=600
# Pod gets evicted! kubelet periodically checks usage.
# Event: "Pod ephemeral local storage usage exceeds the total limit"Common CKA/CKAD Patterns
# Pattern 1: Init container prepares data for main container
apiVersion: v1
kind: Pod
metadata:
name: init-data-prep
spec:
initContainers:
- name: download
image: curlimages/curl:8.7.1
command: ["curl", "-o", "/work/config.json", "https://example.com/config.json"]
volumeMounts:
- name: work
mountPath: /work
containers:
- name: app
image: busybox:1.36
command: ["cat", "/app/config.json"]
volumeMounts:
- name: work
mountPath: /app
volumes:
- name: work
emptyDir: {}
---
# Pattern 2: Sidecar log shipper
apiVersion: v1
kind: Pod
metadata:
name: log-sidecar
spec:
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c", "while true; do echo $(date) >> /var/log/app.log; sleep 1; done"]
volumeMounts:
- name: logs
mountPath: /var/log
- name: log-shipper
image: busybox:1.36
command: ["/bin/sh", "-c", "tail -f /logs/app.log"]
volumeMounts:
- name: logs
mountPath: /logs
volumes:
- name: logs
emptyDir: {}
---
# Pattern 3: Build artifact passing in CI
apiVersion: v1
kind: Pod
metadata:
name: ci-build
spec:
initContainers:
- name: build
image: golang:1.22
command: ["go", "build", "-o", "/output/app", "."]
workingDir: /src
volumeMounts:
- name: source
mountPath: /src
- name: artifacts
mountPath: /output
containers:
- name: test
image: busybox:1.36
command: ["/artifacts/app", "--self-test"]
volumeMounts:
- name: artifacts
mountPath: /artifacts
volumes:
- name: source
emptyDir: {}
- name: artifacts
emptyDir: {}Common Issues
Pod evicted due to ephemeral storage exceeded
- Cause: emptyDir grew beyond
sizeLimitor node ephemeral storage full - Fix: Set
sizeLimiton emptyDir; setephemeral-storageresource limits on containers
Memory-backed emptyDir causes OOMKill
- Cause: tmpfs data counts toward container memory limit
- Fix: Account for tmpfs size in memory limits (container limit β₯ app memory + tmpfs size)
Data missing after container restart
- Cause: Application writes to container filesystem, not emptyDir mount path
- Fix: Verify
volumeMount.mountPathmatches where app writes; check mount is correct
Best Practices
- Always set
sizeLimitβ prevents runaway Pods from filling node disk - Use
medium: Memoryfor temp caches β 20x faster than disk - Account for tmpfs in memory limits β tmpfs usage counts against memory
- Prefer emptyDir over hostPath β no node coupling, cleaner lifecycle
- Use for inter-container communication β init containers preparing data, sidecars reading logs
- Never store important data β emptyDir is ephemeral by design
Key Takeaways
emptyDiris created fresh when Pod starts, shared across all containers- Data survives container restarts but lost on Pod deletion
medium: Memorycreates tmpfs (RAM-backed, ultra-fast, counts against memory limit)sizeLimitprevents unbounded growth (Pod evicted if exceeded)- Common patterns: init prep β main consume, app β sidecar log ship, build β test
- CKA exam: know lifecycle rules (restart = survives, delete/reschedule = gone)
- Resource accounting: disk emptyDir = ephemeral-storage; memory emptyDir = memory

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
