Handbooks / Kubernetes / Chapter 4

Storage

6 pages · ~4 min✓ Reviewed

Builds on ConfigMaps and Secrets. Next up: Scaling and Health.

KubernetesPage 1

Volumes, PersistentVolumes and Claims

1. Volumes, PV and PVC

  • Volume outlives container restarts, not the Pod
  • emptyDir: dies with the Pod
  • hostPath: node path; avoid in production
  • PV: cluster-scoped storage
  • PVC: namespaced request
  • PVC binds 1:1 to a PV matching size, accessModes, storageClassName

2. Access Modes

ModeMounts
RWO ReadWriteOnceread-write, one node
ROX ReadOnlyManyread-only, many nodes
RWX ReadWriteManyread-write, many nodes
RWOP ReadWriteOncePodone Pod only

3. Example: 1Gi Claim

  • Pod mounts the claim via claimName plus volumeMounts
yaml
kind: PersistentVolumeClaim
metadata: {name: data}
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests: {storage: 1Gi}

the claim

yaml
volumes:
- name: d
  persistentVolumeClaim:
    claimName: data
# in the container:
volumeMounts: [{name: d, mountPath: /data}]

the Pod

4. Gotchas

  • PVC Pending: no matching PV or StorageClass
  • Delete reclaimPolicy wipes data with the PVC
  • Retain: PV goes Released, no rebind until claimRef cleared
KubernetesPage 2

StorageClasses and Dynamic Provisioning

1. What a StorageClass Holds

  • PVC with storageClassName creates its PV automatically
  • Default class: annotation storageclass.kubernetes.io/is-default-class: "true"
  • storageClassName: "" turns dynamic provisioning off
yaml
kind: StorageClass
metadata: {name: fast}
provisioner: ebs.csi.aws.com
parameters: {type: gp3}
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

names a provisioner, then holds its settings

2. Binding and Provisioning

ModeBinds whenEffect
ImmediatePVC createdzone mismatch risk
WaitForFirstConsumerPod scheduledPV matches Pod's zone
StaticDynamic
PV made byAdmin, by handClass, on demand
Needs classNoYes
  • Expand: raise PVC requests.storage, never lower
  • Needs allowVolumeExpansion: true

3. Gotchas

  • Dynamic PVs default to reclaimPolicy Delete
  • storageClassName cannot change on an existing PVC
  • No default class and none named: PVC stays Pending
Remember

Class name on the PVC means dynamic. Empty string means static only.

KubernetesPage 3

StatefulSets: Stable Identity and Storage

1. Identity and Order

  • Pods named name-0 to name-N-1
  • DNS: web-0.web.<ns>.svc.cluster.local
  • Needs a headless Service (clusterIP: None) set in spec.serviceName
  • podManagementPolicy: Parallel drops the ordering
  1. Create0 to N-1
  2. TerminateN-1 to 0

2. Storage per Pod

  • volumeClaimTemplates make one PVC per Pod, e.g. data-web-0
  • The PVC reattaches to the same-named Pod after a reschedule
yaml
serviceName: web
volumeClaimTemplates:
- metadata: {name: data}
  spec:
    accessModes: [ReadWriteOnce]
    resources: {requests: {storage: 1Gi}}
DeploymentStatefulSet
Podsinterchangeableunique
Volumeone shared claimown PVC each
Fitsstateless appsdatabases, brokers

3. Gotchas

  • Scale-down or delete keeps PVCs: clean up by hand or set persistentVolumeClaimRetentionPolicy
  • Rolling updates go from the highest ordinal down
Canary

updateStrategy.rollingUpdate.partition: 2 holds back ordinals below 2 on the old revision.

KubernetesPage 4

DaemonSets, Jobs and CronJobs

1. DaemonSet

  • One Pod per matching node
  • Use for log shippers, node monitors, CNI agents
  • New node joins: Pod added automatically
  • nodeSelector limits which nodes qualify

2. Job and CronJob

  1. CronJobcron schedule
  2. Jobruns to completion
  3. Podsretried on failure
FieldSets
completionssuccesses needed
parallelismPods running at once
backoffLimitretries, default 6
restartPolicyOnFailure or Never
concurrencyPolicyAllow, Forbid or Replace
startingDeadlineSecondslimit on late starts
timeZonezone for the schedule

3. Which Controller?

NeedController
Stateless replicasDeployment
Stable identity and storageStatefulSet
One Pod per nodeDaemonSet
Run-once workJob
Scheduled workCronJob

4. Gotchas

  • Finished Jobs and Pods stay until ttlSecondsAfterFinished is set
  • DaemonSet skips tainted nodes (control plane) without tolerations
  • restartPolicy: Always is rejected for Jobs
Remember

Job Pods must end: restartPolicy is OnFailure or Never.

KubernetesPage 5

Storage and Controllers Cheat Sheet

1. Inspect and retain

bash
kubectl get pv,pvc,sc
kubectl describe pvc <name>
kubectl patch pv <name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

describe shows the Events behind a Pending claim; patch before deleting a claim you may need back

2. StatefulSet ops and one-offs

bash
kubectl get sts
kubectl scale sts <name> --replicas=N
kubectl rollout status sts/<name>
kubectl delete pvc -l app=<label>
kubectl create job <name> --image=<img> -- <cmd>
kubectl create job <name> --from=cronjob/<cron>
kubectl logs job/<name>

delete pvc removes leftover claims; --from=cronjob triggers a CronJob now

3. Quick map

SettingValues
Access modesRWO, ROX, RWX, RWOP
Binding modesImmediate, WaitForFirstConsumer
Reclaim policiesDelete, Retain
kubectl get dsper-node DaemonSet coverage
Before deleting a claim

Delete wipes the data with the PVC. Patch the PV to Retain first. Scaling a StatefulSet down keeps its PVCs.

KubernetesPage 6

Check yourself

A PVC sets storageClassName: "" and no PV matches its size. What status does it show, and why?
  • Pending
  • "" turns dynamic provisioning off, so only a hand-made matching PV can bind
A 3-replica StatefulSet with a volumeClaimTemplate is scaled to 1, then back to 3. What happens to web-2's data?
  • The PVCs survive the scale-down
  • web-2 returns and reattaches data-web-2, so the data is intact
A Job manifest sets restartPolicy: Always. What is the bug?
  • The API server rejects it
  • Jobs need OnFailure or Never; Always would restart finished Pods forever