База данных в Kubernetes
С ростом внедрения принципов DevOps все больше и больше приложений помещаются в контейнеры, и инструменты для управления этими контейнерами, такие как Kubernetes, становятся популярными. Этот рост миграции приложений в Kubernetes (K8s) также отражается в приложениях с отслеживанием состояния (например, системах баз данных).
Сначала давайте разберемся с основами:
Для развертывания любого приложения на K8s наиболее предпочтительным способом является декларативный способ, при котором мы объявляем желаемое состояние приложения (например, образ, который следует использовать для запуска модулей, масштабирование модулей для управления нагрузкой и т. д.) в файле. YAML-файл, известный как файл развертывания.

Он также объявляет ReplicaSet, который используется для обеспечения запуска желаемого количества реплик модуля в любой момент времени.
По сути, развертывания полезны для запуска приложений без сохранения состояния (например, сервера nodejs) на модулях K8s путем объявления их желаемого состояния.
При развертывании используется механизм Contol-Loop , предоставляемый Control-Manager, для преобразования желаемого состояния приложения (как описано в YAML-файле развертывания) в фактическое состояние.

Объем в k8s
Когда нам нужно развернуть приложение, которое хранит данные (например, базу данных), нам нужна область постоянного хранилища, потому что модули не могут хранить в ней данные. Как только модуль умирает, все доступные в нем данные теряются.
То есть нам нужен раздел Storage, который не зависит от жизненного цикла Pod.
Volume можно разделить на три секции:
Storage Class (SC)
- Это фактическая область хранения, в которой файлы хранятся в основной памяти. Это может быть локальное хранилище External storage или внешнее хранилище Cloud-based.
Persistent Volume (PV)
Это компонент, предоставляемый k8s, который используется для указания необходимого типа и объема хранилища. Затем указанная сумма прикрепляется к Persistent Volume как внешний плагин.
PV доступен для всего кластера, то есть он не локализован в определенном namespace.
Persistent Volume Claim (PVC)
PVC используется для запроса определенного тома, как определено в конфигурации Pod. Он существует в том же namespace, что и Pod.
Если Pod умирает и на его месте создается новый, то PVC в namespace присоединяется к Pod, тем самым обеспечивая доступ к ранее созданным данным в Storage class.

Жизненный цикл раздела хранилища не зависит от жизненного цикла Pod даже если весь кластер выйдет из строя, наши данные сохранятся в Storage Volume.
Из приведенной выше конфигурации мы можем видеть, что база данных может быть развернута в этом Pod, где фактические данные безопасно хранятся в Storage Class volume, который находится за пределами namespace k8s, с помощью PV и PVC и, следовательно, не будут затронуты.
Фактически, мы можем использовать Deployment для запуска одного экземпляра базы данных в Pod.
Но недостаток возникает, когда мы создаем реплики Pod или пытаемся увеличить или уменьшить количество Pod с БД, поскольку все Pod БД не одинаковы. Если все модули имеют одинаковые уровни (одинаковые права на чтение и запись для всех модулей), тогда начнут создаваться data inconsistency (данные записываются из одного Pod, но неизвестны другим Pods).
Кроме того, даже если мы создадим Pod в отдельном namespace, он все равно может указывать на тот же Storage class за пределами кластера (поэтому на самом деле база данных не реплицировалась).
То есть все Pods базы данных должны иметь свое собственное состояние и идентификатор и не могут быть похожи друг на друга.
Из приведенного выше обсуждения мы можем понять, что репликация приложения с сохранением состояния не так проста, как репликация приложения без сохранения состояния.
StatefulSet
StatefulSet — это встроенный компонент Kubernetes, представленный в версии 1.5. Это можно использовать вместо развертываний для объявления и выполнения модулей K8s.
Согласно документации K8s
StatefulSet управляет развертыванием и масштабированием набора модулей Pod и предоставляет гарантии порядка и уникальности этих модулей.