Skip to content
Rahul Shishodiaon GitHub LinkedIn profile

Volumes

Volume types

TypeCategoryUse
emptyDirEphemeralShare data between containers in same Pod
configMap, secretEphemeralInject config (dedicated volume per source)
projectedEphemeralOne mount combining multiple sources (see below)
downwardAPIEphemeralPod metadata as files (Downward API)
hostPathEphemeralNode filesystem: single-node/dev only
persistentVolumeClaimPersistentClaim PV storage
nfsPersistentNFS share
  • Two steps: spec.volumes[] + spec.containers[].volumeMounts[] (match name)

emptyDir

volumes:
- name: logs-volume
  emptyDir: {}
volumeMounts:
- mountPath: /var/log/nginx
  name: logs-volume

Projected volumes

  • Mount several volume sources under one volumeMount path
  • sources can include: secret, configMap, downwardAPI, serviceAccountToken
  • Each entry uses the same field shapes as the standalone volume type (e.g. secret.secretName, downwardAPI.items)
volumes:
- name: all-in-one
  projected:
    defaultMode: 420
    sources:
    - secret:
        name: mysecret
        items:
        - key: username
          path: my-group/my-username
    - configMap:
        name: myconfigmap
        items:
        - key: config
          path: my-group/my-config
    - downwardAPI:
        items:
        - path: labels
          fieldRef:
            fieldPath: metadata.labels
    - serviceAccountToken:
        path: token
        expirationSeconds: 3600
        audience: api
containers:
- name: app
  volumeMounts:
  - name: all-in-one
    mountPath: /etc/config
    readOnly: true
  • serviceAccountToken: expose the Pod SA token as a file (rotation via projected token volumes)
  • Prefer projected over multiple separate volumes when one directory should merge config + secrets + metadata

PV / PVC flow

Pod → PVCPV
ObjectRole
PVCluster storage resource (decoupled from Pod)
PVCRequests size + access mode; binds to PV
  • Static: create PV manually; PVC storageClassName: "" to skip default SC
  • Dynamic: PVC references storageClassName → provisioner creates PV

PV fields

FieldValues
accessModesReadWriteOnce (RWO), ReadOnlyMany (ROX), ReadWriteMany (RWX), ReadWriteOncePod (RWOP)
persistentVolumeReclaimPolicyRetain (default static), Delete, Recycle
volumeModeFilesystem (default), Block

PVC + Pod mount

# PVC
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: ""
  resources:
    requests:
      storage: 256Mi

# Pod
volumes:
- name: app-storage
  persistentVolumeClaim:
    claimName: db-pvc
volumeMounts:
- mountPath: /mnt/data
  name: app-storage

StorageClass (dynamic)

  • Defines provisioner + parameters; PV created automatically
  • PVC: storageClassName: standard
  • kubectl get storageclass: (default) marker
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd

kubectl

  • kubectl get pv,pvc / kubectl get pv -o wide (VOLUMEMODE)
  • kubectl describe pvc <n>: Used By: shows mounting Pod
  • PV/PVC: declarative only (no imperative create)

Failures

SymptomCause
PVC PendingNo StorageClass / no matching PV
Mount failWrong claimName or PVC not bound

Exam tips

  • PVC binding: access modes + capacity must match PV
  • hostPath data does not follow Pod to another node
  • StatefulSet delete → PVCs remain (data preserved)
  • ConfigMap volume: configMap.name vs Secret: secret.secretName
  • Projected: sources is a list; wrong key (source vs sources) fails validation
  • Projected downwardAPI / resourceFieldRef in sources: containerName required (same as standalone downwardAPI volume)