Для улучшения работы сайта мы используем файлы cookies. Оставаясь на сайте, вы соглашаетесь с политикой обработки персональных данных.

VDSM и хуки

1. VDSM

Менеджер управления использует службу VDSM для управления хостами с zVirt Node и RedOS. Служба VDSM управляет и ведет мониторинг хранилища, памяти и сетевых ресурсов хоста. Кроме того, она координирует создание виртуальных машин, сбор статистики, сбор журналов и другие задачи по администрированию хостов. VDSM работает как сервис на каждом хосте под управлением Менеджера управления и отвечает на XML-RPC запросы от клиентов. Менеджер управления функционирует как клиент VDSM.

2. Хуки VDSM

Службу VDSM можно расширить с помощью хуков. Хуки – это скрипты, выполняемые на хосте при наступлении ключевых событий. При наступлении предусмотренного события служба VDSM запускает любые исполняемые скрипты хуков в /usr/libexec/vdsm/hooks/nn_event-name/ на хосте в порядке, определяемом их буквенно-цифровыми идентификаторами. Как правило, каждому скрипту хука присвоено двузначное число, которое стоит в начале имени файла, чтобы четко указать, в каком порядке будут выполняться скрипты. Скрипты хуков можно писать на любом языке программирования, но в этой главе даны примеры на Python.

Обратите внимание, что выполняются все скрипты, заданные на хосте для события. Если требуется, чтобы один конкретный хук выполнялся только для определенного подмножества виртуальных машин, работающих на хосте, то убедитесь, что скрипт хука отвечает этому требованию, а для этого надо использовать Пользовательские свойства (Custom Properties), ассоциированные с этой виртуальной машиной.

Хуки VDSM могут мешать работе zVirt. Ошибка в хуке VDSM способна привести к отказу виртуальной машины и потере данных. Хуки VDSM надлежит реализовывать с осторожностью и тщательно проверять. Хуки API – это нововведение, которое будет существенно переработано в будущем.

3. Расширение службы VDSM с помощью хуков

В этой главе описано, как расширить службу VDSM с помощью хуков на основе событий. Расширение службы VDSM с помощью хуков – это экспериментальная технология, и настоящая глава адресована опытным разработчикам. Если установить пользовательские свойства на виртуальных машинах, то скриптам хуков можно передать дополнительные параметры, свойственные конкретной виртуальной машине.

4. Установка хука VDSM

Хуки VDSM не установлены по умолчанию. Если требуется определенный хук, то его необходимо установить вручную.

Предварительные условия:
  • Репозиторий на хосте должен быть включен.

  • Необходимо авторизоваться на хосте в качестве root-пользователя.

Порядок действий:
  1. Выведите список доступных хуков:

    dnf list vdsm\*hook\*
  2. Установите пакет нужного хука VDSM на хосте:

    dnf install <vdsm-hook-name>

    Например, чтобы установить пакет vdsm-hook-vhostmd на хосте, введите следующую команду:

    dnf install vdsm-hook-vhostmd
Дополнительные ресурсы

5. Предусмотренные события VDSM

Таблица 1. Предусмотренные события VDSM
Имя Описание

before_vm_start

До запуска виртуальной машины.

after_vm_start

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

before_vm_cont

До возобновления работы виртуальной машины.

after_vm_cont

После возобновления работы виртуальной машины.

before_vm_pause

До приостановки виртуальной машины.

after_vm_pause

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

before_vm_hibernate

До перехода виртуальной машины в спящий режим.

after_vm_hibernate

После перехода виртуальной машины в спящий режим.

before_vm_dehibernate

До выхода виртуальной машины из спящего режима.

after_vm_dehibernate

После выхода виртуальной машины из спящего режима.

before_vm_migrate_source

До миграции виртуальной машины, работающей на хосте-источнике, с которого выполняется миграция.

after_vm_migrate_source

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

before_vm_migrate_destination

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

after_vm_migrate_destination

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

after_vm_destroy

После удаления виртуальной машины.

before_vdsm_start

До запуска службы VDSM на хосте. Хуки before_vdsm_start выполняются  от имени root-пользователя и не наследуют среду процесса VDSM.

after_vdsm_stop

После остановки службы VDSM на хосте. Хуки after_vdsm_stop выполняются от имени root-пользователя и не наследуют среду процесса VDSM.

before_nic_hotplug

До горячего подключения сетевой карты к виртуальной машине.

after_nic_hotplug

После горячего подключения сетевой карты к виртуальной машине.

before_nic_hotunplug

До горячего отключения сетевой карты от виртуальной машины.

after_nic_hotunplug

После горячего отключения сетевой карты от виртуальной машины.

after_nic_hotplug_fail

После неудачной попытки горячего подключения сетевой карты к виртуальной машине.

after_nic_hotunplug_fail

После неудачной попытки горячего отключения сетевой карты от виртуальной машины.

before_disk_hotplug

До горячего подключения диска к виртуальной машине.

after_disk_hotplug

После горячего подключения диска к виртуальной машине.

before_disk_hotunplug

До горячего отключения диска от виртуальной машины.

after_disk_hotunplug

После горячего отключения диска от виртуальной машины.

after_disk_hotplug_fail

После неудачной попытки горячего подключения диска к виртуальной машине.

after_disk_hotunplug_fail

После неудачной попытки горячего отключения диска от виртуальной машины.

before_device_create

До создания устройства, поддерживающего пользовательские свойства.

after_device_create

После создания устройства, поддерживающего пользовательские свойства.

before_update_device

До обновления устройства, поддерживающего пользовательские свойства.

after_update_device

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

before_device_destroy

До удаления устройства, поддерживающего пользовательские свойства.

after_device_destroy

После удаления устройства, поддерживающего пользовательские свойства.

before_device_migrate_destination

До миграции устройства, работающего на хосте-приемнике, на который выполняется миграция.

after_device_migrate_destination

После миграции устройства, работающего на хосте-приемнике, на который выполняется миграция.

before_device_migrate_source

До миграции устройства, работающего на хосте-источнике, с которого выполняется миграция.

after_device_migrate_source

После миграции устройства, работающего на хосте-источнике, с которого выполняется миграция.

after_network_setup

После настройки сети при запуске хоста.

before_network_setup

До настройки сети при запуске хоста.

6. Среда хуков VDSM

Большинство скриптов хуков выполняются от имени пользователя vdsm и наследуют среду процесса VDSM. Исключение составляют те скрипты хуков, которые запускаются событиями before_vdsm_start и after_vdsm_stop. Скрипты хуков, которые запускаются этими событиями, выполняются от имени root-пользователя и не наследуют среду процесса VDSM.

7. XML-объект домена хука VDSM

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

  • *nic_hotplug*

  • *nic_hotunplug*

  • *_update_device

  • *_device_create

  • *device_migrate*

Сейчас хуки before_migration_destination и before_dehibernation получают XML-представление домена от хоста-источника. В XML-представлении домена на хосте-приемнике будет несколько отличий.

Формат XML-представления домена libvirt используется службой VDSM для определения виртуальных машин. Подробнее о формате XML-представления домена libvirt см. на веб-сайте. Идентификатор UUID виртуальной машины можно логически вывести из XML-представления домена, а также получить из переменной среды vmId.

8. Установка пользовательских свойств

Пользовательские свойства, принятые Менеджером управления, и соответственно передаваемые пользовательским хукам, можно задать с помощью команды engine-config. Выполните команду от имени root-пользователя на том хосте, на котором установлен Менеджер управления.

Ключи конфигурации UserDefinedVMProperties и CustomDeviceProperties применяются для хранения имен поддерживаемых пользовательских свойств. Регулярные выражения, задающие допустимые значения для каждого именованного пользовательского свойства, тоже содержатся в этих ключах конфигурации.

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

После обновления ключа конфигурации необходимо перезапустить службу ovirt-engine, чтобы новые значения вступили в силу.

Пример 1. Свойства виртуальной машины: установка пользовательского свойства смарт-карта (smartcard)
  1. Проверьте существующие пользовательские свойства, заданные ключом конфигурации UserDefinedVMProperties, с помощью следующей команды:

    engine-config -g UserDefinedVMProperties

    В выводе ниже показано, что пользовательское свойство память (memory) уже задано. Регулярное выражение ^[0-9]+$ гарантирует, что в пользовательском свойстве всегда будут содержаться только цифры.

    engine-config -g UserDefinedVMProperties
    UserDefinedVMProperties:  version: 4.3
    UserDefinedVMProperties:  version: 4.4
    UserDefinedVMProperties : memory=^[0-9]+$ version: 4.4
  2. Поскольку пользовательское свойство memory уже задано в ключе конфигурации UserDefinedVMProperties, новое пользовательское свойство должно быть добавлено к нему. Дополнительное пользовательское свойство smartcard добавляется к значению ключа конфигурации. Новое пользовательское свойство может принимать значения true или false.

    engine-config -s UserDefinedVMProperties='memory=^[0-9]+$;smartcard=^(true|false)$' --cver=4.4
  3. Убедитесь, что пользовательские свойства, заданные ключом конфигурации UserDefinedVMProperties, были обновлены корректно.

    engine-config -g UserDefinedVMProperties
    UserDefinedVMProperties:  version: 4.3
    UserDefinedVMProperties:  version: 4.4
    UserDefinedVMProperties : memory=^[0-9]+$;smartcard=^(true|false)$ version: 4.4
  4. В конце требуется перезапустить службу ovirt-engine, чтобы изменения конфигурации вступили в силу.

    systemctl restart ovirt-engine.service
Пример 2. Свойства устройств: установка пользовательского свойства интерфейс (interface)
  1. Проверьте существующие пользовательские свойства, заданные ключом конфигурации CustomDeviceProperties, с помощью следующей команды:

    engine-config -g CustomDeviceProperties

    В выводе ниже показано, что пользовательские свойства еще не заданы.

    engine-config -g CustomDeviceProperties
    
    CustomDeviceProperties:  version: 4.3
    CustomDeviceProperties:  version: 4.4
  2. Пользовательское свойство interface ещё не существует, поэтому его можно добавить "как есть". В этом примере значение подсвойства speed указано в диапазоне от 0 до 99999, а значение подсвойства duplex установлено на выбор либо full, либо half.

    engine-config -s CustomDeviceProperties="{type=interface;prop={speed=^([0-9]{1,5})$;duplex=^(full|half)$}}" --cver=4.4
  3. Убедитесь, что пользовательские свойства, заданные ключом конфигурации CustomDeviceProperties, были обновлены корректно.

    engine-config -g CustomDeviceProperties
    
    UserDefinedVMProperties:  version: 4.3
    UserDefinedVMProperties:  version: 4.4
    UserDefinedVMProperties : {type=interface;prop={speed=^([0-9]{1,5})$;duplex=^(full|half)$}} version: 4.4
  4. В конце требуется перезапустить службу ovirt-engine, чтобы изменения конфигурации вступили в силу.

    systemctl restart ovirt-engine.service

9. Настройка пользовательских свойств на виртуальной машине

Когда пользовательские свойства заданы в Менеджере управления, можно приступить к их настройке на виртуальных машинах. Пользовательские свойства настраиваются на вкладке Пользовательские свойства (Custom Properties) в окнах Новая виртуальная машина (New Virtual Machine) и Изменить виртуальную машину (Edit Virtual Machine) на Портале администрирования.

Кроме того, пользовательские свойства можно настроить в диалоговом окне Запустить ВМ (Run Virtual Machine(s)). Пользовательские свойства, заданные в диалоговом окне Запустить ВМ (Run Virtual Machine(s)), будут применяться к виртуальным машинам только до следующего выключения.

Вкладка Пользовательские свойства (Custom Properties) предоставляет возможность выбирать из списка заданных пользовательских свойств. После выбора ключа пользовательского свойства появится дополнительное поле, в котором можно задать значение этого ключа. Нажимая plus big и minus big, добавляйте или удаляйте пары ключ/значение.

10. Оценка пользовательских свойств на виртуальных машинах в хуке VDSM

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

Пример 3. Оценка пользовательских свойств

Далее в коротком примере на языке Python проверяется наличие пользовательского свойства key1. Если пользовательское свойство задано, то выдается стандартная ошибка. Если пользовательское свойство не задано, то ничего не произойдет.

#!/usr/bin/python

import os
import sys

if os.environ.has_key('key1'):
  sys.stderr.write('key1 value was : %s\n' % os.environ['key1'])
else:
  sys.exit(0)

11. Использование модуля хукинга VDSM

VDSM поставляется с модулем хукинга Python, в котором предоставлены вспомогательные функции для скриптов хука VDSM. Этот модуль предоставляется в качестве примера и касается только хуков VDSM, написанных на Python.

Модуль хукинга поддерживает чтение XML-представления libvirt виртуальной машины в объект DOM. Затем скрипты хуков могут использовать встроенную в Python библиотеку xml.dom для работы с объектом.

Измененный объект можно затем сохранить обратно в XML-представление libvirt с помощью модуля хукинга. Модуль хукинга предоставляет следующие функции для поддержки разработки хуков:

Таблица 2. Функции модуля хукинга
Имя Аргумент Описание

tobool

строка

Конвертирует строку "true" или "false" в логическое значение

read_domxml

-

Считывает XML-представление libvirt виртуальной машины в объект DOM

write_domxml

объект DOM

Записывает XML-представление libvirt виртуальной машины из объекта DOM

12. Выполнение хуков VDSM

Скрипты before_vm_start могут изменить XML-представление домена, чтобы изменить определение настроек VDSM виртуальной машины до того, как оно достигнет libvirt. При этом необходимо проявлять осторожность. Скрипты хуков способны нарушить работу VDSM, а дефектные скрипты могут привести к сбоям среды zVirt. В частности, никогда не изменяйте идентификатор UUID домена и не пытайтесь удалить устройство из домена без достаточных знаний и опыта.

Оба скрипта хуков before_vdsm_start и after_vdsm_stop выполняются от имени root-пользователя. Остальные скрипты хуков, для которых требуется root-доступ в систему, должны быть записаны, чтобы использовать команду sudo для повышения привилегий. Для этого необходимо обновить /etc/sudoers, чтобы позволить пользователю vdsm использовать команду sudo без повторного введения пароля. Это необходимо, т.к. скрипты хуков выполняются не в интерактивном режиме.

Пример 4. Конфигурирование командыsudo для хуков VDSM

В этом примере команда sudo будет сконфигурирована так, чтобы позволить пользователю vdsm выполнить команду /bin/chown от имени root-пользователя.

  1. Авторизуйтесь на хосте виртуализации как root-пользователь.

  2. Откройте файл /etc/sudoers в текстовом редакторе.

  3. Вставьте в файл следующую строку:

    vdsm ALL=(ALL) NOPASSWD: /bin/chown

    Тут указано, что пользователь vdsm может выполнить команду /bin/chown от имени root-пользователя. Параметр NOPASSWD указывает на то, что у пользователя не будет запрошен пароль при вызове команды sudo.

После внесения этого изменения в конфигурацию хуки VDSM смогут задействовать команду sudo для выполнения /bin/chown от имени root-пользователя. В этом коде Python используется команда sudo для выполнения /bin/chown от имени root-пользователя в файле /my_file.

retcode = subprocess.call( ["/usr/bin/sudo", "/bin/chown", "root", "/my_file"] )

Стандартный поток сообщений об ошибках скриптов хуков собирается в журнал VDSM. Эта информация используется для отладки скриптов хуков.

13. Коды возврата хука VDSM

Скрипты хуков должны возвращать один из кодов возврата. Код возврата определяет, будут ли дальнейшие скрипты хуков обрабатываться VDSM.

Таблица 3. Коды возврата хука
Код Описание

0

Скрипт хука успешно выполнен

1

Скрипт хука завершился сбоем, необходимо обработать другие хуки

2

Скрипт хука завершился сбоем, другие хуки не обрабатывать

>2

Зарезервировано

14. Примеры хуков VDSM

Примеры скриптов хуков, представленные в этом разделе, необязательно поддерживаются zVirt. Убедитесь, что абсолютно все скрипты хуков, установленные в системе, независимо от источника, тщательно протестированы для работы в вашей среде.

Пример 5. Настройка узлов NUMA

Этот скрипт хука позволяет настраивать выделение памяти на хосте NUMA на основании пользовательского свойства numaset. Если пользовательское свойство не задано, то ничего не произойдет.

Строка конфигурирования:

numaset=^(interleave|strict|preferred):[\^]?\d+(-\d+)?(,[\^]?\d+(-\d+)?)*$

Используемое регулярное выражение позволяет пользовательскому свойству numaset на конкретной виртуальной машине указать режим выделения (interleave, strict, preferred) и используемый узел. Два значения отделяются двоеточием (:). Регулярное выражение позволяет задать в качестве nodeset:

  • один конкретный узел (numaset=strict:1: указывает, что будет задействован только узел 1)

  • диапазон узлов (numaset=strict:1-4: указывает, что будут задействованы узлы 1–4)

  • только не этот конкретный узел (numaset=strict:^3: указывает, что не будет задействован узел 3)

  • любую комбинацию вышеуказанных вариантов через запятую (numaset=strict:1-4,6: указывает, что задействованы узлы 1–4 и 6).

Скрипт:

/usr/libexec/vdsm/hooks/before_vm_start/50_numa
#!/usr/bin/python

import os
import sys
import hooking
import traceback

'''
numa hook
=========
add numa support for domain xml:

<numatune>
    <memory mode="strict" nodeset="1-4,^3" />
</numatune>

memory=interleave|strict|preferred

numaset="1" (use one NUMA node)
numaset="1-4" (use 1-4 NUMA nodes)
numaset="^3" (don't use NUMA node 3)
numaset="1-4,^3,6" (or combinations)

syntax:
    numa=strict:1-4
'''

if os.environ.has_key('numa'):
    try:
        mode, nodeset = os.environ['numa'].split(':')

        domxml = hooking.read_domxml()

        domain = domxml.getElementsByTagName('domain')[0]
        numas = domxml.getElementsByTagName('numatune')

        if not len(numas) 0:
            numatune = domxml.createElement('numatune')
            domain.appendChild(numatune)

            memory = domxml.createElement('memory')
            memory.setAttribute('mode', mode)
            memory.setAttribute('nodeset', nodeset)
            numatune.appendChild(memory)

            hooking.write_domxml(domxml)
        else:
            sys.stderr.write('numa: numa already exists in domain xml')
            sys.exit(2)
    except:
        sys.stderr.write('numa: [unexpected error]: %s\n' % traceback.format_exc())
        sys.exit(2)