Ответ
В Kubernetes подам по умолчанию предоставляется эфемерное хранилище, которое уничтожается вместе с подом. Для сохранения данных (логи, состояние БД, загруженные файлы) используются PersistentVolumes (PV) и PersistentVolumeClaims (PVC). Это одна из ключевых концепций для stateful-приложений в K8s.
Основная абстракция: PV и PVC
- PersistentVolume (PV) — это ресурс кластера, кусок предварительно подготовленного хранилища (например, диск в облаке, NFS-шара, локальный SSD). Администратор кластера создаёт PV.
- PersistentVolumeClaim (PVC) — это запрос пользователя (пода) на хранилище определённого размера и с определёнными правами доступа. Поды используют PVC.
Статическое выделение (Static Provisioning)
Администратор вручную создаёт PV, а затем пользователь создаёт PVC, который привязывается к подходящему PV.
1. Создание PersistentVolume (например, на основе NFS):
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-data-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany # Могут писать многие поды (подходит для NFS)
persistentVolumeReclaimPolicy: Retain # Что делать с данными после удаления PVC: Retain, Delete, Recycle
nfs:
server: 10.0.1.100
path: "/exports/app_data"
2. Создание PersistentVolumeClaim:
# app-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # Запрашиваем 5Gi. Будет привязан к PV с >=5Gi (наш 10Gi PV подходит).
# storageClassName: "" # Для использования статического PV оставляем пустым или не указываем.
3. Использование PVC в поде:
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: nginx:alpine
volumeMounts:
- name: storage-volume
mountPath: "/usr/share/nginx/html" # Куда в контейнере монтируется том
volumes:
- name: storage-volume
persistentVolumeClaim:
claimName: app-data-pvc # Ссылаемся на созданный PVC
Динамическое выделение (Dynamic Provisioning) — стандартный подход
Администратор создаёт StorageClass, описывающий «тип» хранилища (например, fast-ssd в Google Cloud). При создании PVC, ссылающейся на этот StorageClass, система автоматически создаёт PV нужного типа.
1. StorageClass (пример для AWS EBS):
# storageclass-gp3.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com # CSI-драйвер для AWS EBS
parameters:
type: gp3
fsType: ext4
volumeBindingMode: WaitForFirstConsumer # Диск создастся только при запуске пода (учитывает zone)
reclaimPolicy: Delete
2. PVC, использующий StorageClass:
# dynamic-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-app-pvc
spec:
accessModes:
- ReadWriteOnce # Только один под может монтировать том на запись (стандартно для облачных дисков)
storageClassName: gp3 # Указываем класс хранилища
resources:
requests:
storage: 20Gi
После применения этого манифеста Kubernetes автоматически создаст EBS-диск объемом 20Gi типа gp3 в той же зоне доступности, что и под, и привяжет его.
Практические рекомендации:
- Для stateful-приложений (базы данных) используйте StatefulSet вместе с динамическим выделением через StorageClass. StatefulSet обеспечивает стабильные сетевые идентификаторы и упорядоченное развёртывание.
- Выбирайте правильный
accessMode:ReadWriteOnce(RWO) для БД,ReadWriteMany(RWX) для общих файловых хранилищ (NFS, CephFS). - Мониторьте использование хранилища с помощью
kubectl top pod(если установлен metrics-server) и дашбордов в Prometheus/Grafana.