Модуль 7 / 19
Storage: Volume, PV, PVC, StorageClass і CSI
Зміст
1. Цілі модуля
Після модуля ви зможете розрізняти ephemeral і persistent volumes, пояснити зв’язок StorageClass, PV та PVC, обрати access mode і reclaim policy, підтвердити збереження даних та діагностувати Pending PVC.
- життєвий цикл PV/PVC
- static і dynamic provisioning
- binding і topology
- безпечне видалення даних
2. Теорія: Volume і життєвий цикл даних
Writable layer контейнера зникає разом із контейнером і не підходить для стану. emptyDir належить Pod: переживає перезапуск контейнера, але видаляється разом із Pod. PersistentVolume відокремлює життєвий цикл storage від Pod.
Застосунок монтує PVC, а не конкретний диск. Snapshot, backup, replication та disaster recovery не виникають автоматично лише через використання PVC.
3. Теорія: StorageClass, PV і PVC
PersistentVolume — cluster-scoped представлення storage. PersistentVolumeClaim — namespaced запит на capacity, access mode і StorageClass. Binding пов’язує PVC із сумісним PV один до одного.
Під час dynamic provisioning CSI provisioner створює PV за StorageClass. WaitForFirstConsumer відкладає provisioning і binding до появи Pod, щоб урахувати topology Node. Без відповідного provisioner або PV claim залишається Pending.
4. Теорія: access modes і reclaim policy
ReadWriteOnce допускає read-write mount з одного Node і не означає строго один Pod. ReadWriteMany залежить від driver. ReadOnlyMany описує capability. ReadWriteOncePod обмежує volume одним Pod і підтримується CSI-драйверами.
Access modes використовуються для matching і не є файловими ACL або гарантією read-only після mount. Реальну поведінку задають driver, mount flags та застосунок.
ReclaimPolicy Delete видаляє storage asset після claim, якщо driver це підтримує. Retain зберігає PV і дані для ручного відновлення. Перед production перевірте backup/restore.
5. Методичні вказівки
- Починайте з PVC status та Events, потім перевіряйте StorageClass і PV
- Зіставляйте capacity, accessModes, storageClassName, volumeMode та topology
- Не зменшуйте PVC: expansion підтримує лише збільшення й залежить від StorageClass
- Не видаляйте PVC до перевірки reclaim policy та резервної копії
- hostPath допустимий лише для цієї kind-лабораторії, не для production
- Перевіряйте відновлення даних, а не лише статус Bound
6. Лабораторна робота: PV, PVC і writer
Лабораторія очікує kind-кластер course з модуля 1 та Node course-worker. Збережіть маніфест як storage-lab.yaml. hostPath використано лише для демонстрації static binding.
apiVersion: v1
kind: Namespace
metadata:
name: lab-storage
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: lab-storage-pv
spec:
capacity:
storage: 64Mi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual-lab
hostPath:
path: /var/local/course-data
type: DirectoryOrCreate
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
namespace: lab-storage
spec:
storageClassName: manual-lab
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 64Mi
---
apiVersion: v1
kind: Pod
metadata:
name: writer
namespace: lab-storage
spec:
nodeSelector:
kubernetes.io/hostname: course-worker
containers:
- name: app
image: busybox:1.37.0
command: ["sh", "-c", "printf 'persistent-data\n' > /data/message; sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: app-data7. Лабораторна робота: перевіряємо збереження
Збережіть другий маніфест як storage-reader.yaml. Запишіть дані, видаліть writer Pod, створіть reader Pod з тим самим PVC і прочитайте файл.
apiVersion: v1
kind: Pod
metadata:
name: reader
namespace: lab-storage
spec:
nodeSelector:
kubernetes.io/hostname: course-worker
containers:
- name: app
image: busybox:1.37.0
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
readOnly: true
volumes:
- name: data
persistentVolumeClaim:
claimName: app-datakubectl apply -f storage-lab.yaml
kubectl get storageclass
kubectl get persistentvolume lab-storage-pv
kubectl get persistentvolumeclaim app-data -n lab-storage
kubectl wait -n lab-storage --for=condition=Ready pod/writer --timeout=120s
kubectl exec -n lab-storage writer -- cat /data/message
kubectl delete pod writer -n lab-storage --wait=true
kubectl apply -f storage-reader.yaml
kubectl wait -n lab-storage --for=condition=Ready pod/reader --timeout=120s
kubectl exec -n lab-storage reader -- cat /data/message
kubectl get pv,pvc -AКритерій: PVC має Bound, обидва Pod послідовно працюють на course-worker, reader після видалення writer повертає persistent-data, PV досі пов’язаний із claim.
8. Діагностика: Pending PVC
Збережіть маніфест як storage-pending.yaml. Неіснуючий StorageClass не має provisioner, тому PVC залишиться Pending, а Pod — Pending через unbound claim.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pending-data
namespace: lab-storage
spec:
storageClassName: missing-provisioner
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: blocked
namespace: lab-storage
spec:
containers:
- name: app
image: busybox:1.37.0
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pending-datakubectl apply -f storage-pending.yaml
kubectl get pvc,pod -n lab-storage
kubectl describe pvc pending-data -n lab-storage
kubectl describe pod blocked -n lab-storage
kubectl events -n lab-storage --types=Warning
kubectl get storageclass
kubectl get pv
kubectl delete pod blocked -n lab-storage
kubectl delete pvc pending-data -n lab-storage
kubectl delete namespace lab-storage
kubectl get pv lab-storage-pv
kubectl delete pv lab-storage-pvАлгоритм: PVC Events → StorageClass і provisioner → доступні PV → розмір та access modes → topology → Pod scheduling Events. Не виправляйте Pod, доки storage request неможливо задовольнити.
9. Контроль і шпаргалка
- Що переживає restart контейнера, видалення Pod і видалення PVC?
- Чому RWO не означає один Pod?
- Навіщо WaitForFirstConsumer знає про scheduling?
- Чим Retain відрізняється від backup?
- Чому Bound ще не доводить працездатність застосунку?
Модуль засвоєно, якщо ви пов’язуєте Pod → PVC → PV → StorageClass, доводите збереження даних після заміни Pod і пояснюєте Pending claim за Events та параметрами binding.
PDF для роботи офлайн
Завантажте оформлену версію модуля для читання без підключення до мережі.