Для автоматической работы обработчика услуг Hyper-V (pmhyperv) шаблоны виртуальных машин (ВМ) должны соответствовать единому стандарту. Статья описывает структуру каталога, формат файла template.json и подготовку дисков VHDX для Linux и Windows для автоматического создания ВМ через обработчик Hyper-V. Инструкция поможет создавать шаблоны, которые будут развёртываться без участия администратора платформы.
Чтобы подготовить шаблон:
- Создайте каталог с определённой структурой.
- Подготовьте описание шаблона — файл template.json.
- Подготовьте пользовательский файл конфигурации механизма начальной настройки (bootstrap-конфиг).
- Подготовьте гостевую ОС.
- Опубликуйте шаблон.
Структура каталога
Каждый шаблон находится в отдельной подпапке каталога шаблонов:
D:\Templates\
├── ubuntu-24.04\
│ ├── disk.vhdx
│ ├── user-data.yaml.tpl
│ └── template.json
└── windows-server-2022\
├── disk.vhdx
├── unattend.xml.tpl
└── template.jsonИмя подпапки должно совпадать со значением
intname
в файле template.json. Модуль обработчика услуг Hyper-V:
- Сохраняет значение
intnameв BILLmanager. - При создании ВМ создаёт каталог <templates_dir>\<intname>.
Формат файла template.json
Обязательные поля
Дополнительные поля для Linux, поколение 2
Дополнительные поля шаблона, используемые при публикации в BILLmanager
Пользовательский файл конфигурации механизма начальной настройки (bootstrap-конфиг)
Модуль не настраивает гостевую ОС автоматически: параметры DHCP, DNS, учётных записей, SSH, OOBE, разделов и файловых систем не генерируются. Для настройки ОС используется bootstrap-конфиг — файл с инструкциями по конфигурированию. Для Linux это YAML-файл, первая строка которого должна иметь вид #cloud-config. Для Windows это XML-файл. Примеры см. ниже.
Относительный путь к bootstrap-конфигу указывается в поле bootstrap_file файла template.json. Путь задаётся относительно каталога шаблона. Абсолютные пути и переходы между каталогами .. не поддерживаются.
Для передачи информации о ВМ используйте токены — записи вида __BILLMGR_<параметр>__. Перед сборкой ISO-образа модуль подставит актуальное значение. Поддерживаемые токены:
Использование неизвестных токенов формата
__BILLMGR_*__
запрещено.
Минимальные примеры шаблонов
Linux
D:\Templates\ubuntu-test\
├── disk.vhdx
├── template.json
└── user-data.yaml.tpl{
"intname": "ubuntu-test",
"name": "Ubuntu Test",
"os_family": "linux",
"generation": 2,
"vhdx_file": "disk.vhdx",
"bootstrap_file": "user-data.yaml.tpl"
}
Если образ не поддерживает безопасную загрузку (Secure Boot), добавьте поле "secure_boot": "off".
Минимальный файл user-data.yaml.tpl
Файл устанавливает пароль пользователя root и сообщает модулю о завершении начальной настройки:
Пример не изменяет таблицу разделов и файловую систему. Linux-образ должен:
- cодержать настройку сетевых интерфейсов для работы по DHCP до развёртывания ВМ;
- поддерживать NoCloud — источник данных cloud-init, позволяющий передать конфигурацию локально, без сетевого сервиса;
- запускать hv_kvp_daemon.
SSH-сервер требуется только для клиентского доступа и модулем не используется.
Windows
D:\Templates\windows-test\
├── disk.vhdx
├── template.json
└── unattend.xml.tpl{
"intname": "windows-test",
"name": "Windows Test",
"os_family": "windows",
"generation": 2,
"vhdx_file": "disk.vhdx",
"bootstrap_file": "unattend.xml.tpl"
}Система записывает маркер от имени SYSTEM на этапе
specialize
. Подробнее см.документацию Microsoft https://learn.microsoft.com/ru-ru/windows-hardware/manufacture/desktop/specialize?view=windows-11. Конфигурация не использует параметры
AutoLogon
(подробнее см. https://learn.microsoft.com/ru-ru/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon) и
FirstLogonCommands
(подробнее см. https://learn.microsoft.com/ru-ru/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-firstlogoncommands). Настройка не зависит от первого интерактивного входа, языка Windows или имени встроенного администратора. Этап oobeSystem устанавливает сгенерированный пароль для встроенной учётной записи Administrator.
Образ Windows должен:
- использовать DHCP;
- содержать активную службу Hyper-V Data Exchange;
- применять при загрузке файл unattend.xml с подключённого загрузочного DVD-диска.
Перед публикацией выполните команду:
sysprep.exe /generalize /oobe /shutdown /mode:vmОбщие требования к диску VHDX
Подготовьте диск в соответствии с требованиями:
- используйте формат VHDX. Если у вашего шаблона формат VHD, конвертируйте его в формат VHDX. После конвертирования у файла должно быть расширение .vhdx, а команда
Get-VHDдолжна возвращать значениеVhdFormat = VHDX;Простого переименования файла из.vhdв.vhdxнедостаточно. Используйте пециализированное ПО (например, графическую оснастку Hyper-V Manager или утилиту Convert-VHD) - полностью выключите исходную виртуальную машину и отсоедините диск VHDX;
- используйте диск VHDX без контрольных точек и цепочки разностных дисков (differencing chain);
- убедитесь, что образ не содержит пользовательских данных, статических адресов и старых дисков начальной настройки;
- укажите в файле template.json поколение, которое будет соответствовать способу загрузки системы:
- BIOS для поколения 1;
- UEFI для поколения 2;
- используйте VHDX‑диск с ВМ того же поколения, которое указано в метаданных;
- предоставьте служебной учётной записи WinRM право на чтение диска VHDX файлов template.json и bootstrap_file;
- снимите атрибут "только для чтения", так как после копирования модуль выполняет команду
Resize-VHD.
Размер диска
При создании ВМ модуль копирует диск VHDX и задаёт точный виртуальный размер согласно ресурсу disc тарифа. Установите размер диска шаблона не больше, чем минимальное значение ресурса disc для всех тарифов, использующих этот шаблон.
Проверьте размер диска с помощью команды:
Get-VHD 'D:\Templates\ubuntu-24.04\disk.vhdx' |
Select-Object Path, VhdFormat, VhdType, Size, MinimumSize, FileSizeПоле MinimumSize показывает теоретический минимум, до которого Hyper-V может сжать диск, однако модуль обработки не поддерживает уменьшение диска. Если размер диска шаблона превышает целевой размер, заданный ресурсом disc тарифа, создание ВМ завершится ошибкой. Рекомендуется готовить небольшой базовый диск и разрешать только его увеличение.
Модуль изменяет только виртуальный размер VHDX на хосте Hyper-V. Он не меняет таблицу разделов и файловую систему внутри гостевой операционной системы (Linux или Windows). Если нужно увеличить гостевой раздел, используйте bootstrap-конфиг или средства администрирования ОС.
Шаблон Linux
Требования к гостевой ОС
Обязательны:
cloud-initс источником данных NoCloud;hv_kvp_daemonдля:- службы интеграции Data Exchange;
- передачи DHCP-адреса и маркера готовности на узел;
- настройка DHCP по умолчанию;
- получение IP-адреса по DHCP.
Вы можете выполнить установку из:
- официального облачного образа;
- образа ISO.
Подготовку диска выполняйте на временной ВМ в Hyper-V. После завершения настройки и очистки эту ВМ удаляют, сохраняя только файл диска VHDX для шаблона
Установка ОС
Вариант 1: официальный облачный образ
Если у вас нет опыта в настройке шаблонов Linux, рекомендуется начинать с официального облачного образа (cloud image) дистрибутива. Если образ поставляется в формате qcow2 или raw, преобразуйте его на ВМ с Linux с помощью утилиты qemu-img :
qemu-img info ubuntu-24.04-server-cloudimg-amd64.img
qemu-img convert -p -f qcow2 -O vhdx -o subformat=dynamic \
ubuntu-24.04-server-cloudimg-amd64.img disk.vhdxВ команде qemu-img convert укажите фактический формат исходного файла из вывода команды qemu-img info. Например, qcow2. После преобразования скопируйте диск VHDX на узел Hyper-V.
Создайте временную ВМ того же поколения, которое будет указано в файле template.json:
- для Linux поколения 2 используйте шаблон безопасной загрузки
MicrosoftUEFICertificateAuthority; - если образ не поддерживает безопасную загрузку, отключите Secure Boot. В файле template.json укажите
"secure_boot": "off".
Вариант 2: установка с образа ISO
Выполните следующие действия:
- Создайте верменную ВМ с диском VHDX размером не менее 20 ГБ.
- Установите ОС без статического IP-адреса.
- Установите cloud-init и службы интеграции Hyper-V.
- Проверьте работу источника данных NoCloud.
- Очистите идентификатор ВМ и состояние cloud-init.
- Выключите ВМ и перенесите диск VHDX в каталог шаблона.
Настройка ОС
Debian или Ubuntu
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
cloud-init hyperv-daemonsВ Ubuntu служба обмена данными (KVP daemon) может входить в пакет linux-cloud-tools-virtual. Если после установки hyperv-daemons служба hv-kvp-daemon не запускается, установите пакет linux-cloud-tools-virtual и linux-cloud-tools-$(uname -r):
sudo apt-get install -y linux-cloud-tools-virtual linux-cloud-tools-$(uname -r)Проверьте фактическое имя службы:
systemctl list-unit-files | grep -Ei 'hv.*kvp|kvp.*daemon'
pgrep -a hv_kvp_daemonОбязательный результат — работающие cloud-init и hv_kvp_daemon.
RHEL (AlmaLinux)
sudo dnf install -y cloud-init hyperv-daemonsОбязательный результат — работающие cloud-init и hv_kvp_daemon.
Проверка cloud-init
cloud-init --version
cloud-init status --long
pgrep -a hv_kvp_daemonУбедитесь, что отсутствует файл /etc/cloud/cloud-init.disabled, а источник данных NoCloud не запрещён в настройке datasource_list. С
Очистка перед публикацией
Выполните внутри временной ВМ:
sudo cloud-init clean --logs --machine-id
sudo rm -rf /var/lib/cloud/seed/nocloud /var/lib/cloud/seed/nocloud-net
sudo rm -f /etc/ssh/ssh_host_*
sudo sync
sudo poweroffСтандартный cloud-init создаст новые ключи узла SSH при первом запуске. Если дистрибутив изменён, проверьте это до публикации.
После выключения:
- Удалите временную ВМ из Hyper-V, не удаляя диск VHDX.
- Переместите диск в каталог шаблона.
Содержимое диска начальной настройки Linux
Диск seed.iso с меткой cidata — временный ISO-образ, который модуль обработки автоматически создаёт при развёртывании ВМ. Диск seed.iso содержит файлы:
user-data— пользовательский конфигурационный файл cloud-init после подстановки поддерживаемых токенов;meta-data— уникальный идентификатор экземпляра (instance-id) иlocal-hostname;
Пользовательский файл user-data должен записать BILLmanager.Provisioning=vm_<item> в KVP pool 1. Модуль ожидает, пока ВМ перейдёт в состояние Running и в KVP-пуле появится маркер готовности. Время ожидания составляет до 360 секунд. Модуль не подключается к гостевой операционной системе по сети.
После успешной проверки диск seed.iso и исходный каталог начальной настройки удаляются с узла Hyper-V.
Шаблон Windows
Поддерживаемые гостевые системы
Рекомендуются Windows Server 2016 и новее. Гостевая система должна поддерживать:
- запуск процесса подготовки системы (
Sysprep) и мастера удалённой установки (OOBE); - встроенную локальную учётную запись Administrator;
- получение сетевого адреса по DHCP;
- применение файла unattend.xml с подключённого диска DVD.
Подготовка временной ВМ
- Создайте временную ВМ нужного поколения с динамическим диском VHDX.
- Установите ОС Windows и все обновления.
- Настройте сетевой адаптер на получение адреса по DHCP.
- Не включайте машину в домен.
- Активируйте встроенную учётную запись Administrator. Вы можете найти учётную запись по относительному идентификатору безопасности (RID)
-500:
$administrator = Get-LocalUser | Where-Object { $_.SID.Value -match '-500$' } Enable-LocalUser -InputObject $administrator - Удалите временные данные, вспомогательные службы (
agents) и уникальные учётные данные. - Настройте автоматическое расширение системного раздела. Подробнее см. раздел Расширение диска C: при первом запуске.
- Выполните команду
Sysprepи дождитесь полного выключения ВМ. Подробнее см. раздел Подготовка системы (Sysprep).
Пароль временной машины не используется для созданных услуг. Файл unattend.xml задаёт новый случайный пароль. Используйте значение $administrator.Name в пользовательском файле unattend.xml.
Расширение диска C: при первом запуске
Модуль pmhyperv увеличивает размер диска VHDX, но не вызывает команду Resize-Partition внутри гостевой Windows. Добавьте в шаблон задачу автоматического запуска расширения раздела или оставьте это действие на усмотрение пользователя.
- Создайте внутри временной ВМ файл C:\ProgramData\BILLmanager\Expand-SystemVolume.ps1:
$ErrorActionPreference = 'Stop' $partition = Get-Partition -DriveLetter C $supported = Get-PartitionSupportedSize -DriveLetter C if ($supported.SizeMax -gt $partition.Size) { Resize-Partition -DriveLetter C -Size $supported.SizeMax } Unregister-ScheduledTask -TaskName 'BILLmanager Expand System Volume' ` -Confirm:$false -ErrorAction SilentlyContinue - Зарегистрируйте запуск задачи от имени системной учётной записи:
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument ( '-NoProfile -ExecutionPolicy Bypass ' + '-File "C:\ProgramData\BILLmanager\Expand-SystemVolume.ps1"' ) $trigger = New-ScheduledTaskTrigger -AtStartup Register-ScheduledTask -TaskName 'BILLmanager Expand System Volume' ` -Action $action -Trigger $trigger -User 'SYSTEM' -RunLevel Highest -Force - Проверьте задачу на копии ВМ: после увеличения диска VHDX команда
Get-Partition -DriveLetter Cдолжна показать новый размер.
Подготовка системы (Sysprep)
Запустите из PowerShell или командной строки:
& "$env:WINDIR\System32\Sysprep\Sysprep.exe" `
/generalize /oobe /shutdown /mode:vmПосле выполнения команды ВМ выключится. Не запускайте временную ВМ после выключения: следующий запуск должен происходить у созданного экземпляра с подключённым диском unattend.iso.
После выключения удалите временную машину из Hyper-V без удаления диска VHDX и перенесите диск в каталог шаблона.
Содержимое диска начальной настройки Windows
Диск unattend.iso временный ISO-образ, который модуль pmhyperv автоматически создаёт при развёртывании. Диск unattend.iso содержит пользовательский файл unattend.xml после подстановки токенов. Модуль не добавляет сетевые, DNS- или OOBE(Out-of-Box Experience)-настройки. Пользовательский конфигурационный файл должен обеспечить:
- DHCP;
- установку пароля;
- запись
BILLmanager.Provisioning=vm_<item>в гостевую ветку KVP (Key-Value Pair).
Модуль ожидает состояние VM Running и маркер готовности через VMbus, после чего удаляет unattend.iso и исходный каталог.
Публикация шаблона
- Убедитесь, что исходная ВМ выключена.
- Проверьте диск VHDX командой
Get-VHD. В выводе должны отображаться реальные данные о диске: путь, формат VHDX, тип, размер. Если команда возвращает ошибку или пустой результат, диск повреждён или не существует. - Создайте каталог, имя которого совпадает со значением
intname. - Скопируйте диск VHDX и добавьте файл template.json.
- Проверьте корректность JSON и соответствие путей в метаданных.
- Запустите синхронизацию настроек обработчика в BILLmanager.
- Выберите появившийся шаблон (
ostempl) в тестовом тарифном плане. - Создайте тестовую услугу в изолированной сети для проверки работоспособности.
- Дождитесь перехода ВМ в состояние
Runningи появления маркера готовности в KVP-пуле. - Проверьте работу внутри тестовой ВМ:
Get-NetRoute -DestinationPrefix '0.0.0.0/0' | Select-Object InterfaceAlias, NextHop, RouteMetric
Обновление шаблона
Чтобы обновить шаблон:
- Подготовьте новый каталог с временным именем.
- Полностью подготовьте и проверьте диск VHDX.
Не изменяйте диск VHDX, пока он копируется для создания новой ВМ. Изменение исходного файла во время этой операции повреждает копию и вызывает ошибку создания ВМ. - Выключите исходную ВМ.
- Замените каталог шаблона в окно технического обслуживания.
- Повторно синхронизируйте настройки обработчика.
- Создайте тестовую услугу для проверки работоспособности.
Изменение диска VHDX шаблона влияет только на новые ВМ. Ранее созданные ВМ используют собственный файл disk.vhdx в каталоге ВМ и не зависят от обновлений шаблона.
Связанные статьи: