Compare languages | The linstor module: FAQ

This version of the module is deprecated and is no longer supported. Use the sds-drbd module instead.

Текущая версия модуля устарела и больше не поддерживается. Переключитесь на использование модуля sds-drbd.

The module is guaranteed to work only in the following cases:

Работоспособность модуля гарантируется только в следующих случаях:

In all other cases, the module may work, but its full functionality is not guaranteed.

Работоспособность модуля в других условиях возможна, но не гарантируется.

What is difference between LVM and LVMThin?

Когда следует использовать LVM, а когда — LVMThin?

Briefly:

Если кратко, то:

  • LVM is simpler and has performance comparable to native drives;
  • LVMThin allows you to use snapshots and overprovisioning, but twice as slow.
  • LVM проще и обладает производительностью, сравнимой с производительностью накопителя;
  • LVMThin позволяет использовать snapshot’ы и overprovisioning, но медленнее в два раза.

Performance and reliability notes, comparison to Ceph

Производительность и надежность LINSTOR, сравнение с Ceph

You may be interested in our article “Comparing Ceph, LINSTOR, Mayastor, and Vitastor storage performance in Kubernetes”.

Возможно, вам будет интересна наша статья «Исследование производительности свободных хранилищ LINSTOR, Ceph, Mayastor и Vitastor в Kubernetes».

We take a practical view of the issue. A difference of several tens of percent — in practice it never matters. The difference is several times or more important.

Мы придерживаемся практического взгляда на вопрос. Разница в несколько десятков процентов на практике никогда не имеет значения. Имеет значение разница в несколько раз и более.

Comparison factors:

Факторы сравнения:

  • Sequential read and write: do not matter, because on any technology they always run into the network (which is 10Gb/s, which is 1Gb/s). From a practical point of view, this indicator can be completely ignored;
  • Random read and write (which is 1Gb/s, which is 10Gb/s):
  • DRBD + LVM 5 times better (latency — 5 times less, IOPS — 5 times more) than Ceph RBD;
  • DRBD + LVM is 2 times better than DRBD + LVMThin.
  • If one of the replicas is located on local storage, then the read speed will be approximately equal to the storage device speed;
  • If there are no replicas located on local storage, then the write speed will be approximately equal to half the network bandwidth for two replicas, or ⅓ network bandwidth for three replicas;
  • With a large number of clients (more than 10, with iodepth 64), Ceph starts to fall behind more (up to 10 times) and consume much more CPU.
  • Последовательное чтение и запись не имеют никакого значения, потому что на любой технологии они всегда упираются в сеть (что 10 Гбит/с, что 1 Гбит/с). С практической точки зрения этот показатель можно полностью игнорировать.
  • Случайное чтение и запись (что на 1 Гбит/с, что на 10 Гбит/с):
  • DRBD + LVM в 5 раз лучше, чем Ceph RBD (latency в 5 раз меньше, IOPS в 5 раз больше);
  • DRBD + LVM в 2 раза лучше, чем DRBD + LVMThin.
  • Если одна из реплик расположена локально, скорость чтения будет примерно равна скорости устройства хранения.
  • Если нет реплик, расположенных локально, скорость записи будет примерно ограничена половиной пропускной способности сети при двух репликах или ⅓ пропускной способности сети при трех репликах.
  • При большом количестве клиентов (больше 10, при iodepth 64) Ceph начинает отставать сильнее (до 10 раз) и потреблять значительно больше CPU.

All in all, in practice, it doesn’t matter how many knobs you have for tuning, only three factors are significant:

В сухом остатке получается, что на практике неважно, какие параметры менять, и есть всего три значимых фактора:

  • Read locality — if all reading is performed locally, then it works at the speed (throughput, IOPS, latency) of the local disk (the difference is practically insignificant);
  • 1 network hop when writing — in DRBD, the replication is performed by the client, and in Ceph, by server, so Ceph latency for writing always has at least x2 from DRBD;
  • Complexity of code — latency of calculations on the datapath (how much assembler code is executed for each io operation), DRBD + LVM is simpler than DRBD + LVMThin, and much simpler than Ceph RBD.
  • локальность чтения — если все чтение производится локально, оно работает со скоростью (throughput, IOPS, latency) локального диска (разница практически незаметна);
  • 1 сетевой hop при записи — в DRBD репликацией занимается клиент, а в Ceph — сервер, поэтому у Ceph latency на запись всегда минимум в два раза больше, чем у DRBD;
  • сложность кода — latency вычислений на datapath (сколько процессорных команд выполняется на каждую операцию ввода/вывода) — DRBD + LVM проще, чем DRBD + LVMThin, и значительно проще, чем Ceph RBD.

What to use in which situation?

Что использовать в какой ситуации?

By default, we use two replicas (the third is an automatically created diskless replica used for quorum). This approach guarantees protection against split-brain and a sufficient level of storage reliability, but the following features must be taken into account:

По умолчанию модуль использует две реплики (третья — так называемая diskless — используется для поддержания кворума и создается автоматически). Такой подход гарантирует защиту от split-brain и достаточный уровень надежности хранения, но нужно учитывать следующие особенности:

  • When one of the replicas (replica A) is unavailable, data is written only to a single replica (replica B). It means that:
  • If at this moment the second replica (replica B) is also turned off, writing and reading will be unavailable;
  • If at the same time the second replica (replica B) is irretrievably lost, then the data will be partially lost (there is only the old, outdated replica A);
  • If the old replica (replica A) was also irretrievably lost, the data will be completely lost.
  • When the second replica is turned off, in order to turn it back on (without operator intervention), both replicas must be available (in order to correctly work out the split-brain);
  • Enabling a third replica solves both problems (at least two copies of data at any given time), but increases the overhead (network, disk).
  • В момент недоступности одной из реплик (реплики A) данные записываются только в единственную реплику (реплику B). Это означает, что:
  • если в этот момент отключится и вторая реплика (реплика B), запись и чтение будут недоступны;
  • если при этом вторая реплика (реплика B) утеряна безвозвратно, данные будут частично потеряны (есть только старая реплика A);
  • если старая реплика (реплика A) была тоже утеряна безвозвратно, данные будут потеряны полностью.
  • Чтобы включиться обратно при отключении второй реплики (без вмешательства оператора), требуется доступность обеих реплик. Это необходимо, чтобы корректно отработать ситуацию split-brain.
  • Включение третьей реплики решает обе проблемы (в любой момент времени доступно минимум две копии данных), но увеличивает накладные расходы (сеть, диск).

It is strongly recommended to have one replica locally. This doubles the possible write bandwidth (with two replicas) and significantly increases the read speed. But if this is not the case, then everything still continues to work normally (but reading over the network, and double network utilization for writing).

Настоятельно рекомендуется иметь одну реплику локально. Это в два раза увеличивает возможную скорость записи (при двух репликах) и значительно увеличивает скорость чтения. Но даже если реплики на локальном хранилище нет, все также будет работать нормально, за исключением того, что чтение будет осуществляться по сети и будет двойная утилизация сети при записи.

Depending on the task, choose one of the following:

В зависимости от задачи нужно выбрать один из следующих вариантов:

  • DRBD + LVM — faster (x2) and more reliable (LVM is simpler);
  • DRBD + LVMThin — support for snapshots and the possibility of overcommitment.
  • DRBD + LVM — быстрее (в 2 раза) и надежнее (LVM — проще);
  • DRBD + LVMThin — поддержка snapshot’ов и возможность overprovisioning.

How to get information about the space usage?

Как получить информацию об используемом пространстве?

There are two options:

Есть два варианта:

  • Using Grafana dashboard: navigate Dashboards –> Storage –> LINSTOR/DRBD
    In the upper right corner you’ll find information about the space used in the cluster.
  • Через дашборд Grafana: перейдите Dashboards –> Storage –> LINSTOR/DRBD.
    В правом верхнем углу вы найдете информацию об используемом пространстве в кластере.

Attention! This information shows raw space usage in the cluster. Thus if you create a volume with two replicas, then these values should be divided by two to get a representation of how many such volumes can be placed in your cluster.

