При развёртывании масштабируемого веб-приложения, которое обрабатывает большие объёмы пользовательских данных и транзакций, хорошо настроенное управление хранилищем заметно повышает производительность и доступность данных. И тогда при увеличении нагрузки на приложение доступ к данным остаётся быстрым и надёжным, задержки уменьшаются, общее взаимодействие пользователя с приложением улучшается.
Например, у нас была задача обеспечить надёжное и масштабируемое хранение данных в веб-приложении для управления клиентскими заказами. Мы настроили в Kubernetes Storage Class на основе SSD для базы данных (что не является хорошей практикой): это помогло обеспечить быстрый доступ и обработку транзакций. А для логов и нечасто применяемых данных использовали отдельный Storage Class с HDD, и это позволило снизить затраты.
А главное, Storage в Kubernetes — это такая штука, которую ты сделал и забыл, дальше оно там само работает.
Подсистемы PV представляют собой абстракции реальных хранилищ данных, которые размещаются на физических или виртуальных дисках. PV предоставляют интерфейс для управления жизненным циклом данных независимо от того, на каком уровне инфраструктуры они фактически хранятся (например, NFS, iSCSI, cloudstorage и т. д.).
Когда вы работаете с подами в Kubernetes, одним из первых вопросов, который приходит в голову, является: «Куда деваются мои данные после завершения пода?»
Именно здесь на сцену выходят PV. Они как бы говорят вашим данным: «Не волнуйтесь, я сохраню вас». Это не просто хранилище — это хранилище, спроектированное так, чтобы выжить в условиях постоянных изменений, характерных для кластеров Kubernetes.
Создание PV может быть статическим или динамическим, и это одна из его наиболее привлекательных особенностей. В статическом режиме администратор заранее создаёт ряд PV с различными характеристиками. Это как заранее приготовленный шкаф с разными ящиками для хранения. В динамическом режиме PV создаётся «на лету» на основе требований, указанных в PersistentVolumeClaim (PVC). Это как если бы у вас был магический шкаф, который сам создаёт нужный вам ящик, когда вы его запросите.
Один из наиболее интересных аспектов PV — это его жизненный цикл и политики восстановления. Когда PVC удаляется, что происходит с PV? Он может быть сохранён для будущего использования, может быть полностью удалён или даже «рециклирован» для очистки данных. Это даёт администраторам гибкость в управлении ресурсами и обеспечивает высокую степень контроля над данными.
Affinity узлов в PV позволяет вам уточнить, на каких узлах этот конкретный PV может быть использован. Это особенно полезно в больших и разнородных кластерах, где у разных узлов могут быть разные характеристики хранилища. С помощью аффинности узлов вы можете гарантировать, что ваш PV будет размещён там, где это наиболее эффективно с точки зрения производительности и надёжности.
На этой схеме показан процесс работы с PV в Kubernetes:
YAML для Persistent Volume:
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv spec: capacity: storage: 10Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-sc hostPath: path: "/mnt/local-storage" nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: "kubernetes.io/hostname" operator: In values: - node1 - node2
В этом примере:
PersistentVolumes в Kubernetes — не просто механизм хранения данных. Это продуманный и гибкий инструмент, который позволяет администраторам и разработчикам сосредоточиться на своей основной работе, не беспокоясь о данных. Они обеспечивают уровень абстракции и управления, который делает работу с хранилищем не только возможной, но и эффективной.
PersistentVolumeClaims (PVC) — это как заявки на аренду недвижимости в мире Kubernetes.
Если PersistentVolumes (PV) являются зданиями, готовыми к заселению, то PVC — это ваша анкета, в которой вы указываете, какие условия вам нужны: количество комнат, наличие балкона и так далее.
PVC — это запрос на выделение хранилища из общего пула PV. Когда приложение в кластере нуждается в постоянном хранилище, оно не обращается напрямую к PV. Вместо этого оно создаёт PVC, в котором описывает свои требования к хранилищу. Это абстракция, которая позволяет разработчикам фокусироваться на коде, не задумываясь о деталях инфраструктуры.
Как только PVC создан, Kubernetes начинает поиск подходящего PV. Этот процесс называется «связыванием». Если подходящий PV найден, то он «связывается» с PVC, и приложение может начать использовать этот том для хранения данных. Если подходящего PV нет, то PVC остаётся в состоянии Pending до тех пор, пока не появится соответствующий PV или пока не будет выполнено динамическое выделение хранилища.
Принципы работы PVC:
В Kubernetes PersistentVolumeClaim (PVC) предоставляет различные режимы доступа к хранилищу. Эти режимы определяют, как поды могут взаимодействовать с соответствующим
PersistentVolume (PV). Вот подробное описание каждого режима:
Представляет собой способ описания классов хранилища, которые можно использовать для динамического выделения PersistentVolumes (PV) при создании PersistentVolumeClaims (PVC).
Storage Class определяет, какой провайдер хранилища будет использоваться, какие параметры будут применены и другие специфические для провайдера настройки.
Селекторы в PVC позволяют вам фильтровать и выбирать PersistentVolumes (PV) на основе меток. Это предоставляет дополнительный уровень контроля при привязке PVC к PV, позволяя вам удостовериться, что выбранный том соответствует определённым требованиям или политикам. Селекторы в PVC используют метки, которые были присвоены PV. Когда PVC создаётся с определённым селектором, он будет привязан только к тем PV, которые соответствуют меткам селектора.
Определяет, что произойдёт с PersistentVolume (PV) после удаления соответствующего PersistentVolumeClaim (PVC). Это важный аспект управления жизненным циклом хранилища в Kubernetes.
Виды политик восстановления:
1. Retain (сохранить).
2. Delete (удалить).
3. Recycle (переработать).
Вот диаграмма, которая поможет понять ключевые компоненты и взаимодействия, связанные с PersistentVolumeClaim:
На диаграмме:
Пример YAML для PVC:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: standard
Использование PVC в Pod:
apiVersion: v1 kind: Pod metadata: name: "myapp" namespace: default labels: app: "myapp" spec: volumes: - name: my-storage persistentVolumeClaim: claimName: my-pvc containers: - name: myapp image: "debian-slim:latest" volumeMounts: - name: my-storage mountPath: "/data"
Управление жизненным циклом:
Это нечто вроде каталога аренды жилья, где каждый класс представляет собой набор характеристик и условий для хранилища. Это ключевой элемент, который управляет динамическим выделением хранилища в кластере. Этот механизм описывает различные классы хранилища, которые предлагаются в кластере. Каждый класс имеет свои уникальные характеристики, такие, как тип диска, скорость IOPS и параметры шифрования.
SC определяет, как должны быть созданы PersistentVolumes (PV) при динамическом выделении хранилища на основе PersistentVolumeClaims (PVC). Возможность динамического выделения, когда приложение создаёт PVC и указывает в нём Storage Class, Kubernetes автоматически создаёт PV с нужными характеристиками.
Ключевые аспекты Storage Class:
Пример YAML для Storage Class:
apiVersion: v1 kind: StorageClass metadata: name: my-local-sc provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer
В этом примере:
Storage Class особенно полезен в многофункциональных и разнородных кластерах. Например, для базы данных вы можете создать класс с высокопроизводительным SSD, а для архива данных — класс с более дешёвым и медленным хранилищем. Это позволяет оптимизировать затраты и производительность.
Вот диаграмма, которая поможет вам понять ключевые компоненты и взаимодействия, связанные со Storage Class:
На диаграмме:
В целом Storage Class в Kubernetes является инструментом, который добавляет дополнительный уровень абстракции и гибкости при работе с хранилищем данных. Он не только упрощает задачи управления, но и открывает новые возможности для оптимизации ресурсов и повышения эффективности. Эта функциональность становится особенно ценной в сложных и динамичных средах, где требования к хранилищу могут быстро меняться.