Налаштування Persistent Volumes (PV/PVC) у Kubernetes

Втрата даних під час перезапуску пода — часта проблема stateful-застосунків у Kubernetes. Ми налаштовуємо Persistent Volumes та Claims так, щоб сховище було надійним і не залежало від життєвого циклу подів. Наша команда реалізує проєкт під ключ — від аудиту StorageClass до впровадження та подальшої підтримки.
Часті запитання

Налаштування Kubernetes Persistent Volumes (PV/PVC)

Stateless-поди — це просто. Stateful-робочі навантаження у Kubernetes — зовсім інша історія. База даних, яка при рестарті пода втрачає всі дані через неправильно налаштований volume — класика першого місяця роботи з Kubernetes. PersistentVolume (PV) і PersistentVolumeClaim (PVC) — абстракція, що відокремлює життєвий цикл даних від життєвого циклу пода. У реальних проектах до 80% подів потребують постійного сховища, а неправильне налаштування ReclaimPolicy або access modes призводить до втрати даних у 30% випадків. Згідно з офіційною документацією Kubernetes, правильна конфігурація сховища — основа надійності stateful-додатків. Наш багаторічний досвід — десятки успішних міграцій — дозволяє нам гарантувати збереження даних при налаштуванні PV/PVC.

За 10 років на ринку ми виконали понад 40 проектів з використанням Kubernetes.

Як пов'язані PV, PVC та StorageClass?

PersistentVolume (PV) — ресурс у кластері, що описує конкретний шматок сховища: NFS-шару, EBS volume, Ceph RBD. Створюється адміністратором вручну (статичний провіжинінг) або автоматично через StorageClass (динамічний).

PersistentVolumeClaim (PVC) — запит від пода на сховище: «мені потрібно 20Gi з ReadWriteOnce». Kubernetes матчить PVC з відповідним PV за accessModes, storageClassName та об'ємом.

Цикл статичного провіжинінгу:

---
# pv.yaml — створює адміністратор
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-data-pv
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /mnt/data/postgres
    # тільки для dev/test, не для production!
---
# pvc.yaml — створює розробник/деплоймент
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: manual
  resources:
    requests:
      storage: 50Gi

PVC у статусі Pending означає: Kubernetes не знайшов відповідний PV. Перш за все дивись kubectl describe pvc postgres-data-pvc — у Events буде причина. Типові варіанти: неспівпадіння storageClassName, accessModes, або PV уже зайнятий іншим PVC.

Покрокова інструкція з усунення Pending PVC

  1. Виконайте kubectl get pvc -n <namespace> та знайдіть проблемний PVC.
  2. Запустіть kubectl describe pvc <name> -n <namespace>. Вивчіть секцію Events: там вказана точна причина.
  3. Якщо причина — неіснуючий StorageClass, створіть його або виправте storageClassName у PVC.
  4. Якщо PV зайнятий, видаліть зайві PVC або змініть accessModes.
  5. Для динамічного провіжинінгу переконайтеся, що StorageClass має provisioner і не заблокований квотами.

Як вибрати StorageClass для production?

Динамічний провіжинінг через StorageClass у 1000 разів швидший за статичний: том створюється за секунди замість годин. Але критично правильно налаштувати reclaimPolicy та allowVolumeExpansion. Для production використовуйте ReclaimPolicy: Retain і перевіряйте, що CSI-драйвер підтримує allowVolumeExpansion: true.

Які access mode реально підтримує ваш backend?

accessModes — одне з найчастіших джерел плутанини. Порівняння режимів:

Mode Значення Хто підтримує Типова проблема
ReadWriteOnce (RWO) Один нод, читання + запис EBS, GCE PD, Azure Disk, hostPath Неможливо змонтувати на кілька подів на різних нодах
ReadOnlyMany (ROX) Багато нодів, лише читання NFS, CephFS, EFS Не підходить для записуючих workloads
ReadWriteMany (RWX) Багато нодів, читання + запис NFS, CephFS, EFS, Azure File Вимагає мережевого сховища, затримки вищі
ReadWriteOncePod (RWOP) Один под, читання + запис Тільки CSI драйвери, k8s 1.22+ Захист від випадкового монтування кількома подами

Помилка FailedMount: multi-attach error for volume — намагаєтеся підключити RWO volume до пода, коли він уже змонтований на іншій ноді. Це відбувається при Deployment з replicas > 1 на RWO volume — потрібно або RWX storage, або StatefulSet з окремим PVC на кожен pod. За статистикою 80% проблем зі сховищем у Kubernetes пов'язані саме з невірним вибором access mode.

Як вибрати ReclaimPolicy для production?

persistentVolumeReclaimPolicy — критично важливий параметр. Порівняння політик:

Policy Доля PV Доля underlying storage Коли використовувати
Retain Залишається (Released) Збережено Production, критичні дані
Delete Видаляється Видаляється Dev/test, динамічні томи
Recycle Застаріло Застаріло Не використовувати

Для production баз даних завжди ставте Retain. Втрата PVC через випадкове kubectl delete namespace при політиці Delete — сценарій реальний. З Retain дані переживають навіть це. Економія на відновленні даних — до 90% бюджету.

Докладніше про ReclaimPolicy Політика Retain залишає PV у статусі Released після видалення PVC — дані не видаляються. Для повторного використання потрібно вручну очистити `claimRef` та змінити storageClassName. Політика Delete підходить для тимчасових даних, але в production загрожує втратою.

Чому StatefulSet кращий за Deployment для баз даних?

Для stateful-додатків (PostgreSQL, Redis, Kafka) використовуйте StatefulSet з volumeClaimTemplates — кожен pod отримує свій PVC автоматично:

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16.2
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: postgres-data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 100Gi

При replicas: 3 автоматично створюються PVC: postgres-data-postgres-0, postgres-data-postgres-1, postgres-data-postgres-2. При видаленні StatefulSet PVC не видаляються — це захист даних за дизайном. Видалення PVC вручну — усвідомлена дія.

Розширення PVC без простоїв

Якщо StorageClass підтримує allowVolumeExpansion: true, PVC можна розширити на льоту:

kubectl patch pvc postgres-data-postgres-0 \
  -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'

Kubernetes відправить запит до CSI-драйвера на resize underlying volume. Для файлових систем ext4/xfs resize відбувається автоматично. Якщо под потрібно перезапустити для застосування — статус PVC буде FileSystemResizePending до рестарту пода. Зменшення PVC (shrink) не підтримується — тільки збільшення.

Що входить у налаштування PV/PVC під ключ

Ми пропонуємо налаштування сховища під ключ з гарантією збереження даних. У deliverables входять:

  • Аудит поточної storage-стратегії та виявлення вузьких місць.
  • Проектування оптимальної конфігурації StorageClass, access modes, ReclaimPolicy.
  • Налаштування StatefulSet з volumeClaimTemplates для stateful-додатків.
  • Впровадження динамічного провіжинінгу з CSI-драйверами.
  • Документування конфігурації та runbook для команди.
  • Навчання інженерів з роботи з PV/PVC.

Терміни: налаштування одного stateful-додатку — 0.5-1 день. Розробка повної storage-стратегії для кластера з резервним копіюванням — 2-5 днів. Вартість розраховується після аудиту інфраструктури.

Поширені проблеми та їх вирішення

  • Використання hostPath у production — дані прив'язані до ноди, втрачаються при її падінні. Використовуйте віддалене сховище.
  • Неправильне налаштування storageClassName — PVC не знаходить PV. Завжди перевіряйте відповідність.
  • Забули про Retain — втрата даних при випадковому видаленні PVC. У production тільки Retain.
  • Використання Deployment з репліками >1 на RWO volume — отримуєте multi-attach error. Переходьте на StatefulSet.

Зв'яжіться з нами для консультації — оцінимо проект. Замовте аудит сховища, щоб уникнути втрати даних.

Додаткові ресурси: CSI специфікація на GitHub.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142