volumes
Простые тома (volumes)
Volumes - сущности kubernetes, используемые для хранения общих данных внутри отдельного пода. Простые тома применяются, когда нескольким контейнерам одного пода нужно обмениваться данными на уровне файлов.
Volume прикрепляется к поду, хранится на файловой системе ноды и, обычно, уничтожается при пересоздании пода. Следовательно, чувствительные к потере данные нельзя хранить в томах такого типа.
Для подключения volume к котейнеру необходимо: описать все необходимые тома в соответствующем разделе (volumes) спецификации манифеста, и примонтировать эти тома к файловой системе внутри контейнеров.
kind: Pod
...
spec:
volumes: # раздел спецификации для объявления томов
- name: vol1 # имя тома, используется при монтировании тома в контейнер
emptyDir: {} # тип тома: пустая директория, очищается при удалении пода
- name: vol2 #
emptyDir: {} #
kind: Pod
...
spec:
containers:
- name: cont1
image: images/image1
volumeMounts:
- mountPath: "/path/to/container/dir" # путь монтируемой директории внутри контейнера
name: vol1 # задекларированное имя тома
- name: cont2
image: images/image2
volumeMounts:
- mountPath: "other/path/to/container/dir"
name: vol1
Постоянные тома (PersistentVolume)
PersistentVolume - сущность kubernetes, которая представляет собой абстракцию над файловой системой СХД и дает возможность подключать к подам тома с постоянным хранением данных.
Конкретная реализация PersistentVolume может быть очень разной: hostPath, local, nfs, fc, etc.
Для того чтобы объект PV можно было монтировать в под - его надо создать, это можно сделать вручную и динамически.
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv
spec:
storageClassName: "" # Имя класса хранилища
accessModes: # Режим доступа к тому
- ReadWriteOnce
capacity: # Максимально доступный объем тома
storage: 2Gi
hostPath: # тип тома
path: /data/pv
persistentVolumeReclaimPolicy: Delete # Политика восстановления ресурса
accessModes - параметр, который определяет какие операции доступа разрешены в создаваемом хранилище.
- ReadWriteOnce - том может быть примонтирован в режиме чтение/запись к одному или нескольким подам в пределах одной ноды
- ReadWriteOncePod - том может быть примонтирован только к одному поду
- ReadOnlyMany - том может быть примонтирован в режиме только чтение ко множеству подов
- ReadWriteMany - том может быть примонтирован в режиме чтение/запись ко множеству подов
ReclaimPolicy - параметр, который определяет политики поведения провайдера данных после удаления PV
- Retain - данные оставшиеся после удаления PV автоматически не удалятся
- Delete - после удаления PV, оставшиеся данные будут автоматически удалены
Самым удобным является вариант Delete. Но не все CSI драйверы поддерживают такой режим.
PersistentVolumeClaim
Запрос на выделение ресурса PersistentVolumeClaim Для того чтобы примонтировать PV к поду, необходимо сначала создать запрос на выделение PV. Такой запрос называется PersistentVolumeClaim (PVC).
PersistentVolumeClaim - сущность k8s, которая производит поиск доступных PV с определенными характеристиками и если находит - производит связывание пода с PV.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc # Имя PVC, которое нужно указывать в спецификации пода
spec:
storageClassName: "" # Имя класса хранилища, используется для динамического предоставления PV
accessModes: # Режим доступа требуемый от PV
- ReadWriteOnce
resources: # Требование к минимальному объему PV
requests:
storage: 5Gi
После того как PVC нашел подходящий PV и связался с ним, том может быть примонтирован в под
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
volumeMounts:
- name: my-volume
mountPath: /data
volumes:
- name: my-volume
persistentVolumeClaim: # Определяем, что том должен быть создан через PVC
claimName: my-pvc # Имя PVC
# Если указанного PVC нет среди ресурсов кластера - под не будет создан
# Если среди ресурсов кластера нет требуемого PV - под не будет создан
# Под будет находиться в состоянии pending и ждать когда появяться требуемые ресурсы
Dynamic Provisioning
Динамическое предоставление томов
В k8s предусмотрена возможность динамически выделять запрашиваемые PV. При динамическом выделении тома создаются с помощью provisioner.
Для начала необходимо создать StorageClass - отдельный ресурс k8s, в котором будут указаны параметры для динамического создания томов.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: my-storage-class
provisioner: kubernetes.io/hostpath # В данном случае, для создания PV будет использоваться hostpath
reclaimPolicy: Delete
Затем, при создании запроса PVC, необходимо указать имя соответствующего StorageClass.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: my-storage-class # имя SC
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Для экспериментов можно создать StorageClass и provisioner, который будет крутиться в контейнере и создавать PV типа nfs
# Установка helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
# Добавление репозитория чартов
helm repo add stable https://charts.helm.sh/stable && helm repo update
# Установка nfs-server через helm
helm install nfs-server stable/nfs-server-provisioner
# В дальнейшем при создании PVC, на подах может возникнуть следующая проблема (поды зависнут в статусе ContainerCreating):
Output: mount: /var/lib/kubelet/pods/f760c19e-6ec0-46e8-9a3a-d6187fd927e8/volumes/kubernetes.io~nfs/pvc-d3134d79-c2ce-41a2-af72-0f2d45c5c19e:
bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.
# Решение проблемы (необходимо установить на всех нодах !!!):
sudo apt install nfs-common # для debian/ubuntu