CFN Cloud
Cloud Future New Life
en zh
2025-10-08 · 0 views

Volume Basics

Learn how Pods share and persist data with volumes.

Containers are ephemeral. Volumes provide data sharing and persistence so that Pods can keep state, exchange files between containers, and mount configuration safely.

This quick start expands on the basics with practical examples and selection guidance that map to real workloads.

Why volumes matter

  • Containers restart frequently, but data often must survive.
  • Multiple containers in one Pod need a shared filesystem.
  • Configuration and secrets should be mounted, not baked into images.
  • Storage choices affect performance and reliability.

Common volume types

  • emptyDir: temporary storage that lives for the Pod lifetime.
  • configMap / secret: configuration injection as files.
  • persistentVolumeClaim (PVC): durable storage provisioned by a StorageClass.
  • hostPath: mounts a host directory (use with care, not portable).

emptyDir example

emptyDir is great for caches and scratch space:

volumes:
  - name: cache
    emptyDir: {}
volumeMounts:
  - name: cache
    mountPath: /cache

You can size it with emptyDir.sizeLimit and use medium: Memory for tmpfs if you want fast memory-backed storage.

ConfigMap and Secret mounts

Mount configuration files into a container:

volumes:
  - name: app-config
    configMap:
      name: app-config
  - name: app-secret
    secret:
      secretName: app-secret
volumeMounts:
  - name: app-config
    mountPath: /etc/app/config
    readOnly: true
  - name: app-secret
    mountPath: /etc/app/secret
    readOnly: true

Keep secrets read-only and avoid putting them in environment variables unless necessary.

PVC basics

PVCs request storage from a StorageClass and bind to a PersistentVolume:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

Mount the PVC in your Pod:

volumes:
  - name: data
    persistentVolumeClaim:
      claimName: data-pvc
volumeMounts:
  - name: data
    mountPath: /var/lib/app

StorageClass selection

If your cluster has multiple StorageClasses, pick the right one. A fast SSD class is good for databases, while a cheaper class can serve logs or caches. Check what is available:

kubectl get storageclass

You can set a default StorageClass or request a specific class in your PVC:

storageClassName: fast-ssd

Access modes and usage

  • ReadWriteOnce is most common for databases.
  • ReadWriteMany is required for shared filesystems.
  • ReadOnlyMany is useful for distributing data without writes.

Match access modes to your workload and storage backend.

Example: shared volume for multiple containers

If your Pod has a sidecar that needs to read files produced by the main container, mount the same volume into both containers:

apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  volumes:
  - name: shared
    emptyDir: {}
  containers:
  - name: producer
    image: busybox
    command: ["sh", "-c", "while true; do date >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: shared
      mountPath: /data
  - name: consumer
    image: busybox
    command: ["sh", "-c", "tail -f /data/out.txt"]
    volumeMounts:
    - name: shared
      mountPath: /data

This pattern is useful for log shipping, content generation, or preprocessing pipelines.

Stateful workloads

Databases and queues usually require PVCs and a stable identity. In Kubernetes, StatefulSets provide stable network names and storage claims for each replica. If you are using a Deployment for stateful apps, you are likely to hit data corruption or scheduling problems.

Example: StatefulSet volume claim template

StatefulSets can create a PVC per replica automatically:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis
  replicas: 2
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 5Gi

Each replica gets its own PVC (for example, data-redis-0, data-redis-1).

Lifecycle and cleanup

PVCs are not deleted when a Pod is removed. This protects data, but it also means you can leak storage if you forget to clean up old claims. If you want PVCs removed automatically, configure the StorageClass reclaim policy or delete PVCs manually after you tear down a workload.

Be careful with reclaim policies. Retain keeps data around for recovery, while Delete removes the underlying volume automatically. Pick based on how critical the data is.

Backup and migration considerations

Volumes are not backups. If a node fails or data is corrupted, you need a separate backup strategy. For quick tests, a snapshot or a logical dump is enough. For production, define backup retention, verify restores, and store backups outside the cluster.

When migrating between storage classes, create a new PVC, copy data with a helper Pod, and then update your workload to mount the new claim. This reduces downtime and makes rollback simpler.

You can do the copy with a simple rsync Pod that mounts both the old and new PVCs, then switch the workload once data is in sync.

Practical selection tips

  • Use emptyDir for caches and build artifacts.
  • Use PVCs for databases and any persistent state.
  • Avoid hostPath unless you control the node and accept portability limits.
  • Mount configs and secrets as files whenever possible.
  • Prefer stable volume names so application code and runbooks stay consistent.

Security considerations

Mounting a volume into a container means that data is shared at the filesystem level. Use read-only mounts for config and secrets, and limit write access to the minimum necessary path. If you use hostPath, remember it exposes node files directly to the container, which can be a major security risk.

If you run multi-tenant clusters, combine volume policies with PodSecurity and RBAC to avoid unintended access to shared storage.

Encryption at rest depends on your storage provider; enable it when handling sensitive data. For configs and secrets, use rotation and keep old values out of images.

Troubleshooting

  • Pod stuck in Pending: PVC not bound or StorageClass missing.
  • Mount errors: check node permissions and CSI driver logs.
  • Data loss: verify reclaim policy and Pod eviction behavior.
  • Permission denied: ensure the container user matches the volume filesystem permissions.
  • Volume full: increase PVC size if the StorageClass allows expansion.

Diagnostic commands:

kubectl describe pod <pod-name>
kubectl describe pvc <pvc-name>
kubectl get pv

For deeper storage issues, check the CSI controller logs in the kube-system namespace. Many mount failures surface there before they appear in Pod events.

If your storage class supports expansion, you can grow a PVC by updating its spec.resources.requests.storage and watching the resize events.

Performance tuning tips

If IO latency is high, check the underlying storage class and node disk. For small lab clusters, local-path storage is often slower under load. In cloud environments, pick SSD-backed classes for databases and tune volume sizes based on expected write throughput.

You can also benchmark with a simple temporary Pod (for example, running fio) to understand baseline latency before putting production data on the volume.

Avoid placing latency-sensitive databases on the same node as CPU-heavy batch workloads. Resource contention is one of the most common causes of noisy volume performance.

Practical notes

  • Start with a quick inventory: kubectl get nodes, kubectl get pods -A, and kubectl get events -A.
  • Compare desired vs. observed state; kubectl describe usually explains drift or failed controllers.
  • Keep names, labels, and selectors consistent so Services and controllers can find Pods.

Quick checklist

  • The resource matches the intent you described in YAML.
  • Namespaces, RBAC, and images are correct for the target environment.
  • Health checks and logs are in place before promotion.

References