Как организовать работу с persistent storage в Kubernetes?

Краткая архитектура решения

Persistent storage в Kubernetes строится вокруг трёх основных сущностей: PersistentVolume (PV) — реальный ресурс хранения в кластере, PersistentVolumeClaim (PVC) — заявка приложения на хранилище, и StorageClass — шаблон/политика для динамического создания PV (provisioner). Современная интеграция реализуется через CSI-драйверы.

Основные понятия и режимы доступа

  • PersistentVolume (PV) — объект, описывающий диск/шар/ресурс (путь на ноде, облачный диск, NFS, Ceph и т.д.).

  • PersistentVolumeClaim (PVC) — запрос от Pod: размер, AccessModes (ReadWriteOnce, ReadOnlyMany, ReadWriteMany) и StorageClass. PVC привязывается (bind) к PV.

  • StorageClass — параметры динамического Provisioning (driver, параметры, reclaimPolicy, volumeBindingMode).

  • AccessModes:

    • ReadWriteOnce (RWO) — запись с одного узла;

    • ReadOnlyMany (ROX) — чтение с многих;

    • ReadWriteMany (RWX) — чтение/запись с многих (требует сетевого файлового решения).

  • ReclaimPolicy: Delete (удалить физически), Retain (сохранить данные) — важно для стратегии удаления приложений.

Как организовать — шаги и шаблоны

  1. Выбрать/установить CSI-драйвер для вашего окружения (облако, on-prem).

  2. Создать StorageClass с нужными параметрами (iops/throughput, encryption, zone/topology). Рекомендуется volumeBindingMode: WaitForFirstConsumer для кластера с несколькими зонами.

  3. Использовать PVC в приложениях (в Pod/Deployment/StatefulSet) вместо hostPath. Пример PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: data-claim }
spec:
accessModes: \[ "ReadWriteOnce" \]
resources: { requests: { storage: 10Gi } }
storageClassName: fast-storage
  1. Для stateful-приложений используйте StatefulSet + volumeClaimTemplates — каждому поду создастся свой PVC, привязанный к ordinal (web-0, web-1 и т.д.).

  2. Динамическое vs статическое: динамическое (PVC→StorageClass→PV автоматически) — обычно предпочтительнее. Статическое (админ создаёт PV вручную) — только при специальных требованиях.

Бэкап, снапшоты и миграция

  • Используйте VolumeSnapshots (CSI snapshotter) для быстрых снимков и восстановления.

  • Для полного восстановления/миграции применяйте snapshot → создать новый PV/PVC → восстановить данные, либо внешние backup-решения (операторы backup/restore). Регулярно тестируйте процедуры восстановления.

Масштабирование, расширение и ограничения

  • PVC можно увеличить, если StorageClass поддерживает allowVolumeExpansion. Процесс: изменить spec.resources.requests.storage — kube-controller/kubelet и CSI расширят volume и (при поддержке) файловую систему.

  • Учтите volumeMode: Filesystem vs Block (raw блоковый диск).

  • Для RWX нужен сетевой файловый бекенд (NFS, CephFS, Gluster, CSI с поддержкой RWX).

Операция и команды

  • kubectl get pv, kubectl get pvc -A, kubectl get sc — статус.

  • kubectl describe pvc <name> — события, bind-статус, ошибки.

  • kubectl patch pvc <pvc> -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}' — увеличить PVC (если поддерживается).

  • kubectl get volumesnapshot / kubectl describe volumesnapshot — при наличии CRD snapshot.

Безопасность и лучшие практики

  • Не храните секреты в диск-параметрах без шифрования; используйте шифрование на уровне хранилища.

  • Ограничьте создание PV/PVC через RBAC и StorageClass с контролируемыми параметрами.

  • Для логов предпочитайте stdout/stderr + централизованный лог-агрегатор, а не монолитные диски.

  • Планируйте IOPS/throughput, учитывайте требования к латентности и выбирайте подходящий storage (SSD/IOPS-tier).

  • Всегда тестируйте восстановление из снапшота и операции увеличения.

Подводные камни

  • hostPath и локальные PV привязывают Pod к ноде — плохо для переносимости.

  • Неправильный AccessMode (например ожидание RWX при RWO только) приводит к Pending.

  • Некорректные readiness/liveness и использование maxSurge вместе с RWO томами могут вызвать ошибки при RollingUpdate — для stateful-хранилищ используйте StatefulSet или maxSurge: 0.

Закладывайте дизайн хранения в архитектуру приложения: какие данные критичны, нужны ли per-pod PV, какой уровень доступности и RPO/RTO, и автоматизируйте создание PVC через манифесты или Helm-чарты.