Overview

9 Adding volumes for storage, configuration, and metadata

This chapter explains how Kubernetes volumes extend pods beyond their containers’ ephemeral filesystems to store data, share files, and surface configuration and metadata. Volumes are defined at the pod level and mounted into one or more containers, surviving container restarts and enabling patterns such as sidecars that read or write shared files. Depending on the backing, volumes can persist only for the pod’s lifetime (for example, emptyDir) or map to external storage that outlives the pod and can be reattached across pod instances. A single pod may use multiple volumes with different performance and access characteristics, mounted read/write or read-only as needed.

The chapter demonstrates practical patterns and trade-offs. With emptyDir, data survives container restarts and can be shared between containers; it can live on disk or in memory (tmpfs) and can be prepopulated via init containers or simple inline scripts. A newer image volume type can expose files directly from an OCI image to other containers without a copier init step. Accessing the node’s filesystem via hostPath is supported but risky and typically reserved for privileged, system-level workloads due to its broad access. The text also covers sharing data across pods using external storage and highlights how storage technology dictates concurrency and access modes.

The chapter then shows how to project configuration and metadata as files with configMap, secret, and downwardAPI volumes, and how to merge them with projected volumes so one mount can hold multiple sources (including a pod’s ServiceAccount token). It details atomic updates via symlinks, the subPath caveat (which disables live updates), and how to set ownership and permissions with defaultMode, per-file mode, and fsGroup so applications can read sensitive files safely. Finally, it notes the kube-api-access projected volume that Kubernetes injects into most pods by default and closes by contrasting ephemeral volumes with persistent storage, leading into the next chapter on PersistentVolumes and PersistentVolumeClaims.

Mounting a filesystem into the file tree
How the Quiz service fits into the architecture of the Kiada Suite
The Quiz API and the MongoDB database run in the same pod
Volumes are defined at the pod level and mounted in the pod’s containers.
Volumes ensure that part of the container’s filesystem is persisted across restarts.
A pod can contain multiple volumes, and a container can mount multiple volumes.
A volume can be mounted into more than one container.
Pod volumes can also map to storage volumes that persist across pod restarts.
Using volumes to share data between pods
The quiz pod with an emptyDir volume for storing MongoDB data files
The emptyDir is a normal file directory in the node’s filesystem mounted into the container.
Using an init container to initialize an emptyDir volume
The new version of the Quote service uses two containers and a shared volume.
A hostPath volume mounts a file or directory from the worker node’s filesystem into the container.
Using subPath to mount a single file from the volume
Projecting a Secret’s entries into the container’s filesystem via a secret volume
Using a projected volume with several sources

Summary

  • Pods consist of containers and volumes. Each volume can be mounted at the desired location in the container’s filesystem.
  • Volumes are used to persist data across container restarts, share data between the containers in the pod, and even share data between the pods.
  • An emptyDir volume is used to store data for the lifetime of the pod. It starts as an empty directory that’s created just before the pod’s containers are started and is deleted when the pod terminates.
  • An init container can be used to add files to the emptyDir volume before the pod’s regular containers are started. Regular containers can then add additional files or modify existing files in the volume.
  • An image volume can be used to mount an Open Container Initiative (OCI) image or artifact into a container. This is used for static, possibly large files that the container needs for its operation.
  • The hostPath volume allows a pod to access any path in the file system of the host node. This volume type is dangerous because it allows users to make changes to the configuration of the host node and run any process on the node.
  • The configMap, secret, and downwardAPI volumes are used to project ConfigMap and Secret entries as well as pod metadata into a container. Alternatively, the same can be done with a single projected volume.
  • Many other volume types are no longer meant to be directly configured in pods. Instead, a persistentVolumeClaim, ephemeral, or csi volume must be used, which is explained in the next chapter.

FAQ

When should I add a volume to a pod?Use a volume when containers need any of the following: - Data to survive container restarts (for example, databases writing outside the image filesystem). - File sharing between multiple containers in the same pod. - Access to configuration, secrets, or pod metadata as files. - Access to host node files or devices (system pods only, via hostPath). Remember: a volume’s lifetime is the pod’s lifetime. To persist across pod replacements, use storage backed by persistent volumes (covered in the next chapter).
What is an emptyDir volume and what survives a restart?emptyDir creates an initially empty directory for the pod: - Data persists across container restarts because the volume is tied to the pod, not a single container. - Data is lost when the pod is deleted. - You can set medium: Memory to use tmpfs (fast, in-RAM) and sizeLimit to cap usage.
How do I mount a volume in a container, and what mount options matter?Define the volume at spec.volumes, then mount it in the container’s volumeMounts with: - name: the volume’s name and mountPath: the target path in the container. Useful options: - readOnly and recursiveReadOnly: enforce read-only (including subpaths). - subPath / subPathExpr: mount a single file or subdirectory; subPathExpr supports $(ENV_VAR) defined in the container. - mountPropagation: None, HostToContainer, or Bidirectional for advanced mount sharing semantics.
How can containers in the same pod share files?Add a single volume (often emptyDir) and mount it into each container at paths they expect. You can mount it: - Read/write in a producer container. - Read-only in consumer containers (for better security). This pattern is common for sidecars (e.g., log processors, content generators, or init tasks).
How do I pre-populate data in a volume?Common approaches: - Init container: copy or generate files into a shared emptyDir before main containers start. - Inline write: an init container echoes short, inline content into files (handy for small configs). - Image volume: mount the file system of an OCI image directly as a read-only volume (simplest when available). Each ensures the main container sees the ready-to-use files at startup.
What is the image volume type and how do I use it?The image volume type exposes the contents of an OCI image as a read-only volume for other containers in the same pod. Notes: - It’s feature-gated (ImageVolume) and may need enabling by your cluster admin (for Kind, use the provided config in the chapter). - Define a volume with image.reference and mount it where needed (e.g., to feed init scripts or model files into another container). - It replaces many init-copy patterns with a simpler, immutable read-only mount.
What is a hostPath volume and why is it risky?hostPath mounts a file or directory from the node’s filesystem into the pod. Use sparingly: - Appropriate for system-level pods that must read node logs, devices, or sockets. - Dangerous for multi-tenant clusters: it can grant root-equivalent control over the node (e.g., by mounting /var/run/docker.sock). - You can enforce expectations with hostPath.type (Directory, File, …, or *OrCreate variants). Avoid for app data unless the pod is pinned to the same node.
How do configMap and secret volumes work, and how do updates propagate?Mounting as files: - configMap and secret volumes project keys as files. You can include all keys or select items. - Updates: configMap/secret volume contents refresh automatically (can take up to ~1 minute) via symlink swaps for atomic updates. Caveats: - Using subPath disables live updates (files are written directly). - You can mark the reference optional: true; otherwise a missing source blocks pod startup. - Secret volumes use tmpfs (in-memory) by default.
How do I control file permissions and ownership for configMap/secret volumes?Permissions: - defaultMode sets the default file mode for all entries (octal like 0644); per-file mode can be set under items[].mode. Ownership: - Files are owned by the kubelet user/group; to let your app read restricted files, set spec.securityContext.fsGroup to the app’s group ID. This changes the group ownership of mounted files so non-root processes (e.g., user 101:envoy) can read them.
What is a projected volume, and what is the built-in kube-api-access volume?Projected volumes combine sources—ConfigMaps, Secrets, Downward API (and ServiceAccount token)—into a single mount point, simplifying layouts (e.g., put envoy.yaml, cert, and key under /etc/envoy). Built-in: - Most pods get an automatic projected volume named like kube-api-access-*, containing: - A short-lived ServiceAccount token (token), - The cluster CA bundle (ca.crt), - The pod’s namespace (namespace). - Disable it per pod with automountServiceAccountToken: false if your app doesn’t call the Kubernetes API.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Kubernetes in Action, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Kubernetes in Action, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Kubernetes in Action, Second Edition ebook for free