Стадия жизненного цикла модуля: General Availability
Работоспособность модуля гарантируется только при использовании стоковых ядер, поставляемых вместе с поддерживаемыми дистрибутивами.
Работоспособность модуля при использовании других ядер или дистрибутивов возможна, но не гарантируется.
Контроллер работает с двумя типами ресурсов:
Работа с ресурсами BlockDevice
Создание ресурса BlockDevice
Контроллер регулярно сканирует устройства на узле. Если устройство соответствует требованиям контроллера, создаётся ресурс BlockDevice с уникальным именем, содержащий полную информацию об устройстве.
Требования контроллера к устройству
Чтобы контроллер создал ресурс BlockDevice для устройства, оно должно соответствовать следующим требованиям:
- устройство не должно быть DRBD-устройством;
- устройство не должно быть псевдо-устройством (loop device);
- устройство не должно быть логическим томом;
- файловая система должна отсутствовать или быть типа
LVM2_MEMBER; - на блочном устройстве (block device) не должно быть разделов;
- размер блочного устройства должен превышать 1 ГБ;
- если устройство является виртуальным диском, оно должно иметь серийный номер.
Создание раздела на блочном устройстве
Если на блочном устройстве создан раздел, контроллер автоматически создаст ресурс BlockDevice для этого раздела.
Пример создания раздела на блочном устройстве:
fdisk /dev/sdb
Контроллер использует информацию из созданного ресурса при работе с ресурсами LVMVolumeGroup.
Обновление ресурса BlockDevice
Контроллер автоматически обновляет информацию в ресурсе при изменении состояния соответствующего блочного устройства на узле.
Удаление ресурса BlockDevice
Контроллер автоматически удалит ресурс, если соответствующее блочное устройство стало недоступным. Удаление произойдёт только в следующих случаях:
- если ресурс был в статусе Consumable;
- если блочное устройство принадлежит группе томов (volume group), у которой отсутствует LVM-тег
storage.deckhouse.io/enabled=true(эта группа томов не управляется контроллером модуля).
Контроллер выполняет все перечисленные операции автоматически, без участия пользователя.
В случае ручного удаления ресурса он будет пересоздан контроллером.
Работа с ресурсами LVMVolumeGroup
Ресурсы BlockDevice необходимы для создания и обновления ресурсов LVMVolumeGroup. В данный момент поддерживаются только локальные группы томов.
Ресурсы LVMVolumeGroup предназначены для взаимодействия с группами томов LVM (LVM Volume Group) на узлах и отображения актуальной информации об их состоянии.
Создание ресурса LVMVolumeGroup
Ресурс LVMVolumeGroup может быть создан тремя способами, описанными далее.
Автоматическое создание
Контроллер автоматически сканирует группы томов LVM на узлах. Если у группы томов LVM имеется LVM-тег storage.deckhouse.io/enabled=true, а соответствующий Kubernetes-ресурс LVMVolumeGroup отсутствует, контроллер создаёт его автоматически.
В этом случае контроллер автоматически заполняет все поля секции spec ресурса, кроме thinPools. Для управления существующим на узле thin pool необходимо вручную добавить информацию о нём в секцию spec ресурса.
Создание пользователем
Пользователь вручную создает ресурс, заполняя поля metadata.name и spec, указывая желаемое состояние новой группы томов.
Указанная конфигурация проходит валидацию. После успешной валидации контроллер создаёт группу томов LVM на узле согласно конфигурации. Затем контроллер обновляет ресурс LVMVolumeGroup актуальной информацией о состоянии созданной группы томов LVM.
Ручное создание группы томов на узле
Пользователь вручную создает группу томов на узле с помощью стандартных LVM-команд.
После создания группы томов пользователь добавляет LVM-тег storage.deckhouse.io/enabled=true для передачи управления контроллеру.
Контроллер автоматически обнаружит группу томов с этим тегом и создаст соответствующий ресурс LVMVolumeGroup.
Примеры создания ресурсов LVMVolumeGroup
Примеры ниже показывают различные варианты конфигурации с использованием разных селекторов и с thin pool или без него.
Примеры без thin pool:
Создание группы томов LVM с выбором конкретных устройств по именам ресурсов BlockDevice (используется matchExpressions):
apiVersion: storage.deckhouse.io/v1alpha1
kind: LVMVolumeGroup
metadata:
name: "vg-0-on-node-0"
spec:
type: Local
local:
nodeName: "node-0"
blockDeviceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- dev-07ad52cef2348996b72db262011f1b5f896bb68f
- dev-e90e8915902bd6c371e59f89254c0fd644126da7
actualVGNameOnTheNode: "vg-0"
Создание группы томов LVM с выбором всех устройств на узле (используется matchLabels):
apiVersion: storage.deckhouse.io/v1alpha1
kind: LVMVolumeGroup
metadata:
name: "vg-0-on-node-0"
spec:
type: Local
local:
nodeName: "node-0"
blockDeviceSelector:
matchLabels:
kubernetes.io/hostname: node-0
actualVGNameOnTheNode: "vg-0"
Примеры с thin pool:
Создание группы томов LVM с thin pool и выбором конкретных устройств по именам (используется matchExpressions):
apiVersion: storage.deckhouse.io/v1alpha1
kind: LVMVolumeGroup
metadata:
name: "vg-0-on-node-0"
spec:
type: Local
local:
nodeName: "node-0"
blockDeviceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- dev-07ad52cef2348996b72db262011f1b5f896bb68f
- dev-e90e8915902bd6c371e59f89254c0fd644126da7
actualVGNameOnTheNode: "vg-0"
thinPools:
- name: thin-1
size: 250Gi
Создание группы томов LVM с thin pool и выбором всех устройств на узле (используется matchLabels):
apiVersion: storage.deckhouse.io/v1alpha1
kind: LVMVolumeGroup
metadata:
name: "vg-0-on-node-0"
spec:
type: Local
local:
nodeName: "node-0"
blockDeviceSelector:
matchLabels:
kubernetes.io/hostname: node-0
actualVGNameOnTheNode: "vg-0"
thinPools:
- name: thin-1
size: 250Gi
Вы можете использовать любые удобные селекторы для ресурсов BlockDevice. Например, выбрать все устройства на узле (используя matchLabels) или часть устройств, указав их имена или другие параметры.
Поле spec.local является обязательным для типа Local. При расхождении имени в поле spec.local.nodeName и селекторах создание LVMVolumeGroup не будет выполнено.
Все выбранные блочные устройства должны принадлежать одному узлу для LVMVolumeGroup с типом Local.
Обновление ресурса LVMVolumeGroup
Чтобы изменить желаемое состояние группы томов или thin pool на узлах, измените поле spec соответствующего ресурса LVMVolumeGroup. Контроллер автоматически валидирует новые данные и, при их корректности, вносит необходимые изменения в сущности на узле.
Контроллер автоматически обновляет поле status ресурса LVMVolumeGroup, отображая актуальные данные о соответствующей группе томов LVM на узле. Не рекомендуется самостоятельно изменять поле status.
Контроллер не изменяет поле spec, так как оно отражает желаемое состояние группы томов LVM. Для изменения состояния соответствующей группы томов LVM на узле пользователь может изменять поле spec.
Удаление ресурса LVMVolumeGroup
Автоматическое удаление
Контроллер автоматически удалит ресурс, если указанная в нем группа томов стала недоступна (например, на узле были отключены все блочные устройства, из которых состояла группа томов).
Ручное удаление
Пользователь может удалить группу томов LVM на узле вместе со связанными физическими томами LVM, удалив ресурс LVMVolumeGroup:
d8 k delete lvg %lvg-name%
Защита от удаления
Пользователь может запретить удаление ресурса LVMVolumeGroup, добавив аннотацию storage.deckhouse.io/deletion-protection к ресурсу. При наличии этой аннотации контроллер не будет удалять ни ресурс, ни соответствующую группу томов до тех пор, пока аннотация не будет удалена с ресурса.
Если удаляемый ресурс LVMVolumeGroup содержит логический том (даже если это только thin pool, указанный в spec), необходимо самостоятельно удалить все логические тома в удаляемой группе томов. В противном случае ни ресурс, ни группа томов не будут удалены.
Извлечение ресурса BlockDevice из LVMVolumeGroup
Чтобы извлечь ресурс BlockDevice из ресурса LVMVolumeGroup, выполните следующее:
- Измените поле
spec.blockDeviceSelectorресурса LVMVolumeGroup (добавив другие селекторы) или измените соответствующие лейблы у ресурса BlockDevice, чтобы они больше не попадали под селекторы LVMVolumeGroup. - Выполните на узле команды
pvmove,vgreduceиpvremove.
Защита от утечек данных между томами
При удалении файлов операционная система не удаляет содержимое физически, а лишь помечает соответствующие блоки как «свободные». Если новый том получает физические блоки, ранее использовавшиеся другим томом, в них могут остаться данные предыдущего пользователя.
Проблема утечки данных
Утечка данных возможна при следующих условиях:
- Пользователь №1 создал том из StorageClass 1 на узле 1 (режим «Block» или «Filesystem» значения не имеет), разместил в нём данные и затем удалил том.
- Физические блоки, занятые пользователем №1, помечаются как свободные, но их содержимое не очищается.
- Пользователь №2 запрашивает новый том из той же StorageClass 1 на том же узле 1 в режиме «Block».
- При выделении томов системе могут быть предоставлены те же физические блоки, которые ранее использовал пользователь №1.
- Пользователь №2 получает доступ к данным пользователя №1, которые остались в этих блоках.
Thick-тома
Для предотвращения утечек через thick-тома предусмотрен параметр volumeCleanup, который позволяет выбрать метод очистки тома перед удалением физического тома.
Доступные методы очистки
-
Параметр не задан — при удалении тома дополнительные действия не выполняются. Данные могут остаться доступными следующему пользователю, получившему тот же том.
-
RandomFillSinglePass— том будет перезаписан случайными данными один раз перед удалением. Не рекомендуется для твердотельных накопителей, так как уменьшает ресурс накопителя. -
RandomFillThreePass— том будет перезаписан случайными данными три раза перед удалением. Не рекомендуется для твердотельных накопителей, так как уменьшает ресурс накопителя. -
Discard— все блоки тома будут отмечены как свободные с использованием системного вызоваdiscardперед удалением. Опция применима только для твердотельных накопителей.
Рекомендации по использованию Discard
Большинство современных твердотельных накопителей гарантирует, что после выполнения команды discard блок при чтении не вернёт предыдущие данные. Это делает опцию Discard самым эффективным способом предотвращения утечек данных при использовании твердотельных накопителей.
Следует учитывать следующие ограничения:
- Очистка ячейки — относительно долгая операция, поэтому выполняется устройством в фоновом режиме.
- Многие диски не могут очищать отдельные ячейки, а только группы ячеек (страницы).
- Не все накопители гарантируют немедленную недоступность освобождённых данных.
- Не все накопители, заявляющие о таких гарантиях, соответствуют заявленным характеристикам на практике.
Не рекомендуется использовать накопители, которые не гарантируют Deterministic TRIM (DRAT) и Deterministic Read Zero after TRIM (RZAT) или не были проверены на соответствие этим стандартам.
Thin-тома
При освобождении блока thin-тома командой discard со стороны гостевой операционной системы команда передаётся на физическое устройство. При использовании жесткого диска или при отсутствии поддержки discard на твердотельном накопителе данные могут остаться в thin pool до повторного использования блока другим томом.
Пользователи имеют доступ только к thin-томам, а не к самому thin pool. При выделении нового тома из пула для thin-томов LVM выполняет зануление блока thin pool перед его использованием. Это предотвращает утечки данных между клиентами и гарантируется настройкой thin_pool_zero=1 в LVM.