Kubernetes Volumes

Shardul | May 2, 2025 min read

Kubernetes provides a powerful abstraction for managing containerized applications, and volumes play a crucial role in enabling storage across container lifecycles.

In this blog post, we’ll break down:

  • What Kubernetes volumes are
  • The difference between ephemeral and persistent volumes
  • When and how to use each
  • Configuration examples for common volume types

What Are Kubernetes Volumes?

In Kubernetes, a volume is a storage directory accessible to containers in a Pod. Volumes are used to persist data, share files between containers, and inject configuration or secrets. Unlike a container’s root filesystem, which is ephemeral and reset on restarts, a volume’s data can persist.

There are two main types of volumes in Kubernetes:

  • Ephemeral Volumes: Exist only during the Pod’s lifetime
  • Persistent Volumes (PVs): Exist independently of any Pod

Ephemeral Volumes

Ephemeral volumes are tied to a Pod’s lifecycle. When the Pod is deleted, the data is gone. They’re ideal for temporary data, caching, or injecting runtime configuration.

Ephemeral Volume Types:

1. emptyDir

Temporary storage shared between containers in a Pod.

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

Use for: Caching, shared temp files

2. hostPath

Mounts a file or directory from the node’s host filesystem.

hostPath:
  path: /data/foo
  type: Directory

Use with caution— can compromise node security.

3. configMap

Injects non-sensitive configuration data as files.

configMap:
  name: app-config

✅ Use for: Feature flags, environment config

4. secret

Mounts sensitive info like passwords or TLS keys.

secret:
  secretName: my-secret

✅ Use for: DB credentials, tokens

5. downwardAPI

Provides Pod metadata and resource limits to containers.

downwardAPI:
  items:
    - path: "labels"
      fieldRef:
        fieldPath: metadata.labels

Use for: Logging context, telemetry

6. projected

Combines multiple sources (ConfigMap, Secret, etc.) into one volume.

projected:
  sources:
    - configMap:
        name: my-config
    - secret:
        name: my-secret

7. ephemeral

Dynamically creates storage from a PVC template—but it’s deleted with the Pod.

ephemeral:
  volumeClaimTemplate:
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

Persistent Volumes

Persistent Volumes are independent from individual Pods. They are managed via the Kubernetes API and backed by real storage (local disk, NFS, cloud block storage, etc.).

Kubernetes separates the lifecycle of storage from Pods through:

  • PersistentVolume (PV): A resource that represents storage
  • PersistentVolumeClaim (PVC): A Pod’s request for storage
  • StorageClass: Defines how storage is provisioned dynamically

Lifecycle

  1. Admin provisions a PV, or Kubernetes dynamically provisions it.
  2. User creates a PVC specifying size and access mode.
  3. Kubernetes binds the PVC to a matching PV.
  4. Pod uses the PVC as a volume.

1. Define a PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  local:
    path: /storage/data
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - minikube

2. Define a PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

3. Use the PVC in a Pod:

apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: /data
      name: my-storage
  volumes:
  - name: my-storage
    persistentVolumeClaim:
      claimName: mypvc

StorageClass & Dynamic Provisioning

Dynamic provisioning allows PVCs to automatically create backing PVs using a StorageClass.

Example:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2

✅ PVCs can reference this StorageClass for automatic provisioning:

spec:
  storageClassName: fast-storage

Common PV Types

Volume Type Description
awsElasticBlockStore AWS EBS block storage
gcePersistentDisk GCP persistent disk
azureDisk Azure-managed disks
nfs NFS-mounted volumes
local Node-local storage (non-portable)
csi Container Storage Interface (CSI driver)

Summary Table

Volume Type Type Use Case Persistent? Storage Backend
emptyDir Ephemeral Caching, temp files Node local disk
hostPath Ephemeral Host file access Host filesystem
configMap Ephemeral Config injection K8s API
secret Ephemeral Credential injection tmpfs (RAM)
downwardAPI Ephemeral Pod metadata K8s API
projected Ephemeral Combine secret/configMap/etc. Mixed
ephemeral Ephemeral Stateful ephemeral workloads PVC-based
persistentVolumeClaim Persistent Data persistence across Pods Block, file, cloud

Best Practices

  • ✅ Use ephemeral volumes for short-lived data or configuration.
  • ✅ Use PVCs for data that must survive Pod restarts or rescheduling.
  • ⚠️ Be cautious with hostPath and give appropriate permissions.
  • 🔐 Protect secret volumes with RBAC and limit Pod access.

Further Reading