Storage
Хоть и kubernetes очень удобен для разворачивания и управления нагрузкой, которая не имеет состояния(stateless), он также предоставляет механизмы для хранения данных и работы приложений, которым необходимо хранить в себе некоторое состояние(stateful). Данные механизмы позволяют не терять данные между перезапусками контейнеров(Volumes), а также динамически выделять хранилище(StorageClass, PersistentVolumeClaim, PersistentVolume) и управлять снимками хранилища(VolumeSnapshotClass, VolumeSnapshot).
Volumes
Для предотвращения потери данных между перезапусками контейнера в описании пода есть параметр .spec.volumes, в котором можно указать описание тома, где будут храниться данные между перезапусками. Также тома можно смонтировать одновременно сразу к нескольким контейнерам, тем самым обеспечив связь между ними.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
В данном примере показан volume типа nfs, который монтируется в конкретный контейнер
через параметр volumeMounts
. Связь между volume
пода и volumeMounts
контейнера производится через
параметр name
. Volume поддерживает множество различных типов томов: configMap, secret, emptyDir,
fc, iscsi, nfs, cephfs, rbd и другие. Помимо встроенных типов есть возможность добавление в кластер
дополнительных типов с помощью Container Storage Interface (CSI).
Ephemeral Volumes
Не всем приложениям нужно хранить данные между пересозданием пода, например данные временных файлов, кэша, логов и т.д. Также приложению могут потребоваться данные из api kubernetes, которые можно смонтировать внутрь пода. Для этого подойдут эфемерные тома, которые создаются только на время жизни пода.
EmptyDir
Это пустая директория, которая создается и монтируется в под после его создания и назначения на ноду. Данный тип удобно использовать для временного хранения файлов, которые нужны только во время работы приложения, либо для обмена данными между контейнерами в поде.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
medium: Memory
sizeLimit: 500Mi
По умолчанию размер тома не ограничивается(только размером файловой системы на ноде), но может быть
ограничен дополнительным параметром sizeLimit
и через resources. Через параметр
medium: Memory
можно указать хранение данных не на файловой системе, а в оперативной памяти.
ConfigMap
ConfigMap в Kubernetes предназначен для хранения конфигурационных данных, которые могут быть использованы внутри приложения, запущенного в контейнере. ConfigMap Volume позволяет использовать данные ConfigMap в виде файлов внутри контейнера. Для использования ConfigMap Volume необходимо сначала создать ConfigMap, который будет содержать необходимые конфигурационные данные.
apiVersion: v1
kind: ConfigMap
metadata:
name: log-config
data:
log_level: debug
Затем можно создать Volume в поде, используя данные из ConfigMap.
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
optional: false
Secret
Также в Kubernetes существует ресурс Secret, который используется для хранения конфиденциальных данных, таких как пароли, ключи API и сертификаты.
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
key: dmFsdWU=
type: Opaque
Secret может быть использован в качестве тома в Pod.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
optional: true
DownwardAPI
В Kubernetes существует возможность для контейнеров получать информацию об окружении, в котором они запущены, с помощью механизма Downward API. Downward API позволяет контейнерам получить информацию о:
лейблах пода
полях пода
имени и уникальном идентификаторе пода
имени и уникальном идентификаторе неймспейса
Для использования Downward API можно использовать volume типа downwardAPI, который включает в себя файлы, содержащие запрашиваемую информацию.
apiVersion: v1
kind: Pod
metadata:
name: downwardapi-example
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: downwardapi
mountPath: /etc/podinfo
readOnly: true
volumes:
- name: downwardapi
downwardAPI:
items:
- path: "metadata/labels"
fieldRef:
fieldPath: metadata.labels
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
Projected
Projected volume в Kubernetes позволяет объединять в одном volume несколько источников данных, таких как ConfigMap, Secret, Downward API и ServiceAccountToken, и предоставлять их как один файловый системный раздел в контейнере. Это может быть полезно, если контейнеру требуется доступ к нескольким ресурсам конфигурации или сервисным данным.
apiVersion: v1
kind: Pod
metadata:
name: projected-example
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
volumes:
- name: config
projected:
sources:
- configMap:
name: myconfigmap
- secret:
name: mysecret
Persistent Volumes
Persistent Volumes (PV) в Kubernetes - это абстракция над физическим хранилищем данных, которая позволяет абстрагировать хранилище от приложений, которые его используют. PV - это ресурс Kubernetes, который описывает хранилище данных, такое как диск, NFS-шару или том в облаке, и его характеристики, такие как доступность, емкость и режим доступа. PV можно создать заранее, до того, как к нему обратится приложение, а потом использовать его как ресурс для подов. Когда приложение запрашивает PV, Kubernetes выбирает наиболее подходящее свободное хранилище на основе его параметров.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Persistent Volume Claim (PVC) - это способ запроса ресурса PV в Kubernetes. Когда PVC создается, Kubernetes выбирает PV, который соответствует критериям PVC (размер, доступность и т.д.), и резервирует его для использования.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Поды могут использовать PVC, чтобы монтировать том в свои контейнеры.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Storage Classes
StorageClass - это объект, который определяет класс хранилища для PersistentVolume (PV). StorageClass определяет способ, которым PV будет создан, конфигурирован и управляться. Он также определяет тип хранилища, такой как NFS, iSCSI, Ceph, AWS EBS, GCP PD и т.д., и параметры хранилища, такие как размер, скорость, доступность и т.д.
StorageClass может использоваться для динамического выделения PV. Это означает, что при создании пода, если нужный PV не существует, StorageClass может автоматически создать его для пода. Например, если поду требуется PersistentVolumeClaim (PVC) определенного размера, и нет доступного PV, StorageClass может создать новый PV нужного размера и назначить его PVC. Это может быть очень удобно для разработчиков, которые не хотят создавать и управлять PV вручную.
Кроме того, разные приложения могут использовать разные классы хранилищ, а StorageClass обеспечивает способ управления и мониторинга этих классов в едином месте.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate