nav-img
Evolution

Эксплуатация

Системные требования

Сервис основан на технологии vhost-user и работает в связке с виртуальными машинами QEMU/KVM. Запуск поддерживается только на гипервизорах с ОС на базе ядра GNU/Linux. Сервис практически не взаимодействует с локальным хранилищем, поскольку все IO-запросы виртуальных машин сразу передаются на выполнение в SDS-кластер. Команды управления сервисом встречаются редко и перезаписывают файлы конфигурации. Из-за особенностей поведения виртуальных машин сервис вынужден производить копирование IO-запросов на запись в память сервиса перед отправкой в кластер, поэтому требуется дополнительная память, что может влиять на пропускную способность сервиса. Количество памяти, выделенной для IO-запросов, контролируется параметром конфигурации o-mem-limit-mb, значение по умолчанию — половина от всей доступной памяти шарда.

Минимальные

Рекомендуемые

ОС

Ubuntu 22.04, SberLinux 8/9

Ubuntu 22.04, SberLinux 8/9

CPU

1 CPU core

4 CPU core

RAM

1 GB

4 GB

Storage

1x NVMe 128GB

1x NVMe 128GB

Network

x1 25Gb (x2 port)

x1 100Gb (x2 port)

Подготовка вычислительного узла к работе

Установка ПО

Сервис vhostd поставляется в составе комплекса программ Cloud SDS. Исполняемый файл и типовые файлы конфигурации растространяются в виде deb и rpm пакетов для ОС Ubuntu и ОС Sberlinux соответственно с именем storage-vhostd. Установка осуществляется из репозитория штатными средствами ОС. Пример установки пакета с зависимостями из внутреннего репозитория Cloud.ru для ОС Ubuntu 22.04:

curl -fsSL https://pkg.sbercloud.tech/artifactory/api/security/keypair/public/repositories/sds-deb | sudo apt-key add -
echo 'deb https://pkg.sbercloud.tech/artifactory/sds-deb jammy unstable' | sudo tee /etc/apt/sources.list.d/sds-deb.list
sudo apt update
sudo apt install storage-vhostd

Настройка HugePages

Сервис vhostd использует технологию общей памяти (shared memory), чтобы общаться с процессами виртуальных машин. В общем случае QEMU можно настроить хранить память виртуальной машины в обычной памяти из малых страниц, и сервис vhostd будет с ними работать, но рекомендуется включить поддержку больших страниц памяти (Huge Pages) и использовать их при запуске виртуальных машин. Для включения больших страниц необходимо передать специальный флаг на старте ОС, для чего в системах на базе загрузчика GRUB в файл /etc/default/grub добавьте в строку GRUB_CMDLINE_LINUX параметры default_hugepagesz, hugepagesz, hugepages, transparent_hugepage.

Пример с 2МБ страницами:

GRUB_CMDLINE_LINUX="default_hugepagesz=2M hugepagesz=2M hugepages=2048 transparent_hugepage=never"

Выделяется 2048 больших страниц размером по 2 МБ, таким образом всего под большие страницы будет выделено 4096 МБ.

В следующем примере выделяется 10 страниц по 1 ГБ:

GRUB_CMDLINE_LINUX="hugepagesz=1G hugepages=10 default_hugepagesz=1G transparent_hugepage=never"

Описание и назначение различных параметров ядра при настройке больших страниц выходят за рамки данного руководства. Подробнее в документации:

После обновления настроек запуска ядра выполните команду update-grub и перезагрузить ОС, чтобы настройки применились.

Инициализация хоста

Каждый участник SDS-кластера имеет свой уникальный ID. Сервера метаданных различают клиентов по их ID. Если на настраиваемом хосте нет других сервисов SDS или сервис vhostd настраивается первым — необходимо произвести инициализацию хоста.

Выполните команду storage host init:

storage host init --ip.public 192.168.50.100

В результате выполнения команды будет создан файл /etc/storage/host.yml.

Получение файла mds_list.yml

Сервису vhostd необходим первоначальный файл mds_list.yml, откуда сервис сможет узнать о структуре кластера, с которым предстоит работать. Это можно сделать двумя способами — скопировать с другой ноды или испольховать команду storage mds list:

# Копируем mds_list.yml с другой ноды
scp OtherNode:/etc/storage/auth.yml /etc/storage/auth.yml
# Создаем файл локально зная путь к одному из серверов метаданных
storage --cluster 4312 --mds.address 192.168.50.1 --mds.port 60002 user login --name admin --password passwd # В результате будет создан файл /etc/storage/auth.yml
storage --cluster 4312 --mds.address 192.168.50.1 --mds.port 60002 --membership /etc/storage/mds_list.yml mds list --save # Сохранит список серверов метаданных в файл /etc/storage/mds_list.yml
rm /etc/storage/auth.yml # Сервис vhostd не производит управляющих операций с SDS-кластером, поэтому не нуждается в файле auth.yml

Настройка прав доступа

Одной из ключевых задач при настройке взаимодействия между компонентами libvirt/qemu и vhostd является корректная конфигурация прав доступа. По умолчанию vhostd запускается под управлением пользователя storage, в то время как libvirt/qemu работают от имени пользователя libvirt. Реализация Unix domain sockets в Linux требует наличия прав на чтение и запись (RW). По умолчанию vhostd создает сокеты с правами доступа 0644:

  • Чтение и запись для владельца (RW).

  • Только чтение для группы и остальных пользователей (R).

Libvirtd запускает экземпляры QEMU с включенным профилем AppArmor, что ограничивает доступ к сокетам в директории /var/lib/storage.

Для обеспечения корректной работы выполните следующие действия:

  1. Добавьте пользователя libvirt в группу storage.

  2. Запустите сервер vhostd: - с флагом --unix-sock-perms 0660. - или укажите в конфигурационном файле /etc/storage/vhostd/vhost.conf опцию unix-sock-perms=0660.

  3. Настройте в /etc/apparmor.d/abstractions/libvirt-qemu доступ на RW до файлов в директории сокетов:

    echo '/var/lib/storage/*.sock rw,' >> /etc/apparmor.d/local/abstractions/libvirt-qemu

При работе в контейнерной среде последовательность действий может отличаться, однако общий принцип настройки прав доступа остается неизменным.

Поддержка SELinux

Операционные системы на базе SberLinux используют механизм безопасности SELinux для разграничения доступа к системным ресурсам. Аналогично настройке прав доступа к сокетам в Ubuntu, в SELinux необходимо правильно настроить модуль Type Enforcement.

Пример модуля Type Enforcement для SELinux:

module qemu-kvm 1.0;
require {
type svirt_t;
type unconfined_service_t;
type tmpfs_t;
type var_lib_t;
type sysctl_vm_t;
class file { getattr map open read };
class sock_file write;
class unix_stream_socket connectto;
}
#============= svirt_t ==============
#!!!! This avc is allowed in the current policy
allow svirt_t sysctl_vm_t:file { open read };
allow svirt_t sysctl_vm_t:file getattr;
#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'
allow svirt_t tmpfs_t:file map;
#!!!! This avc is allowed in the current policy
allow svirt_t unconfined_service_t:unix_stream_socket connectto;
#!!!! This avc is allowed in the current policy
allow svirt_t var_lib_t:sock_file write;

Для применения модуля выполните следующие команды:

sudo semodule -r qemu-kvm
checkmodule -M -m -o qemu-kvm.mod $QEMU_KVM_TE
semodule_package -o qemu-kvm.pp -m qemu-kvm.mod
sudo semodule -i qemu-kvm.pp

Где $QEMU_KVM_TE — файл, содержащий текст из SELinux Type Enforcement Unit Example. Подробная документация по SELinux доступна по ссылке.

Настройка поддержки post-copy миграции (опционально)

Режим миграции post-copy является более сложным по сравнению с pre-copy, требует дополнительных прав доступа и может представлять определенные риски. При недостаточно качественном сетевом соединении между гипервизорами в режиме post-copy могут наблюдаться значительные снижения производительности виртуальных машин. В случае post-copy — ряд страниц RAM оказывается недоступен и перед продолжением работы должен быть загружен через сеть.

Поддержка post-copy обеспечивается механизмом ядра Linux под названием userfaultfd, который позволяет настраивать специальную обработку определенных областей памяти. При попытке доступа к защищенным страницам памяти ядро передает управление приложению, которое приостанавливает выполнение виртуальной машины до получения требуемых страниц с удаленного гипервизора.

По умолчанию доступ к механизму userfaultfd имеют только пользователи с правами root. Для предоставления доступа обычным пользователям необходимо изменить параметр ядра vm.unprivileged_userfaultfd:

sudo sysctl vm.unprivileged_userfaultfd=1

Также доступ можно контролировать через механизм capabilities, предоставив пользователю права CAP_SYS_PTRACE.

В новых версиях ядра (начиная с Ubuntu 22.04 HWE Linux 6.1) появилось устройство /dev/userfaultfd, позволяющее более тонко настраивать доступ к функционалу userfaultfd. Подробнее в документации userfaultfd.

Сервис vhostd проверяет доступность post-copy в следующем порядке:

  • Попытка доступа через системный вызов SYS_userfaultd.

  • Попытка доступа через устройство /dev/userfaultd.

  • Если оба способа не сработали, то postcopy недоступен.

В логах сервиса отображается статус доступности post-copy:

  • «Post-copy migration is available» (уровень info) — при успешной проверке.

  • «Post-copy migration forbidden ({причина})» (уровень warn) — при недоступности.

Если в логах в ответ на команду VHOST_USER_GET_PROTOCOL_FEATURES появляется строка VHOST_USER_PROTOCOL_F_PAGEFAULT, то это значит, что поддержка post-copy доступна на уровне vhostd.

Поскольку сервер vhostd может выполняться с разными правами для гипервизора QEMU и libvirt — post-copy и доступ до подсистемы userfaultd может быть открыт для vhostd, но закрыт для QEMU. В этом случае при попытке postcopy миграции будут видны сообщения вида: «error: internal error: unable to execute QEMU command „migrate-set-capabilities“: Postcopy is not supported», в логе мигрирующей VM также можно будет встретить сообщения типа postcopy_ram_supported_by_host: userfaultfd not available: Operation not permitted, что означает, что гипервизору QEMU не достаточно прав для post-copy.

Выбор post-copy миграции осуществляется на этапе архитектуры системы в зависимости от политик безопасности и потребностей пользователя.

Управление сервисом storage-vhostd.service

После завершения установки и настройки сервис управляется стандартными средствами systemd.

Запуск сервиса vhostd:

systemctl start storage-vhostd.service
systemctl enable storage-vhostd.service

Перезапуск в случае критической ошибки:

systemctl reset-failed storage-vhostd
systemctl restart storage-vhostd

Управление сервисом с использованием приложения storage

Приложение Storage из пакета storage-common используется для управления сервисом vhostd. В отличие от других компонентов Cloud SDS (mds, csd), приложение Storage взаимодействует только с локальным сервисом vhostd.

Для передачи команд используется бинарный RPC-протокол с простой схемой версионирования. Каждая конкретная версия приложения Storage и сервиса vhostd работают только с одной определенной версией протокола. Архитектура предполагает синхронное обновление сервиса vhostd и приложения Storage на каждой вычислительной ноде.

В таблице ниже приведены доступные версии RPC между Storage и vhostd, а также версии, в которых происходили обновления:

Версия RPC

Описание

Версия vhostd

Версия storage

ABIv0

Первоначальная версия, представлены команды attach, detach, list, stop

0.1.8

0.0.136

ABIv1

Добавлена поддержка выбора типа lease для команды attach

0.1.57

0.1.50

ABIv2

Добавлена возможность выбирать имя сокета для команды attach

0.1.78

0.1.59

ABIv3

Команда list возвращает информацию о номере шарда конкретной привязки

1.1.28

1.1.27

ABIv4

Добавлена поддержка работы с множеством кластеров

1.1.33

1.1.31

ABIv5

Добавлена поддержка установки пользовательских device ID

1.4.14 (1.3.63)

1.4.6 (1.3.63)

В случае несовпадения версий RPC между Storage и vhostd команда отклоняется с сообщением об ошибке (Invalid request method_version). В текущей версии ABIv4 поддерживаются 4 команды: attach, detach, list, stop. Команды, изменяющие состояние сервиса (attach, detach), являются идемпотентными. Описание команд приведено ниже.

Команда attach

Описание

Добавляет новую привязку диска к сокету. Единственным обязательным параметром является volume, который задает ID диска в кластере. Остальные параметры являются необязательными:

  • Параметр cluster или membership указывается для определения кластера диска. По умолчанию используется ID кластера из файла /etc/storage/mds_list.yml.

  • Параметр lease определяет тип владения диском. В большинстве случаев (99.98%) используется значение exclusive. Обычные файловые системы не готовы к тому, что данные в них могут меняться конкурентно, shared-rw/shared-ro могут применяться только в специальных случаях.

  • Параметр socket позволяет задать имя сокета вместо автоматически генерируемого UUID.

Несколько идентичных команд привязки завершатся успещно, если первая из них завершилась успешно. Ошибки могут быть разными, если состояние сервиса изменилось между реальными вызовами команды.

Начиная с версии 1.2.43 можно указывать полный путь к сокету, при условии что директория пути соответствует параметру конфигурации unix-sock-prefix.

Начиная с версии 1.4.6 (1.3.63) поддерживается установка пользовательского имени устройства диска, которое будет отображаться внутри виртуальной машины:

user@host:/dev/disk/by-id$ ls
virtio-custom-id virtio-custom-id-part1

Параметры

  • lease — тип владения диском (exclusive, shared-rw, shared-ro);

  • socket — имя файла или полный путь до unix-domain сокета привязки;

  • volume — ID диска SDS;

  • device — имя устройства внутри VM (начиная с версии 1.4.6).

Результат

  • Полный путь к созданному сокету при успешном выполнении.

  • Если передан полный путь до сокета и он не совпадает с параметром конфигурации unix-sock-prefix, сервис вернет ошибку «Invalid socket directory».

  • Если передан неизвестный ID SDS-кластера, то сервис вернет ошибку «Unknown cluster ID»

  • Если передан неправильный ID SDS-кластера, то сервис вернет ошибку «Provide valid cluster ID».

  • Если путь до сокета уже зарегистрирован для другого диска или с другими настройками, сервис вернет ошибку «Socket at (…) has been already attached with different settings», где … — полный путь до сокета.

  • (До 1.4.6 / 1.3.63) device == volume (Начиная с 1.4.6 / 1.3.63) если device указан, то внутри VM будет отображаться он, иначе поведение как до 1.4.6 / 1.3.63 (device == volume).

Примеры

Полная форма:

storage \
[(--cluster $CLUSTER_ID)|(--membership $MEMBERSHIP_FILE)] \
vhost attach \
[--lease $LEASE_TYPE][--socket $SOCKET_NAME] \
--volume $VOLUME_ID
--device $DEVICE_ID

Пример:

storage \
--cluster 4312 \
vhost attach \
--lease exclusive \
--socket volume.sock \
--volume 0x1000
--device custom-id

Команда detach

Описание

Удаляет привязку по пути к сокету. Обязательным параметром является socket, который должен содержать полный путь к точке привязки. Оригинальный дизайн команды предполагает, что на вход принимается результат команды attach. То есть, переданное из attach передается в detach для удаления точки привязки.

