В Kubernetes важно правильно настроить StorageClass, чтобы эффективно использовать место для хранения данных приложений. Выбирать StorageClass по умолчанию можно вручную, но такой способ часто приводит к ошибкам и усложняет работу. В этой статье мы расскажем, почему ручной способ — не самый удобный, и покажем подход, который реализовали в Deckhouse. Он помогает проще и надёжнее управлять хранением данных.

Ручной метод назначения StorageClass
В Kubernetes существует ручной способ назначения StorageClass по умолчанию. Значение указывается с помощью аннотации storageclass.kubernetes.io/is-default-class=true
:
kubectl patch storageclass standard-storage -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Этот стандартный механизм позволяет указывать, какой StorageClass должен использоваться по умолчанию при создании Persistent Volume Claim (PVC), если класс хранения не указан явно. То есть пользователи могут назначать StorageClass по умолчанию, добавляя или удаляя эту аннотацию у соответствующих объектов StorageClass. И эта аннотация может быть у нескольких StorageClass одновременно.
При этом у такого способа назначения StorageClass по умолчанию есть недостатки. Во-первых, при работе руками можно допустить ошибку, а ещё такой процесс занимает время. Во-вторых, ручная настройка не позволяет централизованно управлять конфигурациями StorageClass.
Кроме того, так как аннотация может быть у нескольких StorageClass одновременно, это может приводить к сложно предсказуемому поведению.
Сложно предсказуемое поведение
Если несколько StorageClass имеют аннотацию storageclass.kubernetes.io/is-default-class=true
, Kubernetes не может однозначно определить, какой класс использовать по умолчанию. Это может привести к тому, что PVC будет создан с использованием последнего созданного StorageClass, который пометили как по умолчанию.
В итоге PVC может создаться с использованием не того StorageClass, что может привести к неправильному распределению ресурсов и неоптимальному использованию хранилища. А если PVC создаётся с использованием StorageClass, который не соответствует требованиям приложения (например, низкопроизводительный класс для высокопроизводительного приложения), это может привести к проблемам с производительностью. Допустим, если база данных требует быстрого доступа к данным, но используется медленный StorageClass, это может замедлить обработку запросов.
Подробнее об этом можно почитать в документации Kubernetes.
Централизованное управление StorageClass в Deckhouse Kubernetes Platform
Для нас важно, чтобы кластер изначально был максимально настроен и управлялся централизованно, в том числе через UI. Аннотации, спрятанные где-то в недрах объектов, не позволяли прозрачно контролировать конфигурацию. Мы хотели иметь понятный параметр в одном месте, который бы однозначно определял StorageClass по умолчанию для всего кластера.
Кроме того, все StorageClass, создаваемые нашими модулями, защищены вебхуками — их нельзя изменять вручную. Чтобы дать пользователю возможность управлять аннотациями, пришлось бы делать исключения и «дыры» в этой системе, что усложняло бы архитектуру и снижало безопасность. Мы даже пытались решать это через параметры в CRD, на основе которых модули создают StorageClass, но с ростом числа модулей стало ясно, что поддерживать такую логику невозможно — слишком много связей и ручной работы.
Поэтому мы упростили администрирование: ввели в Deckhouse Kubernetes Platform (DKP) единый механизм указания значения по умолчанию для StorageClass.
В DKP 1.66 был добавлен глобальный параметр defaultClusterStorageClass
, который позволяет явно указать, какой StorageClass должен использоваться по умолчанию во всём кластере. Теперь платформа запрещает вручную управлять аннотацией storageclass.kubernetes.io/is-default-class=true
для StorageClass. Это означает, что пользователи больше не могут назначать его по умолчанию вручную с помощью этой аннотации.
Если значение не указано, фактический StorageClass, используемый в кластере по умолчанию, будет определяться в следующем порядке:
StorageClass в кластере, имеющий default-аннотацию
storageclass.kubernetes.io/is-default-class='true'
.Первый (по алфавиту) StorageClass из создаваемых модулем облачного провайдера, если используется какой-либо модуль облачного провайдера.
Если StorageClass с указанным именем отсутствует, Deckhouse просто предупреждает об этом в логе. И как только нужный StorageClass появляется в кластере, на него автоматически навешивается аннотация default.
Пример конфигурации
Пример ресурса ModuleConfig/global
, где задаётся defaultClusterStorageClass
:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: global
spec:
version: 1
settings:
defaultClusterStorageClass: 'default-fast'
modules:
publicDomainTemplate: '%s.kube.company.my'
resourcesRequests:
controlPlane:
cpu: 1000m
memory: 500M
placement:
customTolerationKeys:
- dedicated.example.com
Получается, что StorageClass с именем 'default-fast'
теперь является StorageClass по умолчанию для всего кластера.
Вместо заключения
Благодаря новому способу выбора StorageClass по умолчанию в Deckhouse Kubernetes Platform нам удалось решить проблемы с ручным управлением. Теперь все настройки централизованы, и никто не может случайно изменить их вручную. Это делает систему более понятной и снижает риск ошибок.
P. S.
Читайте также в нашем блоге: