← К программе курса

Модуль 7 / 19

Storage: Volume, PV, PVC, StorageClass и CSI

KUBERNETES

Содержание
01

1. Цели модуля

После модуля вы сможете различать ephemeral и persistent volumes, объяснить связь StorageClass, PV и PVC, выбрать access mode и reclaim policy, подтвердить сохранность данных и диагностировать Pending PVC.

  • жизненный цикл PV/PVC
  • static и dynamic provisioning
  • binding и topology
  • безопасное удаление данных
02

2. Теория: Volume и жизненный цикл данных

Writable layer контейнера исчезает вместе с контейнером и не подходит для состояния. emptyDir принадлежит Pod: переживает перезапуск контейнера, но удаляется вместе с Pod. PersistentVolume отделяет жизненный цикл storage от Pod.

Приложение монтирует PVC, а не конкретный диск. Это сохраняет абстракцию между потребителем и реализацией storage. Snapshot, backup, replication и disaster recovery не возникают автоматически только из-за использования PVC.

03

3. Теория: StorageClass, PV и PVC

PersistentVolume — cluster-scoped представление storage. PersistentVolumeClaim — namespaced запрос на capacity, access mode и StorageClass. Binding связывает PVC с совместимым PV один к одному.

При dynamic provisioning CSI provisioner создаёт PV по StorageClass. volumeBindingMode WaitForFirstConsumer откладывает provisioning и binding до появления Pod, чтобы учитывать topology выбранного Node. Без подходящего provisioner или PV claim остаётся Pending.

04

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 выберите policy осознанно и проверьте backup/restore.

05

5. Методические указания

  • Начинайте с PVC status и Events, затем проверяйте StorageClass и PV
  • Сопоставляйте capacity, accessModes, storageClassName, volumeMode и topology
  • Не уменьшайте PVC: стандартное expansion поддерживает только увеличение и зависит от StorageClass
  • Не удаляйте PVC до проверки reclaim policy и резервной копии
  • hostPath допустим только для этой kind-лаборатории, не как production storage
  • Проверяйте восстановление данных, а не только статус Bound
06

6. Лабораторная работа: PV, PVC и writer

Лаборатория ожидает kind-кластер course из модуля 1 с Node course-worker. Сохраните манифест как storage-lab.yaml. hostPath используется только для демонстрации статического binding.

terminal
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-data
07

7. Лабораторная работа: проверяем сохранность

Сохраните второй манифест как storage-reader.yaml. Запишите данные, удалите writer Pod, создайте reader Pod с тем же PVC и прочитайте файл.

terminal
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-data
terminal
kubectl 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.

08

8. Диагностика: Pending PVC

Сохраните манифест как storage-pending.yaml. Несуществующий StorageClass не имеет provisioner, поэтому PVC останется Pending, а Pod — Pending из-за unbound claim.

terminal
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-data
terminal
kubectl 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 не может быть удовлетворён.

09

9. Контроль и шпаргалка

  • Что переживает restart контейнера, удаление Pod и удаление PVC?
  • Почему RWO не означает один Pod?
  • Зачем WaitForFirstConsumer знает о scheduling?
  • Чем Retain отличается от backup?
  • Почему Bound ещё не доказывает работоспособность приложения?

Модуль освоен, если вы связываете PodPVCPVStorageClass, доказываете сохранность данных после замены Pod и объясняете Pending claim по Events и параметрам binding.

PDF для работы офлайн

Скачайте оформленную версию модуля для чтения без подключения к сети.

Скачать PDFPDF