Начиная с версии 1.2.43 поведение команды было изменено:

  • Старое поведение (до 1.2.43): При передаче имени сокета, а не его полного пути, имя сравнивается с полными путями всех привязок. Если сервис не находит совпадений, то предполагается, что сокет мог быть удален ранее и в списке привязок такой привязки (только с именем сокета) нет. Сервис возвращает безошибочный ответ, чтобы обеспечить идемпотентное поведение.

  • Новое поведение (начина с 1.2.43): При передаче имени сокета, а не его полного пути, имя достраивается до полного добавлением значения параметра конфигурации unix-sock-prefix. Производится сравнение со всеми привязками. Если совпадение найдено, привязка удаляется и сервис возвращает безошибочный ответ. Если привязки в таком виде не найдено, то сервис считает, что привязку могли удалить ранее и возвращает безошибочный ответ, чтобы обеспечить идемпотентное поведение.

Параметры

Socket — полный путь к UNIX-сокету привязки.

Результат

  • Если привязка существует, она удаляется, удаляется файл unix-domain сокета и возвращается код успеха.

  • Если привязка не существует, сервис предполагает, что она могла существовать и все равно возвращает код успеха.

Примеры

Полная форма:

storage vhost detach \
--socket $SOCKET_PATH|$SOCKET_NAME

Пример:

storage vhost detach \
--socket /var/lib/storage/volume.sock

Команда list

Описание

Отображает список активных привязок.

Параметры

Отсутствуют.

Результат

В случае успеха возвращает список из всех зарегистрированных привязок:

  • VOLUME — ID диска SDS;

  • SOCKET — полный путь до файла сокета привязки;

  • LEASE — тип владения диском;

  • SHARD — ID шарда обработки запросов;

  • CLUSTER — ID кластера привязки.

Примеры

Полная форма и пример:

storage vhost list

Команда stop

Описание

Выполняет штатную остановку сервиса vhostd.

Параметры

Отсутствуют.

Примеры

Полная форма и пример:

storage vhost stop

Процедура обновления сервиса

В ходе эксплуатации могут возникнуть причины обновления версии сервиса — добавление функционала, исправление ошибок, окончание срока поддержки версии. Общая процедура обновления элементов кластера предполагает обновление сначала серверных компонентов (storage-csd, storage-mds), затем обновление клиентских приложений (storage-vhostd, storage-common). Совместимость между клиентскими и серверными частями кластера гарантируется в формате, что сервер ожидает возможность общения с клиентами более старых версий. Поддержка старых версий клиентов со стороны сервера заканчивается, когда заканчивается срок поддержки версии клиента, после чего нет гарантии, что после обновления серверов сильно устаревший клиент сможет подключиться.

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

  1. Проверьте совместимость новых версий компонентов кластера (csd, mds), клиента (vhostd) и управляющей утилиты (Storage).

  2. Выполните миграцию виртуальных машин с обновляемого хоста.

  3. Обновите ПО (apt update``и ``apt upgrade или установите новую версию контейнера с сервисом).

  4. Проверьте корректность файлов конфигурации, привязок, списков MDS и хоста (seastar.conf, vhost.conf, attachments.yml, mds_list.yml, host.yml).

  5. Запустите сервис/контейнер (systemctl start storage-vhostd.service).

  6. Проверьте успешный перезапуск сервиса.

    $ systemctl status storage-vhostd.service
    ● storage-vhostd.service - SDS vhost server daemon
    Loaded: loaded (/etc/systemd/system/storage-vhostd.service; enabled; vendor preset: enabled)
    Active: active (running) since Fri 2024-02-16 13:29:34 MSK; 10s ago
    Main PID: 648049 (vhostd)
    Tasks: 6 (limit: 28676)
    Memory: 77.3M
    CPU: 85ms
    CGroup: /system.slice/storage-vhostd.service
    └─648049 /usr/bin/vhostd
    Feb 16 13:29:34 tzh systemd[1]: Started SDS vhost server daemon.
  7. Запустите тестовую виртуальную машину для проверки работоспособности. После проверки тестовую виртуальную машину можно удалить.

  8. Выполните обратную миграцию виртуальных машин с контролем работоспособности.

В экстренных случаях возможен жесткий перезапуск сервиса vhostd без миграции виртуальных машин. Это возможно, поскольку состояние virtqueue хранится на стороне процесса виртуальной машины. В этом случае операции ввода-вывода будут приостановлены до восстановления работы сервиса. Обновление через миграцию является рекомендуемым способом обновления.

Интеграция с QEMU

Технология vhost-user поддерживается начиная с QEMU версии 2.12.0. В дистрибутиве Ubuntu 22.04 по умолчанию поставляется QEMU версии 6.2. Для подключения дисков SDS к QEMU используется тип устройства vhost-user-blk-pci. ОС виртуальной машины должна содержать драйвер virtio-blk (см. выше ссылки на драйверы). QEMU должен быть настроен так, чтобы выделить память для виртуальной машины в shared-режиме. Для повышения производительности рекомендуется использовать технологию HugePages.

Минимальный пример запуска QEMU с диском SDS, подключенным через vhostd:

QEMU=qemu-system-x86_64
VHOST_SOCK=/var/lib/storage/sds-disk.sock
VHOST_CHAR_DEV=char0
VHOST_BLK_DEV=blk0
MEM_DEV=mem
MEM_SIZE=1G
CPU_COUNT=1
$QEMU \
-enable-kvm \
-cpu host \
-m $MEM_SIZE -smp $CPU_COUNT \
-object memory-backend-file,id=$MEM_DEV,size=$MEM_SIZE,mem-path=/dev/hugepages,share=on \
-numa node,memdev=$MEM_DEV \
-chardev socket,id=$VHOST_CHAR_DEV,path=$VHOST_SOCK \
-device vhost-user-blk-pci,id=$VHOST_BLK_DEV,chardev=$VHOST_CHAR_DEV,num-queues=$CPU_COUNT

Подробнее о QEMU читайте в соответствующей документации.

Интеграция с libvirt

Поддержка блочных устройств vhost-user появилась в libvirt версии 7.1. В Ubuntu 22.04 устанавливается libvirt версии 8.0. Пример конфигурации диска vhost-user в libvirt:

<disk type='vhostuser' device='disk'>
<driver name='qemu' type='raw'/>
<source type='unix' path='/var/lib/storage/sds-disk.sock'>
<reconnect enabled='yes' timeout='1'/>
</source>
<target dev='vda' bus='virtio'/>
</disk>

В примере дано описание vhost-user диска, подключение к которому производится через unix-domain сокет /var/lib/storage/sds-disk.sock. Автоматическое переподключение при потере соединения происходит через 1 секунду. Диск устанавливается в шину virtio на первое место. Полное описание конфигурации и значение полей представлено в документации libvirt.

Полный пример конфигурации виртуальной машины:

<domain type='kvm'>
<name>Example</name>
<memory unit='MiB'>1024</memory>
<currentMemory unit='MiB'>1024</currentMemory>
<memoryBacking>
<hugepages />
</memoryBacking>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-6.2'>hvm</type>
<boot dev='hd' />
</os>
<cpu mode='host-passthrough'>
<numa>
<cell id='0' cpus='0' memory='1024' unit='MiB' memAccess='shared'/>
</numa>
</cpu>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='vhostuser' device='disk' snapshot='no'>
<driver name='qemu' type='raw' />
<source type='unix' path='/var/lib/storage/sds-disk.sock' />
<target dev='vda' bus='virtio' />
</disk>
</devices>
</domain>

В примере описана виртуальная машина с 1 процессором, 1ГБ памяти и одним диском SDS.

Общая схема интеграции сервиса vhostd с внешними системами

Для создания комплексного решения предоставления доступа к Cloud SDS через сервис vhostd требуется реализовать несколько ключевых компонентов:

  • Настроить виртуальные машины и их подключение к сервису vhostd.

  • Управлять дисками через утилиту storage volume (создание, клонирование, удаление).

  • Организовать загрузки операционных систем на диски.

При работе с ISO-образом ОС необходимо продумать схему доставки и загрузки его в виртуальной машине:

  • Подключить ISO-образ локально в эмулируемый CD-привод. Установщик ОС должен поддерживать диски virtio, после чего установка не отличается от работы с локальным диском.

  • Загрузка образов через PXE. Ситуация аналогичная с локальным CD-приводом, но доступ к образам может быть реализован по сети.

Готовые образы виртуальных машин обычно строятся на основе приложения cloud-init. Приложение встраивается в процесс старта ОС и выполняет рутинные операции по первоначальной настройке ОС — расширяет диск, добавляет пользователей, прописывает ключи. Конфигурация cloud-init передается в виртуальную машину в виде ISO-образа с несколькими описания действий. Подробности работы с cloud-init описаны в соответствующей документации. Аналогичные решения bsd-cloudinit для BSD-систем и cloudbase-init для Windows имеют свои особенности.

Готовый образ виртуальной машины необходимо загрузить на соответствующий диск SDS заранее, до ее запуска. В комплексе программ Cloud SDS есть утилита sbdctl, которая позволяет производить прямой доступ к дискам SDS, команды import/export, write/read позволяют производить полную или частичную перезапись данных на дисках SDS. Подробности описаны в документации к утилите sbdctl.

Пример загрузки файла образа на диск SDS с помощью sbdctl:

sbdctl import --volume-id 0xda20facb746c7996 --input os-disk.img --format raw
Внимание

Необходимо отметить, что образы дисков хранятся в SDS в простом бинарном (raw) формате и читаются также. Если загрузить образы qcow2, vmdk и аналоги в SDS без их предварительной конвертации, виртуальная машина не сможет с ними работать, потому что сервис vhostd предоставляет прямой доступ к хранимым данным и не производит конвертации на ходу.

В качестве примера интеграции с внешней системой реализованы драйверы Cinder, Nova, Glance для интеграции Cloud SDS с OpenStack. Подробное описание работы драйверов выходит за рамки данного руководства. Для получения дополнительной информации обратитесь к специализированной документации.

Логирование и анализ логов

Сервис vhostd логирует все действия приложения, внешние команды и взаимодействие с виртуальными машинами. В зависимости от конфигурации сервиса, лог пишется либо в консоль, либо в файлы в указанную директорию. Файлы логов на ходу сжимаются алгоримтом zstd. Когда размер файла логов становится больше параметра конфигурации log-rotate-file-size-mb, файл лога ротируется. Если число файлов логов после ротации становится больше log-rotate-file-cnt, наиболее старый файл удаляется. Каждый шард сервиса ведет свой файл лога.

Пример:

# В директории /var/log/storage/vhostd файлы логов
$ ls /var/log/storage/vhostd
vhost.0.log.zst # Лог 0-ого шарда
vhost.1.log.zst # Лог 1-ого шарда
# Через какое-то время размер файла лога переходит через границу, происходит ротация
$ ls /var/log/storage/vhostd
vhost.0.log.zst # Актуальный лог 0-ого шарда
vhost.0.log.0.zst # Прошлый лог 0-ого шарда
vhost.1.log.zst # Актуальный лог 1-ого шарда
vhost.1.log.0.zst # Прошлый лог 1-ого шарда
# Следующая ротация приведет к тому, что файлы с суффиксом 0.zst будут переименованы в файлы 1.zst, прошлый актуальный лог будет переименован с суффиксом 0.zst
$ ls /var/log/storage/vhostd
vhost.0.log.zst # Актуальный лог 0-ого шарда
vhost.0.log.0.zst # Прошлый лог 0-ого шарда
vhost.0.log.1.zst # Файл, который раньше был vhost.0.log.0.zst лог 0-ого шарда
vhost.1.log.zst # Актуальный лог 1-ого шарда
vhost.1.log.0.zst # Прошлый лог 1-ого шарда
vhost.1.log.1.zst # Файл, который раньше был vhost.1.log.0.zst лог 1-ого шарда

Для просмотра логов можно использовать утилиты zstdless/zstdcat:

$ zstdcat /var/log/storage/vhostd/vhost.0.log.zst
# Log session started. TZ: +0300
# version:1.2.53 commit:f4633fcf seastar:1.0 build:debug timestamp:2024-02-14T05:46:45Z flags:mod,clang-16.0.6,asan,ubsan branch:master
INFO 2024-02-14 08:55:20.754463 sds/vhost/main - setup MDS provider...
INFO 2024-02-14 08:59:14.223526 sds/mds/client - mds client options:client_id: 20a8cd7be37cf921, membership: ["/etc/storage/mds_list.yml"]
INFO 2024-02-14 08:59:14.226467 seastar - Created fair group , capacity rate 43980465111:43980465111, limit 16777216000, rate 16777216 (factor 1), threshold 1
INFO 2024-02-14 08:59:14.265475 sds/vhost/main - Registered Clusters:
321/622B0181-EF4A-44E1-AF80-08AB05092A54
INFO 2024-02-14 08:59:14.265515 sds/vhost/main - setup vhost service...
INFO 2024-02-14 08:59:14.265616 sds/vhost/service/provider - checking postcopy support...
INFO 2024-02-14 08:59:14.267224 sds/vhost/processor - Post-copy migration is available
INFO 2024-02-14 08:59:14.267333 sds/vhost/service/provider - load attachments...
INFO 2024-02-14 08:59:14.267383 sds/vhost/service/provider - cluster mode: single
INFO 2024-02-14 08:59:14.276621 sds/vhost/rpc - RPC server starts at: (127.0.0.1:60100)
INFO 2024-02-14 08:59:14.281006 sds/vhost/main - setup monitoring...
INFO 2024-02-14 08:59:14.295837 sds/vhost/attachment - setup bdev (/var/lib/storage/F400BCFB-7B9D-4117-89D6-AD4DFFD4C349.sock)->(0x0000000000100000@321)
INFO 2024-02-14 08:59:14.295882 sds/vhost/attachment - setup accepting socket at /var/lib/storage/F400BCFB-7B9D-4117-89D6-AD4DFFD4C349.sock
INFO 2024-02-14 08:59:14.296652 sds/vhost/attachment - [/var/lib/storage/F400BCFB-7B9D-4117-89D6-AD4DFFD4C349.sock] wait for clients... on (21)
INFO 2024-02-14 08:59:14.296957 sds/vhost/attachment - setup bdev (/var/lib/storage/test_vol.sock)->(0xee270d63316001f3@321)
INFO 2024-02-14 08:59:14.296983 sds/vhost/attachment - setup accepting socket at /var/lib/storage/test_vol.sock
INFO 2024-02-14 08:59:14.298156 sds/vhost/attachment - [/var/lib/storage/test_vol.sock] wait for clients... on (23)
INFO 2024-02-14 08:59:14.298262 sds/vhost/service - vhost-service running...
INFO 2024-02-14 09:20:49.630160 sds/vhost/service/provider - detach volume at /var/lib/storage/F400BCFB-7B9D-4117-89D6-AD4DFFD4C349.sock
INFO 2024-02-14 09:20:49.631393 sds/vhost/attachment - bdev task(/var/lib/storage/F400BCFB-7B9D-4117-89D6-AD4DFFD4C349.sock) aborted...
INFO 2024-02-14 09:42:21.183924 sds/vhost/attachment - got client from (23)! fd: (45)
INFO 2024-02-14 09:42:21.184318 sds/vhost/processor - [cluster:321,vol:ee270d63316001f3] init vhost device
INFO 2024-02-14 09:42:21.184344 sds/vhost/processor - [cluster:321,vol:ee270d63316001f3] control request processing started.
INFO 2024-02-14 09:42:21.186130 sds/vhost/processor - [cluster:321,vol:ee270d63316001f3] <- VHOST_USER_GET_FEATURES(1) [0 bytes] (fds: () data: ())
INFO 2024-02-14 09:42:21.186248 sds/vhost/processor - [cluster:321,vol:ee270d63316001f3] -> VHOST_USER_GET_FEATURES(1) [8 bytes] (fds: () data: (VIRTIO_BLK_F_BARRIER VIRTIO_BLK_F_SIZE_MAX VIRTIO_BLK_F_SEG_MAX VIRTIO_BLK_F_BLK_SIZE VIRTIO_BLK_F_FLUSH VIRTIO_BLK_F_TOPOLOGY VIRTIO_BLK_F_MQ VIRTIO_BLK_F_DISCARD VIRTIO_BLK_F_WRITE_ZEROES VIRTIO_F_NOTIFY_ON_EMPTY VHOST_F_LOG_ALL VIRTIO_RING_F_INDIRECT_DESC VIRTIO_RING_F_EVENT_IDX VHOST_USER_F_PROTOCOL_FEATURES VIRTIO_F_VERSION_1 ))
...

Из примера видно, что каждый файл лога начинается с двух строк описания/комментария, где TZ — часовой пояс, в котором представлено время лога, version — версия vhostd, timestamp — время и дата сборки.

Сообщения в логе имеют формат:

Уровень лога

Дата

Время

Подсистема

Сообщение

INFO

2024-02-14

08:59:14.265515

sds/vhost/main

setup vhost service…

Внимание

Чтение файлов конфигурации и перевод логирования в файл происходит не на старте приложения, часть сообщений может быть выведена в консоль или записана в /var/log/storage/vhostd.stdout.

Провайдер метрик Prometheus

Сервис vhostd запускает на порту 9991 HTTP-сервер, предоставлящий метрики, совместимые с ПО Prometheus. Проверить работу сервиса можно командой curl:

$ curl --silent http://192.168.100.10:9991/metrics
# HELP sds_vhostd_alien_receive_batch_queue_length Current receive batch queue length
# TYPE sds_vhostd_alien_receive_batch_queue_length gauge
sds_vhostd_alien_receive_batch_queue_length{client_id="0xaba8cd7be37cf921",shard="0"} 0.000000
sds_vhostd_alien_receive_batch_queue_length{client_id="0xaba8cd7be37cf921",shard="1"} 0.000000
# HELP sds_vhostd_alien_total_received_messages Total number of received messages
# TYPE sds_vhostd_alien_total_received_messages counter
sds_vhostd_alien_total_received_messages{client_id="0xaba8cd7be37cf921",shard="0"} 0
sds_vhostd_alien_total_received_messages{client_id="0xaba8cd7be37cf921",shard="1"} 0
# HELP sds_vhostd_alien_total_sent_messages Total number of sent messages
# TYPE sds_vhostd_alien_total_sent_messages counter
sds_vhostd_alien_total_sent_messages{client_id="0xaba8cd7be37cf921",shard="0"} 0
sds_vhostd_alien_total_sent_messages{client_id="0xaba8cd7be37cf921",shard="1"} 0
# HELP sds_vhostd_client_bytes_total Total number of bytes processed
# TYPE sds_vhostd_client_bytes_total counter
sds_vhostd_client_bytes_total{client_id="0xaba8cd7be37cf921",shard="0",type="caws"} 0
sds_vhostd_client_bytes_total{client_id="0xaba8cd7be37cf921",shard="0",type="reads"} 1536
sds_vhostd_client_bytes_total{client_id="0xaba8cd7be37cf921",shard="0",type="writes"} 0
...
sds_vhostd_service_status{client_id="0xaba8cd7be37cf921",shard="0"} 1.000000
sds_vhostd_service_status{client_id="0xaba8cd7be37cf921",shard="1"} 1.000000
# HELP sds_vhostd_stall_detector_reported Total number of reported stalls, look in the traces for the exact reason
# TYPE sds_vhostd_stall_detector_reported counter
sds_vhostd_stall_detector_reported{client_id="0xaba8cd7be37cf921",shard="0"} 0
sds_vhostd_stall_detector_reported{client_id="0xaba8cd7be37cf921",shard="1"} 0
# HELP sds_vhostd_volumes_attached_currently Number of volumes currently attached to this vhostd instance on this shard
# TYPE sds_vhostd_volumes_attached_currently gauge
sds_vhostd_volumes_attached_currently{client_id="0xaba8cd7be37cf921",shard="0"} 2.000000
sds_vhostd_volumes_attached_currently{client_id="0xaba8cd7be37cf921",shard="1"} 1.000000
# HELP sds_vhostd_volumes_attached_total Total number of volumes attached to this vhostd instance on this shard
# TYPE sds_vhostd_volumes_attached_total counter
sds_vhostd_volumes_attached_total{client_id="0xaba8cd7be37cf921",shard="0"} 6
sds_vhostd_volumes_attached_total{client_id="0xaba8cd7be37cf921",shard="1"} 1
# HELP sds_vhostd_volumes_opened_currently Number of volumes currently opened on this shard
# TYPE sds_vhostd_volumes_opened_currently gauge
sds_vhostd_volumes_opened_currently{client_id="0xaba8cd7be37cf921",shard="0"} 1.000000
# HELP sds_vhostd_volumes_opened_total Total number of volumes ever opened on this shard
# TYPE sds_vhostd_volumes_opened_total counter
sds_vhostd_volumes_opened_total{client_id="0xaba8cd7be37cf921",shard="0"} 4

Избранные метрики vhostd и их описание

Метрики vhostd начинаются с префикса sds_vhostd_ , затем идет имя метрики. vhostd — многопоточное приложение, метрики каждого потока учитываются отдельно, определить к какому потоку относится данная метрика позволяет атрибут "shard". Он есть у большинства метрик, кроме тех, которые характеризуют сервер в целом. Большинство метрики имеют атрибут client_id — это ID самого процесса сервера, по которому его идентифицирует SDS-кластер. Любой диск, используемый заданным экземпляром сервера vhostd, на стороне SDS закреплен за указанным client_id. У метрик, связанных с дисками, есть атрибут volume_id — это уникальный идентификатор данного диска внутри SDS-кластера. У метрик, связанных с IO-командами, есть атрибут type, описывающий к какой IO-команде принадлежит данная метрика, есть следующие команды: caws, reads, writes, flushes, unmaps.

В таблице ниже приведены основные доступные метрики без общего префикса sds_vhostd_, характерные атрибуты метрики представлены в столбце «Атрибуты»:

Метрика

Атрибуты

Тип

Описание

client_bytes_total

client_id, shard, type

Счетчик

Общее число байт для заданной IO-команды

client_data_size*

client_id, shard, type

Гистограмма

Общее число байт для заданной IO-команды заданного размера

client_errors_total

client_id, shard, type

Счетчик

Число ошибок IO-команд

client_latency_us

client_id, shard, type

Гистограмма

Задержка выполнения IO-команд

client_requests_total

client_id, shard, type

Счетчик

Общее число IO-команд

client_unaligned_requests

client_id, shard, type

Счетчик

Общее число невыровненных IO-команд

client_volume_bytes_total

client_id, shard, type, volume_id

Счетчик

Общее число байт для заданной IO-команды на заданный диск

client_volume_data_size

client_id, shard, type, volume_id

Гистограмма

Общее число байт для заданной IO-команды заданного размера на заданный диск

client_volume_errors_total

client_id, shard, type, volume_id

Счетчик

Число ошибок IO-команд на заданный диск

client_volume_latency_us

client_id, shard, type, volume_id

Гистограмма

Задержка выполнения IO-команд на заданный диск

client_volume_requests_total

client_id, shard, type, volume_id

Счетчик

Общее число IO-команд на диск

client_volume_unaligned_requests_total

client_id, shard, type, volume_id

Счетчик

Общее число невыровненных IO-команд на диск

io_req_in_queue

client_id, shard

Индикатор

Текущее число IO-команд в очереди на выполнение

io_req_inflight

client_id, shard

Индикатор

Текущее число выполняемых IO-команд

io_req_memory_in_use

client_id, shard

Индикатор

Количество памяти шарда, используемое для IO-команд

io_req_total

client_id, shard

Счетчик

Общее число команд IO-команд, требующих дополнительной памяти

memory_allocated_memory

client_id, shard

Индикатор

Количество выделенной памяти шарда в байтах

memory_free_memory

client_id, shard

Индикатор

Количество свободной памяти шарда в байтах

memory_total_memory

client_id, shard

Индикатор

Общее количество доступной памяти у шарда

service_panic_total

client_id, shard

Счетчик

Общее число ошибок virtio (PanicDevice), приводящих к останову обработки IO с диска для VM

service_status

client_id, shard

Индикатор

1 — если сервис на шарде работает, NaN — если сервис на шарде не работает

volumes_attached_currently

client_id, shard

Индикатор

Количество привязанных дисков к сервису по шардам

volumes_attached_total

client_id, shard

Счетчик

Количество привязанных дисков к сервису по шардам (растет на attach)

volumes_opened_currently

client_id, shard

Индикатор

Количество используемых виртуальными машинами дисков

volumes_opened_total

client_id, shard

Счетчик

Количество подключений дисков к виртуальным машинам (растет на vm start)

Баг-репорты и обратная связь

Баг-репорт должен включать в себя:

  • Версию vhostd:

    $ vhostd --version
    version:1.2.51 commit:ddab1fb seastar:1.0 build:release timestamp:2024-01-31T13:45:26Z flags:mod,clang-16.0.6 branch:HEAD
  • Версию storage:

    $ storage --version
    version: 1.2.61
    commit: 94f0277
    build date: 02.02.2024
    build type: Release
    build id: 06e8e0b1ef7afd48
    go version: go1.21.4
  • Версии пакетов компонентов кластера csd, mds:

    $ storage mds list
    ID ADDRESS NET-STATUS RAFT-STATUS UPTIME MAINTENANCE VERSION
    *1 192.168.100.81:60003 online ready 7d3h25m false 1.2.62
    2 192.168.100.82:60003 online ready 7d3h9m false 1.2.62
    3 192.168.100.83:60003 online ready 7d3h5m false 1.2.62
    $ storage cs list
    ID HOST TIER MGMT-STATUS STATUS ADDRESS UPTIME CHUNKLETS LAST-SCRUB IS-SCRUBBING COLD-SPACE HOT-SPACE VERSION
    1 0x42e93d98528c6eba 0 ok active 192.168.100.82:59001 7d3h9m 20(12+4+4) 15 Feb 24 08:36 MSK false 3.10GB/7.09GB 807.59MB/807.60MB 1.2.53
    2 0xe97d741ed478aea0 0 ok active 192.168.100.81:59002 7d3h26m 26(18+4+4) 14 Feb 24 14:36 MSK true 4.29GB/7.09GB 807.51MB/807.60MB 1.2.53
    3 0x516fac3c095d8df8 0 ok active 192.168.100.83:59003 7d3h6m 21(14+3+4) 14 Feb 24 16:07 MSK false 3.77GB/7.09GB 807.58MB/807.60MB 1.2.53
    4 0x42e93d98528c6eba 0 ok active 192.168.100.82:59004 7d3h9m 28(19+4+5) 15 Feb 24 12:16 MSK false 4.32GB/7.09GB 807.52MB/807.60MB 1.2.53
    5 0xe97d741ed478aea0 0 ok active 192.168.100.81:59005 7d3h26m 26(18+4+4) 14 Feb 24 16:11 MSK false 4.49GB/7.09GB 807.52MB/807.60MB 1.2.53
    6 0x516fac3c095d8df8 0 ok active 192.168.100.83:59006 7d3h6m 23(15+4+4) 14 Feb 24 19:40 MSK false 4.44GB/7.09GB 807.59MB/807.60MB 1.2.53
    7 0x42e93d98528c6eba 0 ok active 192.168.100.82:59007 7d3h9m 27(19+4+4) 14 Feb 24 19:41 MSK false 4.60GB/7.09GB 807.59MB/807.60MB 1.2.53
    8 0xe97d741ed478aea0 0 ok active 192.168.100.81:59008 7d3h26m 28(19+5+4) 14 Feb 24 18:39 MSK false 4.79GB/7.09GB 807.52MB/807.60MB 1.2.53
    9 0x516fac3c095d8df8 0 ok active 192.168.100.83:59009 7d3h6m 21(13+4+4) 14 Feb 24 16:05 MSK false 4.23GB/7.09GB 807.60MB/807.60MB 1.2.53
    10 0x42e93d98528c6eba 0 ok active 192.168.100.82:59010 7d3h9m 26(17+5+4) 14 Feb 24 16:38 MSK false 5.01GB/7.09GB 807.25MB/807.60MB 1.2.53
    11 0xe97d741ed478aea0 0 ok active 192.168.100.81:59011 7d3h26m 26(17+5+4) 14 Feb 24 19:53 MSK false 3.73GB/7.09GB 807.59MB/807.60MB 1.2.53
    12 0x516fac3c095d8df8 0 ok active 192.168.100.83:59012 7d3h6m 22(14+4+4) 14 Feb 24 22:48 MSK false 4.76GB/7.09GB 807.59MB/807.60MB 1.2.53
    13 0x42e93d98528c6eba 0 ok active 192.168.100.82:59013 7d3h9m 28(18+5+5) 14 Feb 24 18:00 MSK false 4.73GB/7.09GB 807.27MB/807.60MB 1.2.53
    14 0xe97d741ed478aea0 0 ok active 192.168.100.81:59014 7d3h26m 28(19+4+5) 14 Feb 24 16:10 MSK false 4.41GB/7.09GB 807.59MB/807.60MB 1.2.53
    15 0x516fac3c095d8df8 0 ok active 192.168.100.83:59015 7d3h6m 22(16+3+3) 14 Feb 24 19:16 MSK false 4.48GB/7.09GB 807.60MB/807.60MB 1.2.53
  • Текстовое описание проблемы;

  • Файлы логов vhostd (vhost.0.log.zst, vhost.1.log.zst, …);

  • Файлы coredump-ов, если есть в наличии (рекомендуется архивировать для уменьшения их размера);

  • Адрес для обратной связи.

Типовые проблемы

В практике работы с хранилищами данных применяются две стратегии обработки ошибок:

  1. Многократные повторные попытки выполнения запроса с ожиданием успешного завершения операции.

  2. Немедленное возвращение ошибки клиентскому приложению (в случае vhostd - возврат ошибки драйверу блочного устройства).

Каждая стратегия имеет свои преимущества и недостатки. Первый подход позволяет разрабатывать клиентские приложения в предположении, что операции с хранилищем всегда завершаются успешно. В случае временных проблем запрос будет автоматически повторен, что увеличит время выполнения, но в конечном итоге операция завершится. Второй подход обеспечивает оперативное информирование клиента о возникшей проблеме, позволяя принять решение о повторной попытке или других действиях.

В реальных условиях большинство приложений не обрабатывают ошибки хранилища должным образом. Например, операционная система Linux при получении ошибки от диска автоматически перемонтирует файловую систему в режим только для чтения, что приводит к прекращению всех операций записи. Для восстановления работоспособности требуется вмешательство администратора. Из-за этого вторая стратегия не подходит для использования в не специализированных условиях.

Сервис vhostd реализует стратегию многократных повторных попыток при возникновении ошибок взаимодействия с кластером. Для виртуальных машин такие ситуации выглядят как временные зависания операций ввода-вывода.

При возникновении критических проблем сервис storage-vhostd может выполнить аварийную остановку с последующим автоматическим перезапуском. Состояние очередей virtio сохраняется в общей памяти процесса QEMU виртуальной машины. После перезапуска vhostd виртуальные машины с правильно настроенным параметром reconnect будут пытаться переподключиться к соответствующим сокетам, после чего в рамках процесса hand-shake QEMU делится сохраненной ранее памятью с процессом vhostd, за счет чего обработка запросов может продолжиться с того места, где оборвалась в прошлый раз. Для виртуальной машины такие падения также выглядят как зависания.

Ошибка выделения местао для диска с заданным failure-domain (failt to call: GetMap … code: ERR_CS_SHORTAGE)

Любой создаваемый диск требует место для размещения. Место выделяется не сразу, а по мере необходимости. При попытке выполнения операций ввода-вывода с диском сервис может вернуть ошибку:

INFO 2024-02-15 15:33:39.373931 sds/mds/client - call: GetMap[210], [1/1] xid: 0xeadde149d636f782, retries: 582 to: 192.168.100.81:60003, req-tout: 0ms, rpc-tout: 10000ms WARN 2024-02-15 15:33:39.378219 sds/mds/client - fail to call: GetMap[210], [1/1] xid: 0xeadde149d636f782, retries: 582, code: ERR_CS_SHORTAGE

Сервис vhostd продолжает попытки выделения места, ожидая изменения конфигурации кластера. Логи при этом заполняются запросом GetMap. Для виртуальной машины это проявляется как зависание операций ввода-вывода.

Конфликт аренды диска (failt to call: AquireLease … code: ERR_LEASE_CONFLICT)

Привязки в vhostd в общем случае создаются с эксклюзивными правами доступа — в конкретный момент времени у диска может быть только один владелец. При попытке доступа к диску, который уже используется другим клиентом, в логах появляются сообщения:

INFO 2024-02-15 16:13:03.974843 sds/mds/client - call: AcquireLease[200], xid: 0xeadde149d636f840, retries: 0 to: 192.168.100.81:60003, req-tout: 0ms, rpc-tout: 10000ms WARN 2024-02-15 16:13:03.977040 sds/mds/client - fail to call: AcquireLease[200], xid: 0xeadde149d636f840, retries: 0, code: ERR_LEASE_CONFLICT INFO 2024-02-15 16:13:03.977336 sds/client/metadata_server - acquire lease: volume_id: 0x5ebfbe227d5798c9, err: ERR_LEASE_CONFLICT, resp: hdr { type: MDS_ACQUIRE_LEASE_REQ code: ERR_LEASE_CO NFLICT } ERROR 2024-02-15 16:13:03.978048 sds/vhost/processor/queue - io-failed: sds::client::InvalidLease (invalid lease)

Проблемы с hotplug-дисками при миграции виртуальных машин pc-q35-6.2

В версиях QEMU 6.2 и libvirt 8.0.0 в Ubuntu обнаружена ошибка, проявляющаяся при миграции виртуальных машин с чипсетом pc-q35-6.2. Hotplug-диски vhost-user становятся недоступными на целевом хосте после миграции, хотя сама миграция завершается успешно. При выполнении команды virsh qemu-monitor-command ${VM_DOMAIN} --hmp 'info pci':

Ожидаемое:

Bus 0, device 4, function 0: SCSI controller: PCI device 1af4:1001 PCI subsystem 1af4:0002 IRQ 0, pin A BAR0: I/O at 0x1000 [0x107f]. BAR1: 32 bit memory at 0x10004000 [0x10004fff]. BAR4: 64 bit prefetchable memory at 0x10000000 [0x10003fff]. id "virtio-disk1"

Реальное:

Bus 7, device 0, function 0: SCSI controller: PCI device 1af4:1042 PCI subsystem 1af4:1100 IRQ 0, pin A BAR1: 32 bit memory at 0xffffffffffffffff [0x00000ffe]. BAR4: 64 bit prefetchable memory at 0xffffffffffffffff [0x00003ffe]. id "virtio-disk1"

Ошибка не имеет отношения к сервису vhostd, исправление необходимо проводить на стороне QEMU с бекпортом фикса из ветки 7.1. Необходимо убедиться, что ошибка исправлена в используемом ПО QEMU.

Проблемы с переподключением hotplug-дисков к vhostd после перезагрузки vhostd

После перезапуска сервиса vhostd hotplug-диски не восстанавливают соединение автоматически. Проблема вызвана ошибкой в libvirt, не передающем параметр reconnect. Необходимо использовать версию libvirt с исправлением.

Нехватка памяти в vhostd

Виртуальные машины меняют данные в памяти, передаваемые через дескрипторы virtio, сервис вынужден делать копию данных перед расчетом контрольных сумм, для создания копии необходимо место в памяти равное размеру запроса. АИнтенсивные операции записи могут привести к исчерпанию доступной памяти и падению сервиса. Начиная с версии 1.2.25 и 1.1.51 в сервис добавлен семафор-очередь для памяти IO-запросов, которая настраивается флагами конфигурации io-mem-limit-mb, io-mem-max-req, io-mem-handicap-kb (см. описание конфигурации) — меняя границы, можно избежать падения из-за перегрузки операциями write. Если smp = 4, memory = 4 ГБ, то для каждого шарда будет выделен 1 ГБ памяти, параметр можно установить на уровне io-mem-limit-mb ~ 512. Если памяти шарда больше, то лимит можно увеличить. Для точной настройки в конкретных условиях стоит произвести мониторинг метрик сервиса vhostd и определить максимальные уровни потребления на ожидаемых нагрузках. За количеством выделенной памяти можно следить используя метрики sds_vhostd_memory_allocated_memory, sds_vhostd_memory_free_memory.

Ошибка ERR_LEASE_CONFLICT после перезапуска контейнера с vhostd

Если в контейнере не сохранился файл host.yml, или он пересоздается при каждом создании контейнера, то диски, захваченные прошлой итерацией контейнера, могут быть привязаны к старому client_id. Попытка нового vhostd с новым host.yml захватить диски приведет к ошибке ERR_LEASE_CONFLICT.

Рассинхронизация таблицы привязок attachments.yml с состоянием привязок в управляющем сервисе

Внешний сервис управления может потерять синхронизацию с локальной таблицей привязок. Причиной может стать ситуацию, когда виртуальная машина с диском мигрирует на другой гипервизор, сервис vhostd временно недоступен, а управляющий сервис пытается удалить привязку в этот момент. В версиях vhostd до 1.2.43/1.1.58 это могло приводить к ошибкам при повторном подключении виртуальной машины. Команда attach работала не идемпотентно, из-за чего считала попытку привязки на известный ей сокет ошибкой.

Неиспользуемые привязки не потребляют ресурсов, потому что захват диска происходит позже, уже после того как виртуальная машина подключилась и пытается выполнять первые IO-запросы.

Файлы unix-domain сокетов без привязок в БД

Версии vhostd до 1.2.43/1.1.58 не удаляли файлы сокетов в директории /var/lib/storage после удаления привязок, потому что в общем случае сервис не знает используются ли эти файлы другой программой. Современные версии пытаются удалить файл сокета при получении команды detach.

Cообщение «unsupported configuration: a block I/O throttling is not supported for vhostuser disk»

Код libvirt игнорирует факт, что настройки IO-тротлинга для vhostuser диска не заданы в конфигурации виртуальной машины, и производит проверку на доступность функции тротлинга для диска, функция недоступна средствами QEMU. Логгирование ошибки в коде библиотеки реализовано в самом методе проверки qemuDomainDiskBlockIoTuneIsSupported, из-за чего в логе libvirt появляются сообщения об ошибке:

2024-02-13 09:01:24.297+0000: 64055: error : qemuDomainDiskBlockIoTuneIsSupported:15705 : unsupported configuration: a block I/O throttling is not supported for vhostuser disk

Функция IO-тротлинга реализуется средствами Cloud SDS и настраивается через утилиту storage (Подробнее в разделе Rate/bandwidth лимитирование Руководства администратора).

