По умолчанию данные внутри контейнера исчезают вместе с его смертью. Kubernetes предлагает несколько уровней абстракции для хранения данных — от временных до постоянных.
Проблема: Pod умер → данные потеряны
Файловая система контейнера эфемерна. Если Pod перезапустился — база данных пуста, загруженные файлы исчезли, логи пропали. Для stateful-приложений это неприемлемо.
Решение — Volumes: внешнее хранилище, которое живёт дольше пода.
emptyDir: временное хранилище
Создаётся вместе с Pod, уничтожается вместе с Pod. Полезен для временных файлов и обмена данными между контейнерами в одном Pod.
apiVersion: v1
kind: Pod
metadata:
name: app-with-temp-storage
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: temp-data
mountPath: /tmp/cache
- name: sidecar
image: busybox
volumeMounts:
- name: temp-data
mountPath: /shared
volumes:
- name: temp-data
emptyDir: {}
Оба контейнера видят одни и те же файлы. Данные живут пока жив Pod.
hostPath: монтирование директории с узла
Монтирует директорию с хост-машины (Worker Node) в Pod. Данные переживают перезапуск пода, но привязаны к конкретному узлу.
volumes:
- name: host-logs
hostPath:
path: /var/log/myapp
type: DirectoryOrCreate
Использование: доступ к устройствам хоста, специфические dev-сценарии. В production не рекомендуется — Pod привязан к узлу.
PersistentVolume и PersistentVolumeClaim
Полноценное постоянное хранилище. Состоит из двух объектов:
- PersistentVolume (PV) — реальный ресурс хранения. Создаётся администратором или автоматически (StorageClass). Описывает ёмкость, тип, параметры доступа.
- PersistentVolumeClaim (PVC) — запрос на хранилище от приложения. Разработчик описывает, сколько места и какой тип нужен. K8s найдёт подходящий PV.
# persistent-volume.yaml (обычно создаёт администратор)
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce # один Pod в режиме чтение/запись
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
hostPath:
path: /data/postgres # для minikube/dev; в prod — NFS, cloud disk, etc.
# persistent-volume-claim.yaml (создаёт разработчик)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi
# Использование PVC в Pod/Deployment
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
kubectl apply -f persistent-volume.yaml
kubectl apply -f persistent-volume-claim.yaml
kubectl get pv
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS STORAGECLASS
# postgres-pv 10Gi RWO Retain Bound standard
kubectl get pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
# postgres-pvc Bound postgres-pv 10Gi RWO standard
Режимы доступа (AccessModes)
| Режим | Описание |
|---|---|
| ReadWriteOnce (RWO) | Один узел, чтение+запись |
| ReadOnlyMany (ROX) | Много узлов, только чтение |
| ReadWriteMany (RWX) | Много узлов, чтение+запись (NFS, CephFS) |
StorageClass: динамический provisioning
Вручную создавать PV для каждого PVC — неудобно. StorageClass автоматизирует создание хранилища.
# storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iopsPerGB: "10"
encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
Теперь PVC с storageClassName: fast-ssd автоматически создаст EBS-диск в AWS:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 20Gi
# Доступные StorageClass в кластере
kubectl get storageclass
# NAME PROVISIONER AGE
# standard (default) docker.io/hostpath 10d
# fast-ssd kubernetes.io/aws-ebs 5d
StatefulSet для stateful-приложений
Обычный Deployment не подходит для баз данных: поды взаимозаменяемы, не имеют стабильных имён и отдельных PVC.
StatefulSet решает это:
- Стабильные имена подов:
postgres-0,postgres-1,postgres-2 - Гарантированный порядок запуска и остановки
- Каждый Pod получает собственный PVC (VolumeClaimTemplate)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
Каждый из трёх подов получит свой PVC: data-postgres-0, data-postgres-1, data-postgres-2. При удалении пода PVC сохраняется — данные не теряются.
kubectl get statefulset
# NAME READY AGE
# postgres 3/3 5m
kubectl get pvc
# NAME STATUS VOLUME CAPACITY
# data-postgres-0 Bound pvc-abc... 10Gi
# data-postgres-1 Bound pvc-def... 10Gi
# data-postgres-2 Bound pvc-ghi... 10Gi
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!