Ephemeral Storage Volume: emptyDir

By default, containers within a Kubernetes Pod operate with isolated filesystems. Any data written to a container's local writable layer is ephemeral; once the container is destroyed, the data vanishes. To facilitate data sharing between containers in the same Pod and to provide a space for temporary storage, Kubernetes offers a fundamental volume type known as emptyDir.

An emptyDir volume is first created when a Pod is assigned to a node and exists as long as that Pod is running on that node. The kubelet allocates an empty directory on the host node, which is then mounted into all containers that reference it.
The defining characteristic of emptyDir is its tight coupling with the Pod's lifecycle. Understanding this behavior is critical for designing resilient applications:

  • Initialization: The volume is created when the Pod is scheduled. It starts as an empty directory.
  • Container Resilience: If a container within the Pod crashes and is restarted, the data in the emptyDir volume persists. This allows the restarted container to pick up where it left off.
  • Pod Termination: Once the Pod is deleted from the cluster or evicted from the node, the emptyDir volume and all its contents are permanently erased.
  • Node Locality: The data is stored locally on the node. If a Pod is rescheduled to a different node, it will start with a fresh, empty directory; it does not "follow" the Pod across the cluster.

Common Use Cases

emptyDir is ideal for data that is necessary for the Pod's operation but does not need to be preserved long-term. Typical scenarios include:

  • Temporary Scratch Space: Applications performing heavy data processing—such as sorting large datasets, compressing/decompressing files, or running ETL (Extract, Transform, Load) pipelines—can use emptyDir to store intermediate results.
  • Checkpointing: For long-running computational tasks, writing periodic state snapshots (checkpoints) to an emptyDir allows the application to recover quickly after a container crash without restarting the entire process from scratch.
  • The Sidecar Pattern: This is one of the most frequent uses of emptyDir. For example, a primary application container can write logs to a shared volume, while a sidecar container (like Fluent Bit or Filebeat) reads those logs from the same volume to ship them to a centralized logging server.

Implementation Example

The following configuration demonstrates a Pod with two containers sharing a volume named cache-vol.

apiVersion: v1
kind: Pod
metadata:
  name: shared-data-pod
spec:
  containers:
  - name: app
    image: busybox
    command: ["/bin/sh", "-c"]
    args:
      - while true; do date >> /data/index.html; sleep 5; done
    volumeMounts:
    - name: cache-vol
      mountPath: /data
  - name: sidecar
    image: nginx
    volumeMounts:
    - name: cache-vol
      mountPath: /usr/share/nginx/html
  volumes:
  - name: cache-vol
    emptyDir: {}

Configuration Breakdown:

  • The volumes section defines cache-vol as an emptyDir. By leaving the curly braces empty ({}), Kubernetes uses the node's default disk medium.
  • The app container appends a timestamp to /data/index.html every five seconds.
  • The sidecar container (Nginx) mounts the same volume as its web root. Consequently, any request to the Nginx server will serve the file being updated by the app container in real-time.

Leveraging Memory for High Performance

While emptyDir defaults to the node's disk, you can configure it to use a tmpfs (RAM-backed filesystem) for significantly higher I/O performance.

  volumes:
  - name: cache-vol
    emptyDir:
      medium: Memory
      sizeLimit: 256Mi

When using medium: Memory, keep the following in mind:

  • Speed: Read/write operations are substantially faster than disk, making it perfect for high-frequency, small-volume temporary data.
  • Resource Accounting: Memory used by a tmpfs volume counts toward the container's memory limit. Failing to set a sizeLimit can lead to the Pod consuming all available node memory.
  • Volatility: Unlike disk-based emptyDir, data in memory is lost immediately if the node reboots.

Managing Storage Limits

To prevent a single Pod from consuming all available disk space on a node—which could lead to "Disk Pressure" and impact other workloads—you should define a sizeLimit.

The kubelet monitors the usage of emptyDir volumes. If the volume exceeds the specified sizeLimit, the kubelet may evict the Pod to protect the node's stability. Explicitly defining limits is a best practice for maintaining cluster health and ensuring predictable resource allocation.

Critical Considerations

When integrating emptyDir into your architecture, observe these guidelines:

  1. No Persistence: Never store business-critical or permanent data in an emptyDir. For data that must survive Pod deletion, use PersistentVolumes (PV) and PersistentVolumeClaims (PVC).
  2. Node Binding: Remember that data is local. If your application relies on data consistency across rescheduling events, emptyDir is not the right tool.
  3. OOM Risks: When using medium: Memory, always pair the sizeLimit with appropriate container memory requests and limits to avoid triggering Out-Of-Memory (OOM) kills.
  4. Concurrency Control: When multiple containers write to the same emptyDir, be mindful of file locking and race conditions. Handle synchronization at the application level or designate specific sub-directories for each container.

Summary

emptyDir provides a lightweight, efficient solution for ephemeral storage and inter-container communication within a Pod. By understanding its lifecycle—essentially "living and dying" with the Pod—and utilizing configurations like medium: Memory and sizeLimit, developers can optimize their applications for both performance and stability.