Устаревание mds_list.yml на вычислительных нодах vhostd без активных клиентов/виртуальных машин

Версии vhostd до 1.2.61 не обновляют список mds_list.yml при отсутствии активных виртуальных машин. Если состав серверов метаданных (MDS) изменился полностью, либо все известные инстансу vhostd недоступны и ему негде обновить карту, то при попытке подключиться к диску виртуальная машина не сможет запуститься. Для решения проблемы обновите vhostd до версии 1.2.61, либо проверьте актуальность файла mds_list.yml перед attach и запуском новых виртуальных машин на ноде. Если mds_list.yml устарел, то до того как запускать новые виртуальные машины нужно:

Сервис прочтет актуальный файл mds_list.yml и сможет подключиться к серверу.

Ошибки при выполнении команды storage vhost attach «failed to read negotiation header», «failed to read response»

В блок-схеме работы сервиса vhostd представлен алгоритм обработки команд RPC, присылаемых командой storage vhost. Каждый запрос обрабатывается синхронно. Операция attach ждет создания unix-сокета на диске и запуска задачи обработки сокета, которые могут занимать достаточно много времени. При одновременном запуске сотен запросов storage vhost attach, время ожидания увеличивается. До релиза storage версии 1.2.75 утилита не учитывала флаг --timeout (по умолчанию 30 секунд) и операция завершалась ошибкой i/o timeout: server closed через 3 секунды. Начиная с версии 1.2.75 утилита storage ждет указанное время timeout. Из-за ограничений алгоритма обработки командных запросов в текущей версии vhostd ошибки timeout будут продолжать появляться, если число одновременных запросов на attach будет расти.

Начиная с версии 1.3.1 vhostd способна обработать 1000 одновременных команд storage vhost attach за 25 секунд. В реальности такие нагрузки маловероятны, так как менеджеры виртуальных машин libvirt/OpenStack запускают их намного медленнее. В таких условиях время выполнения команды attach не превышает 0.1 секунды.

Падение сервиса на ошибке PanicDevice

vhostd использует очереди virtio для чтения запросов и отправки результатов в виртуальные машины. Если очередь virtio повреждена, адреса в ней могут стать невалидными. В этом случае работать с этой очередью нельзя. В логе vhostd происшествие будет отмечено ошибкой PanicDevice. До версии 1.2.76 эти ошибки считались фатальными и приводили к падению приложения, начиная с версии 1.2.76 — сервер разрывает соединение с указанной виртуальной машиной. На стороне виртуальной машины данная ошибка выглядит как зависание при попытке сделать IO-операцию со сломанным диском. Виртуальная машина автоматически попытается восстановить соединение после исправления очереди. Если на заданный unix-сокет для связи с ВМ приходило много соединений, которые заканчивались ошибкой PanicDevice, то перезапуск этого сокета будет выполнен через увеличивающиеся промежутки времени.

Ошибка InvalidPayloadSize в логах vhostd

Была внесена ошибка форматирования сообщений в логе для некоторых команд vhost на control plane, из-за чего в лог выводилась ошибка InvalidPayloadSize. Ошибка не давала удалять диски из ВМ в режиме реального времени. Внесено в 1.2.96. Исправлено в 1.2.104 и 1.3.12.

Режим снапшотов в виртуальных машинах libvirt/QEMU

QEMU поддерживает разные режимы работы со снапшотами При неправильной настройке режима снапшотов у диска будут появляться сообщения вида unsupported configuration: disk 'vda' must use snapshot mode XXX, где XXX — один из режимов.

Режимы:

  • internal — снапшот в файле диска;

  • external — снапшот в другом файле;

  • none — QEMU/virsh не следят за снапшотами для данного диска;

  • manual — новый режим в libvirt 8.2, создан для упрощения работы с системами типа vhostd.

QEMU/libvirt не могут контролировать снапшоты — уровень интеграции систем меньше, чем когда libvirt делает снапшот диска средствами QEMU. Таким образом, за правильным сохранением и загрузкой снапшотов должен следить драйвер.

Ошибка libvirtd вида: «Invalid value for attribute „protocol“ in element „source“: „sbd“»

Поддержка виртуальных машин с дисками sbd отсутствует в базовых версиях libvirtd и QEMU, поставляемых ubuntu. Версии пакетов libvirtd и QEMU c патчем для актуальной версии ubuntu доступны по ссылке.

Ошибка sds/assert - Assert at …/mds_provider.cc: „false“ Unknown provider state 4 с генерацией coredump. (актуально для всех версий vhostd < 1.3.32)

vhostd был запущен без корректного файла mds_list.yml. vhostd не гарантирует работоспособность ПО без правильных файлов конфигурации.

Ошибка вида «Unable to connect character device „XXX“: Failed to connect to „/var/lib/storage/YYY.sock“: Permission denied» в логе виртуальной машины QEMU ^^^^^^^^^^^^^^^^^^^^^^^^^^I^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Подключение к vhostd происходит через unix-сокеты, которые по умолчанию хранятся в директории /var/lib/storage/, linux контролирует права доступа к сокетам по аналогии с обычными файлами на файловой системе. Помимо правил доступа могут включены SELinux или Apparmor, которые также ограничивают возможности приложений, запущенных через них, для доступа к системным ресурсам и файлам/сокетам.

Падение при одновременном подключении большого числа виртуальных машин/дисков (много подряд идущих строк «got client from», после чего падение шарда, ошибка Segmentation fault или обрыв лога)

При добавлении поддержки работы нескольких ВМ с одним диском на vhostd, была внесена ошибка с конкурентным доступом к единому реестру доступных дисков. Доступ на запись 99% времени осуществлялся отдельными шардами, оставшийся 1% мог происходить, когда много виртуальных машин могли быстро подключиться к vhostd и ожидали диски. Это приводило к перезапуску vhostd. Данные пользователей/виртуальные машины при этом не оказывались затронуты. Ошибка внесена с версии 1.1. Исправлено в релизах на всех новых версиях 1.2.110, 1.3.53, 1.4.7.

Для старых версий:

  1. Ограничите число дисков на виртуальную машину.

  2. После старта vhostd запустите виртуальные машины с задержкой.

Падение при старте с невалидным сокетом (например, bind: Address already in use) в attachments.yml или падение во время добавлении невалидного сокета (например, с неправильными правами) через storage vhost attach

Падение происходит при спользовании занятого сокета или недостаточных правах доступа. На эту проблему указывают сообщения в логе перед падением:

INFO 2024-11-12 11:41:21.913382 sds/vhost/blk_device_handler - setup bdev (/var/lib/storage/55c8738e-18fd-453b-9dc7-9893239bbae2.sock)->(0x14b4d4dc3d146a11@123)
INFO 2024-11-12 11:41:21.913384 sds/vhost/unix_socket - setup accepting socket at /var/lib/storage/55c8738e-18fd-453b-9dc7-9893239bbae2.sock
ERROR 2024-11-12 11:41:21.913514 sds/vhost/unix_socket - listen_unix_socket: error: (std::system_error (error system:13, bind: Permission denied))
ERROR 2024-11-12 11:41:21.913559 sds/assert - Assert at /home/rvhakimov/workspace3/sds/src/virtio/vhostd/server/blk_device_handler.cc:104 '!_complete' attachment destroyed before stopped

Тип error system указывает на проблему с сокетом.

Начиная с версий 1.4.12 и 1.3.59, если подобная ошибка возникает при старте, то vhost завершает выполнение с выводом конкретной ошибки. Если ошибка возникает при вызове команды storage vhost attach, то vhost продолжает работу, а утилита storage выводит ошибку failed to add new attachment. Подробности ошибки можно найти в логе по listen_unix_socket: error:.

Ошибка «Invalid response method_version version (expected: X, actual: Y): got exception»

Ошибка появляется, если версия storage tool не совпадает с версией сервиса vhostd. X и Y — версии RPC ABI.