Гид по технологиям

Постоянное хранилище в Kubernetes

7 min read Kubernetes Обновлено 05 Dec 2025
Постоянное хранилище в Kubernetes — руководство
Постоянное хранилище в Kubernetes — руководство

Логотип Kubernetes на графике

Быстрые ссылки

  • A Basic Example
  • Storage Classes
  • Access Modes
  • Conclusion

Введение

Файловые системы внутри Pod в Kubernetes по умолчанию эфемерны. Это соответствует идее «стейтлесс» контейнеров. Постоянные данные следует хранить вне контейнера — даже если они выглядят как часть локальной файловой системы контейнера. Kubernetes предоставляет абстракции для выделения и управления таким хранилищем: PersistentVolume (PV) и PersistentVolumeClaim (PVC).

Коротко о терминах (1 строка каждая):

  • PersistentVolume (PV): ресурс кластера, представляющий физический или сетевой том.
  • PersistentVolumeClaim (PVC): запрос Pod на использование PV с определёнными параметрами (ёмкость, класс, режим доступа).
  • StorageClass: шаблон политики хранения, который выбирает драйвер и параметры для динамического provision.

Важно: PV существуют независимо от Pod. PVC связывает Pod с PV. Если PVC используется, Kubernetes может создать PV, который переживёт любой отдельный Pod.

A Basic Example

Ниже — простой пример, где мы вручную создаём PersistentVolume и PersistentVolumeClaim, а затем монтируем PVC в Pod. Каждый ресурс лежит в своём manifest-файле. Применение кластера выполняется командой:

kubectl apply

Создание PersistentVolume

Пример манифеста PV (yaml):

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-volume
  namespace: pvc-demo
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data

Это создаёт том с именем my-volume, ёмкостью 2Gi, расположенный на узле по пути /mnt/data. Поскольку том создаётся вручную, мы указываем storageClassName: manual. StorageClass позволяет требовать привязки томов и PVC к одному и тому же классу.

Создание PersistentVolumeClaim

Пример PVC (yaml):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-volume-claim
  namespace: pvc-demo
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Этот PVC запрашивает 1Gi пространства в storage-классе manual. Ранее созданный PV удовлетворяет этим условиям и будет сопряжён (bound) с PVC. После создания оба ресурса покажут статус Bound.

Проверка состояния (примеры команд):

kubectl get pv my-volume
kubectl get pvc my-volume-claim

Добавление Pod

Пример Pod, который использует PVC:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: pvc-demo
spec:
  containers:
    - name: my-container
      image: my-image:latest
      volumeMounts:
        - mountPath: /path/in/container
          name: my-pod-volume
  volumes:
    - name: my-pod-volume
      persistentVolumeClaim:
        claimName: my-volume-claim

В volumes указываем ссылку на PVC по имени claimName. В volumeMounts используем совпадающее имя и указываем mountPath, куда том будет примонтирован внутри контейнера. Всё, что будет записано в /path/in/container, попадёт на том PV и сохранится при пересоздании Pod.

Storage Classes

StorageClass описывает «политику» хранилища: какой provisioner использовать, какие параметры передать и как реализовать reclaimPolicy. Для облачных сервисов Kubernetes обычно предоставляет предустановленные StorageClass, которые соответствуют блочному хранилищу платформы (например, Google Persistent Disk или аналог в DigitalOcean).

Если вы используете managed Kubernetes:

  • не нужно создавать PV вручную; создайте PVC с нужным storageClassName и размером; провайдер спровижинит том автоматически;
  • убедитесь, что storageClassName существует в кластере и соответствует ожидаемому профилю производительности и репликации.

Примеры storageClass-провиженеров (терминология и имена зависят от провайдера):

  • GKE: gcePersistentDisk
  • DigitalOcean: do-block-storage

Советы:

  • Для production указывайте storageClass явно, чтобы избежать привязки к дефолту.
  • Используйте аннотации и параметры (например, type, fsType) в StorageClass для тонкой настройки.

Режимы доступа (Access Modes)

Поддерживаемые значения для поля accessModes:

  • ReadWriteOnce — том одновременно монтируется только на один узел с правами чтения-записи.
  • ReadOnlyMany — том может монтироваться на несколько узлов, но только в режиме только для чтения.
  • ReadWriteMany — том может быть смонтирован на несколько узлов одновременно с правами чтения-записи.

Только один режим может быть «активным» для конкретного тома в момент связывания. Поэтому два PVC привяжутся к одному PV только если оба заявляют совместимый режим доступа.

Режим доступа влияет на планировщик: если нужен шардированный/реплицированный Pod на нескольких узлах с общим томом — используйте ReadWriteMany или ReadOnlyMany в зависимости от сценария.

Ограничение: не все провайдеры поддерживают ReadWriteMany. Проверьте совместимость драйвера.

Полезная памятка и чеклисты

Роль: Разработчик

  • Указывайте mountPath и проверяйте права внутри контейнера.
  • Используйте PVC в Pod-манифестах, а не напрямую PV.
  • Тестируйте recovery: удалите Pod и убедитесь, что данные сохранились.

Роль: SRE / Оператор кластера

  • Определите StorageClass с политиками Reclaim, provisioner и параметрами производительности.
  • Настройте бэкап/снапшоты для PV, если это важно.
  • Мониторьте SLI: доступность томов, latency IO, ошибки монтирования.

Роль: Админ кластера

  • Управляйте правами на создание StorageClass и PV.
  • Очистка: настройте ReclaimPolicy (Delete или Retain) в PV в зависимости от жизненного цикла данных.

Короткий SOP для добавления постоянного тома в приложение:

  1. Определить требования к объёму, IOPS, режиму доступа.
  2. Выбрать/создать StorageClass подходящего типа.
  3. Создать PVC с resources.requests.storage и storageClassName.
  4. Обновить манифест Pod/Deployment с volumeMounts и volumes на PVC.
  5. Протестировать монтирование и доступ к данным.
  6. Настроить бэкапы и политики хранения (Retention).

Точки отказа и когда это не сработает

  • Если StorageClass не поддерживает нужный accessMode, PVC не будет связан с PV.
  • Если PV размещён на конкретном узле (hostPath) и Pod запланирован на другой узел, монтирование не сработает.
  • ReadWriteOnce не подходит для масштабируемых мультиузловых приложений, требующих записи с разных узлов.

Безопасность и приватность

  • Контролируйте RBAC для создания PVC/PV/StorageClass — это снижает риск неавторизованного выделения томов.
  • Шифруйте данные на уровне облачного провайдера или в файловой системе, если требуется защита данных.
  • При обработке персональных данных убедитесь в соответствии с локальным регламентом (например, GDPR): предусмотреть шифрование, логирование доступа и политики удаления данных.

Советы по миграции и совместимости

  • При миграции между провайдерами создайте новый PVC на целевом провайдере и синхронизируйте данные через rsync/backup-restore.
  • Обратите внимание, что hostPath-тома не портируемы между узлами; используйте сетевые или блочные тома, если нужен перенос.
  • Для приложений с высоким I/O выбирайте SSD-backed StorageClass и проверьте лимиты IOPS на стороне провайдера.

Диагностика проблем (короткий чек)

  • PVC в статусе Pending: нет подходящего PV или StorageClass не поддерживает динамический provision.
  • Pod в состоянии CrashLoop при обращении к тому: проверьте права доступа и SELinux/AppArmor политики, а также owner и uid файлов на томе.
  • Ошибки монтирования: проверьте логи kubelet на узле и events в namespace.

Команды для отладки:

kubectl describe pvc my-volume-claim -n pvc-demo
kubectl describe pv my-volume
kubectl get events -n pvc-demo
journalctl -u kubelet

Факты и рекомендации

  • Типичные единицы измерения: Gi, Ti (используйте двоичные суффиксы для совместимости с Kubernetes).
  • Рекомендация: явно задавайте storageClassName в манифестах для predictability.
  • ReclaimPolicy: Delete — автоматическое удаление тома при удалении PV; Retain — сохранить данные для ручной очистки.

Примеры облачных сценариев

  • GKE: создайте PVC с storageClassName: standard (или другим существующим классом). GKE автоматически создаст и привяжет диск.
  • DigitalOcean Managed Kubernetes: используйте do-block-storage в storageClassName.

Ниже пример типичного PVC для облака (yaml):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cloud-volume-claim
  namespace: production
spec:
  storageClassName: standard
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Примеры тестов и критерии приёмки

Критерии приёмки для внедрения PVC в приложение:

  • PVC получает статус Bound в течение ожидаемого окна времени (например, минуты).
  • После перезапуска Pod данные в примонтированной директории сохраняются.
  • При масштабировании replicaSet, если требуется общий том, используются поддерживаемые accessModes.

Тесты:

  • Записать файл в монтированную папку, удалить Pod, создать Pod заново и проверить файл.
  • Создать два Pod на разных узлах с PVC, если нужен ReadWriteMany — убедиться, что запись в одном Pod видна в другом.

Мероприятия при инциденте и откат

Если PV потерял данные или PVC повредился:

  1. Остановите приложения, чтобы избежать дополнительной порчи данных.
  2. Снимите snapshot (если поддерживается) или экспортируйте доступные данные для резервного копирования.
  3. Если есть Retain-политика, вручную подключите том к тестовому узлу и оцените целостность.
  4. При необходимости восстановите данные из резервной копии и создайте новый PVC/PV.

Decision flow (выбор подхода) — Mermaid

flowchart TD
  A[Нужно ли сохранять данные после перезапуска Pod?] -->|Нет| B[Не нужен PV: используйте обычные volumes]
  A -->|Да| C[Нужно ли делиться данными между узлами?]
  C -->|Нет| D[ReadWriteOnce]
  C -->|Да, только чтение| E[ReadOnlyMany]
  C -->|Да, чтение/запись| F[ReadWriteMany]
  D --> G{Managed K8s?}
  G -->|Да| H[Создать PVC с нужным StorageClass]
  G -->|Нет| I[Создать PV + PVC вручную]
  H --> J[Примонтировать в Pod]
  I --> J

Часто задаваемые вопросы

Нужно ли создавать PersistentVolume вручную в облаке?

Нет. В большинстве управляемых кластеров достаточно создать PVC с правильным storageClassName — провайдер создаст PV автоматически.

Можно ли использовать hostPath в production?

hostPath удобен для тестирования и локальных кластеров, но в production он не портируем и привязан к конкретному узлу.

Что происходит с данными, если PVC удалён?

Поведение зависит от ReclaimPolicy PV. Если ReclaimPolicy = Delete, том и данные будут удалены; если Retain — данные сохранятся для ручной обработки.


Вывод

PersistentVolume и PersistentVolumeClaim — простая и надёжная модель для хранения постоянных данных в Kubernetes. Для управляемых кластеров обычно достаточно PVC с нужным StorageClass. Для ручного управления используйте PV + PVC. Всегда учитывайте режим доступа, совместимость провайдера и политику Reclaim для безопасности данных.

Important: всегда тестируйте сценарии восстановления и настройте резервное копирование для важных данных.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Не вставляется изображение в Paint на Windows 11
Windows

Не вставляется изображение в Paint на Windows 11

Как выключить iPhone 13
Mobile

Как выключить iPhone 13

Включение писания пальцем в Windows 11
Windows

Включение писания пальцем в Windows 11

Как обновить RAM: выбор и установка
Железо

Как обновить RAM: выбор и установка

Как запланировать SMS на Android
Android.

Как запланировать SMS на Android

Удалить или отключить Bing в Skype
Руководство

Удалить или отключить Bing в Skype