emptyDir, временное хранилище на жизнь пода:
Самый простой volume. Создается пустым при старте пода, удаляется вместе с ним. Важный нюанс: перезапуск контейнера внутри пода (упал процесс, kubelet его поднял) данные в emptyDir не трогает. А вот удаление пода стирает все.
Код: Выделить всё
apiVersion: v1
kind: Pod
metadata:
name: cache-demo
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: cache
mountPath: /var/cache/app
volumes:
- name: cache
emptyDir:
sizeLimit: 500MiPersistentVolume и PersistentVolumeClaim:
Идея в разделении ролей. PersistentVolume (PV) это кусок реального хранилища: облачный диск, NFS-шара, локальный каталог на ноде. PersistentVolumeClaim (PVC) это заявка приложения: нужно 5Gi с таким-то режимом доступа. Kubernetes сам связывает заявку с подходящим томом, разработчику не нужно знать, где физически лежат данные.
Руками PV сейчас почти не создают. Работает динамический provisioning через StorageClass: появился PVC, провижинер сам создал под него диск. В minikube и kind из коробки есть класс с именем standard, он же дефолтный. Проверить:
Код: Выделить всё
kubectl get storageclassКод: Выделить всё
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pg-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5GiПодключаем к постгресу через Deployment из главы 4:
Код: Выделить всё
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
strategy:
type: Recreate
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
envFrom:
- secretRef:
name: pg-secret
env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: pg-dataКод: Выделить всё
kubectl get pvc pg-data
kubectl get pvОтдельно про reclaimPolicy у PV. Delete (дефолт для динамически созданных томов) удаляет диск вместе с данными при удалении PVC. Retain оставляет том, данные можно вытащить. В managed-кластерах Yandex Cloud, VK Cloud или Selectel дефолт обычно Delete, проверьте это до того, как удалите PVC боевой базы.
Типичные грабли:
PVC висит в Pending. Чаще всего нет дефолтного StorageClass или в заявке опечатка в имени класса. describe покажет событие с текстом про provisioner.
Запросили ReadWriteMany на блочном хранилище. Облачные диски дают только RWO, RWX умеют файловые системы вроде NFS или CephFS. Заявка останется Pending навсегда.
Postgres падает с жалобой на непустой каталог. На свежем ext4-томе в корне лежит lost+found, и initdb отказывается работать. Лечится переменной PGDATA с подкаталогом, как в примере выше, или через subPath в volumeMounts.
Несколько реплик Deployment с одним RWO-томом. Для баз и прочего stateful правильный инструмент это StatefulSet с volumeClaimTemplates, где каждая реплика получает свой PVC. Он за рамками этой главы, но знайте, куда копать.
Что усвоили: emptyDir для временного, PVC для постоянного, StorageClass решает, откуда возьмется диск, а reclaimPolicy решает судьбу данных. В главе 9 займемся namespaces, requests и limits, то есть наведем порядок в ресурсах кластера.