Внимание! Эта информация отражает состояние всего сырого пространства в кластере. То есть если вы создаете тома в двух репликах, то эти значения стоит поделить на два. Это нужно, чтобы получить примерное представление о том, сколько таких томов может быть размещено в вашем кластере.

  • Using LINSTOR command line:
  • Через командный интерфейс LINSTOR:

shell kubectl exec -n d8-linstor deploy/linstor-controller – linstor storage-pool list

shell kubectl exec -n d8-linstor deploy/linstor-controller – linstor storage-pool list

Attention! This information shows raw space usage for each node in the cluster. Thus if you create a volume with two replicas, then these two replicas must completely fit on two nodes in your cluster.

Внимание! Эта информация отражает состояние сырого пространства для каждого узла в кластере. То есть если вы создаете тома в двух репликах, то эти две реплики обязательно должны целиком поместиться на двух узлах вашего кластера.

Changing the default StorageClass

Как назначить StorageClass по умолчанию

List the StorageClasses in your cluster:

Отобразите список всех StorageClass’ов:

bash kubectl get storageclass

bash kubectl get storageclass

Mark the default StorageClass as non-default:

Снимите аннотацию с предыдущего StorageClass’а по умолчанию:

bash kubectl annotate storageclass local-path storageclass.kubernetes.io/is-default-class-

bash kubectl annotate storageclass local-path storageclass.kubernetes.io/is-default-class-

Mark a StorageClass as default:

Добавьте аннотацию для назначения нового StorageClass’а по умолчанию:

bash kubectl annotate storageclass linstor-data-r2 storageclass.kubernetes.io/is-default-class=true

bash kubectl annotate storageclass linstor-data-r2 storageclass.kubernetes.io/is-default-class=true

How to add existing LVM or LVMThin pool?

Как добавить существующий LVM- или LVMThin-пул?

The general method is described in`LINSTOR storage configuration page. Unlike commands listed below it will automatically configure the StorageClasses as well.

Основной метод описан на странице конфигурации хранилища LINSTOR. В отличие от команд, перечисленных ниже, он также автоматически настроит StorageClass’ы.

Example of adding an existing LVM pool:

Пример добавления LVM-пула:

shell linstor storage-pool create lvm node01 lvmthin linstor_data

shell linstor storage-pool create lvm node01 lvmthin linstor_data

Example of adding an existing LVMThin pool:

Пример добавления LVMThin-пула:

shell linstor storage-pool create lvmthin node01 lvmthin linstor_data/data

shell linstor storage-pool create lvmthin node01 lvmthin linstor_data/data

You can also add pools with some volumes have already been created. LINSTOR will just create new ones nearby.

Можно добавлять и пулы, в которых уже созданы какие-то тома. LINSTOR просто будет создавать в пуле новые тома.

How to configure Prometheus to use LINSTOR for storing data?

Как настроить Prometheus на использование хранилища LINSTOR?

To configure Prometheus to use LINSTOR for storing data:

Чтобы настроить Prometheus на использование хранилища LINSTOR, необходимо:

Example:

Пример:

yaml apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: prometheus spec: version: 2 enabled: true settings: longtermStorageClass: linstor-data-r2 storageClass: linstor-data-r2

yaml apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: prometheus spec: version: 2 enabled: true settings: longtermStorageClass: linstor-data-r2 storageClass: linstor-data-r2

  • Wait for the restart of Prometheus Pods.
  • Дождаться перезапуска подов Prometheus.

How to evict resources from a node?

Как выгнать ресурсы с узла?

  • Download the script evict.sh on a host that has access to the Kubernetes API server with administrative privileges (for the script to work, you need kubectl and jq installed):
  • Загрузите скрипт evict.sh на хост, имеющий доступ к API Kubernetes с правами администратора (для работы скрипта потребуются установленные kubectl и jq):
  • Download the latest version of the script from GitHub:
  • Последнюю версию скрипта можно скачать с GitHub:

shell curl -fsSL -o evict.sh https://raw.githubusercontent.com/deckhouse/deckhouse/main/modules/041-linstor/tools/evict.sh chmod 700 evict.sh

shell curl -fsSL -o evict.sh https://raw.githubusercontent.com/deckhouse/deckhouse/main/modules/041-linstor/tools/evict.sh chmod 700 evict.sh

  • Alternatively, download the script from the deckhouse pod:
  • Также скрипт можно скачать из пода deckhouse:

shell kubectl -n d8-system cp -c deckhouse $(kubectl -n d8-system get po -l app=deckhouse -o jsonpath=’{.items[0].metadata.name}’):/deckhouse/modules/041-linstor/tools/evict.sh ./evict.sh chmod 700 evict.sh

shell kubectl -n d8-system cp -c deckhouse $(kubectl -n d8-system get po -l app=deckhouse -o jsonpath=’{.items[0].metadata.name}’):/deckhouse/modules/041-linstor/tools/evict.sh ./evict.sh chmod 700 evict.sh

  • Fix all faulty LINSTOR resources in the cluster. To identify them, execute the following command:
  • Исправьте все ошибочные ресурсы LINSTOR в кластере. Чтобы найти их, выполните следующую команду:

shell kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor resource list –faulty

shell kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor resource list –faulty

  • Verify that all pods within the d8-linstor namespace are running:
  • Убедитесь, что все поды в пространстве имен d8-linstor находятся в состоянии Running:

shell kubectl -n d8-linstor get pods | grep -v Running

shell kubectl -n d8-linstor get pods | grep -v Running

Evict Resources from a Node Without Deleting It from LINSTOR and Kubernetes

Выгнать ресурсы с узла без удаления его из LINSTOR и Kubernetes

Run the evict.sh script in interactive mode with the --delete-resources-only mode:

Запустите скрипт evict.sh в интерактивном режиме, указав режим удаления --delete-resources-only:

shell ./evict.sh –delete-resources-only

shell ./evict.sh –delete-resources-only

To run the evict.sh script in non-interactive mode, it is necessary to add the --non-interactive flag when calling it, as well as the name of the node from which resources need to be evicted. In this mode, the script will perform all actions without requesting user confirmation. Example of invocation:

Для запуска скрипта evict.sh в неинтерактивном режиме необходимо добавить флаг --non-interactive при его вызове, а так же имя узла, с которого необходимо выгнать ресурсы. В этом режиме скрипт выполнит все действия без запроса подтверждения от пользователя. Пример вызова:

shell ./evict.sh –non-interactive –delete-resources-only –node-name “worker-1”

shell ./evict.sh –non-interactive –delete-resources-only –node-name “worker-1”

Note! After the script completes, the node will remain in Kubernetes with the status SchedulingDisabled, and in LINSTOR, the node will have the property AutoplaceTarget=false set, preventing the LINSTOR scheduler from creating resources on this node.

Важно! После завершении работы скрипта узел в Kubernetes останется в статусе SchedulingDisabled, а в LINSTOR у данного узла будет выставлен параметр AutoplaceTarget=false, что запретит планировщику LINSTOR создавать на этом узле ресурсы.

Run the following command to allow resource and pod placement on the node again:

Если необходимо снова разрешить размещать ресурсы и поды на узле, то необходимо выполнить команды:

shell alias linstor=’kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor’ linstor node set-property “worker-1” AutoplaceTarget kubectl uncordon “worker-1”

shell alias linstor=’kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor’ linstor node set-property “worker-1” AutoplaceTarget kubectl uncordon “worker-1”

Run the following command to check the AutoplaceTarget property for all nodes (the AutoplaceTarget field will be empty for nodes where LINSTOR resource placement is allowed):

Проверить параметр AutoplaceTarget у всех узлов можно так (поле AutoplaceTarget будет пустым у тех узлов, на которых разрешено размещать ресурсы LINSTOR):

shell alias linstor=’kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor’ linstor node list -s AutoplaceTarget

shell alias linstor=’kubectl -n d8-linstor exec -ti deploy/linstor-controller – linstor’ linstor node list -s AutoplaceTarget

Evict Resources from a Node and Subsequently Remove It from LINSTOR and Kubernetes

Выгнать ресурсы с узла с последующим его удалением из LINSTOR и Kubernetes

Run the evict.sh script in interactive mode with the --delete-node mode and specify the node to be removed:

Запустите скрипт evict.sh в интерактивном режиме, указав режим удаления --delete-node:

shell ./evict.sh –delete-node

shell ./evict.sh –delete-node

To run the evict.sh script in non-interactive mode, you need to add the --non-interactive flag when calling it, as well as the name of the node that needs to be removed. In this mode, the script will execute all actions without requesting user confirmation. Example of invocation:

Для запуска скрипта evict.sh в неинтерактивном режиме необходимо добавить флаг --non-interactive при его вызове, а так же имя узла, который необходимо удалить. В этом режиме скрипт выполнит все действия без запроса подтверждения от пользователя. Пример вызова:

shell ./evict.sh –non-interactive –delete-node –node-name “worker-1”

shell ./evict.sh –non-interactive –delete-node –node-name “worker-1”

Note! During the execution, the script will remove the node from both Kubernetes and LINSTOR.

Важно! В процессе выполнения скрипт удалит узел как из Kubernetes, так и из LINSTOR.

In this --delete-node mode, resources are not physically removed from the node. To clean up the node, log in to it and perform the following actions:

В этом режиме ресурсы физически с узла не удаляются. Для зачистки узла необходимо зайти на нее и выполнить следующие действия:

Note! These actions will destroy all your data on the node.

Внимание! Выполнение этих действий приведет к уничтожению всех ваших данных на узле.

  • Get and remove all volume groups from the node that were used for LINSTOR LVM storage pools:
  • Получите список групп томов (vg), которые использовались для LVM-пулов хранения LINSTOR, а затем удалите их с узла:

shell vgs -o+tags | awk ‘NR==1;$NF~/linstor-/’ vgremove -y

shell vgs -o+tags | awk ‘NR==1;$NF~/linstor-/’ vgremove -y <имена групп томов (vg) из вывода предыдущей команды>

  • Get and remove all logical volumes from the node that were used for LINSTOR LVM_THIN storage pools:
  • Получите список логических томов (lv), которые использовались для LVM_THIN пулов хранения LINSTOR, а затем удалите их с узла:

shell lvs -o+tags | awk ‘NR==1;$NF~/linstor-/’ lvremove -y /dev//

shell lvs -o+tags | awk ‘NR==1;$NF~/linstor-/’ lvremove -y /dev/<имя группы томов (vg) из вывода предыдущей команды>/<имя логического тома(lv) из вывода предыдущей команды>

  • Следуйте инструкции, начиная со второго пункта для дальнейшей очистки узла.

Troubleshooting

Диагностика проблем

Problems can arise at different levels of component operation. This simple cheat sheet will help you quickly navigate through the diagnosis of various problems with LINSTOR-created volumes:

Проблемы могут возникнуть на разных уровнях работы компонентов. Эта простая шпаргалка поможет вам быстро сориентироваться при диагностике различных проблем с томами, созданными в LINSTOR:

LINSTOR cheatsheet

LINSTOR шпаргалка

Some typical problems are described here:

Некоторые типичные проблемы описаны ниже.

linstor-node cannot start because the drbd module cannot be loaded

linstor-node не может запуститься из-за невозможности загрузки drbd-модуля

Check the status of the linstor-node Pods:

Проверьте состояние подов linstor-node:

shell kubectl get pod -n d8-linstor -l app=linstor-node

shell kubectl get pod -n d8-linstor -l app=linstor-node

If you see that some of them get stuck in Init:CrashLoopBackOff state, check the logs of kernel-module-injector container:

Если вы видите, что некоторые из них находятся в состоянии Init:CrashLoopBackOff, проверьте логи контейнера kernel-module-injector:

shell kubectl logs -n d8-linstor linstor-node-xxwf9 -c kernel-module-injector

shell kubectl logs -n d8-linstor linstor-node-xxwf9 -c kernel-module-injector

The most likely reasons why it cannot load the kernel module:

Наиболее вероятные причины, почему он не может загрузить модуль ядра:

  • You may already have an in-tree kernel version of the DRBDv8 module loaded when LINSTOR requires DRBDv9. Check loaded module version: cat /proc/drbd. If the file is missing, then the module is not loaded and this is not your case.
  • Возможно, у вас уже загружена in-tree-версия модуля DRBDv8, тогда как LINSTOR требует DRBDv9. Проверить версию загруженного модуля: cat /proc/drbd. Если файл отсутствует, значит, модуль не загружен и проблема не в этом.
  • You have Secure Boot enabled. Since the DRBD module we provide is compiled dynamically for your kernel (similar to dkms), it has no digital sign. We do not currently support running the DRBD module with a Secure Boot configuration.
  • Возможно, у вас включен Secure Boot. Так как модуль DRBD, который мы поставляем, компилируется динамически для вашего ядра (аналог dkms), он не имеет цифровой подписи. На данный момент мы не поддерживаем работу модуля DRBD в конфигурации с Secure Boot.

Pod cannot start with the FailedMount error

Под не может запуститься из-за ошибки FailedMount

Pod is stuck in the ContainerCreating phase

Под завис на стадии ContainerCreating

If the Pod is stuck in the ContainerCreating phase, and you see the following errors in kubectl describe pod:

Если под завис на стадии ContainerCreating, а в выводе kubectl describe pod есть ошибки вида:

text rpc error: code = Internal desc = NodePublishVolume failed for pvc-b3e51b8a-9733-4d9a-bf34-84e0fee3168d: checking for exclusive open failed: wrong medium type, check device health

text rpc error: code = Internal desc = NodePublishVolume failed for pvc-b3e51b8a-9733-4d9a-bf34-84e0fee3168d: checking for exclusive open failed: wrong medium type, check device health

… it means that device is still mounted on one of the other nodes.

значит, устройство все еще смонтировано на одном из других узлов.

To check it, use the following command:

Проверить это можно с помощью следующей команды:

shell linstor resource list -r pvc-b3e51b8a-9733-4d9a-bf34-84e0fee3168d

shell linstor resource list -r pvc-b3e51b8a-9733-4d9a-bf34-84e0fee3168d

The InUse flag will indicate which node the device is being used on.

Флаг InUse укажет, на каком узле используется устройство.

Pod cannot start due to missing CSI driver

Под не может запуститься из-за отсутствия CSI-драйвера

An example error in kubectl describe pod:

Пример ошибки в kubectl describe pod:

text kubernetes.io/csi: attachment for pvc-be5f1991-e0f8-49e1-80c5-ad1174d10023 failed: CSINode b-node0 does not contain driver linstor.csi.linbit.com

text kubernetes.io/csi: attachment for pvc-be5f1991-e0f8-49e1-80c5-ad1174d10023 failed: CSINode b-node0 does not contain driver linstor.csi.linbit.com

Check the status of the linstor-csi-node Pods:

Проверьте состояние подов linstor-csi-node:

shell kubectl get pod -n d8-linstor -l app.kubernetes.io/component=csi-node

shell kubectl get pod -n d8-linstor -l app.kubernetes.io/component=csi-node

Most likely they are stuck in the Init state, waiting for the node to change its status to Online in LINSTOR. Run the following command to check the list of nodes:

Наиболее вероятно, что они зависли в состоянии Init, ожидая, пока узел сменит статус на Online в LINSTOR. Проверьте список узлов с помощью следующей команды:

shell linstor node list

shell linstor node list

If you see any nodes in the EVICTED state, then they have been unavailable for 2 hours, to return them to the cluster, run:

Если вы видите какие-либо узлы в состоянии EVICTED, значит, они были недоступны в течение 2 часов. Чтобы вернуть их в кластер, выполните:

shell linstor node rst

shell linstor node rst

Errors like Input/output error

Ошибки вида Input/Output error

Such errors usually occur at the stage of creating the file system (mkfs).

Такие ошибки обычно возникают на стадии создания файловой системы (mkfs).

Check dmesg on the node where your Pod is running:

Проверьте dmesg на узле, где запускается под:

shell dmesg | grep ‘Remote failed to finish a request within’

shell dmesg | grep ‘Remote failed to finish a request within’

If you get any output (there are lines with the “Remote failed to finish a request within …” parts in the dmesg output), then most likely, your disk subsystem is too slow for the normal functioning of DRBD.

Если вывод команды не пустой (в выводе dmesg есть строки вида «Remote failed to finish a request within …»), скорее всего, ваша дисковая подсистема слишком медленная для нормального функционирования DRBD.