С Hyper-V на VMware и обратно: конвертация виртуальных дисков

xsfohqeyqsuronjrbjou2t4hpqw.jpeg

Привет, Хабр!

Периодически я слышу от практикующих инженеров странное: VMDK, VHD и VHDX — абсолютно разные форматы виртуальных дисков, чуть ли не закрытые, а конвертировать из одного в другое — долго и больно. Сегодня наглядно покажу, что это не так, разберу, как эти форматы соотносятся друг с другом и как делать быструю конвертацию при миграции с Hyper-V на VMware и обратно.

Немного теории. C точки зрения свойств, виртуальные диски делятся на два типа:

  • тонкие (thin disk, dynamic disk) и 
  • толстые (thick disk, fixed disk). Все остальное — разностные, thick provisioned lazy- zeroed — лишь вариации на тему.


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

Форматы дисков


RAW — «сырой» образ любого диска. Это обычный контейнер, который не содержит никаких специфических заголовков и футеров и представляет образ диска «как есть». Если мы откроем такой образ HEX-редактором, то сразу увидим заголовки GPT/MBR и/или файловой системы. Точно такой же образ получается через команду dd в Linux. RAW в этом плане абсолютно честен с нами.

0oe897bapic5h0tljstnmhezofk.png
Начало файла RAW.

d46a-6wkfji6gv7t_i4na83c4is.png
Конец файла RAW.

VMDK. VMware ESXi — обыкновенный RAW, где геометрия диска описывается в обычном текстовом файле-описателе (дескрипторе). Именно его имя мы видим в vSphere Console, когда подключаем виртуальный диск к виртуальной машине или просматриваем содержимое каталога на Datastore. VMware ESXi ничего не делает с образом. Совсем. Диск покоится себе и расширяется по мере необходимости. В лучших традициях VMware формат описателя очень простой:

# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=fffffffe
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfs"
 
# Extent description
RW 15122560 VMFS "disk-example-flat.vmdk"
 
# The Disk Data Base
#DDB
ddb.adapterType = "lsilogic"
ddb.geometry.cylinders = "941"
ddb.geometry.heads = "255"
ddb.geometry.sectors = "63"
ddb.longContentID = "4f5dc83d0a5270bee54e2d85fffffffe"
ddb.uuid = "60 00 C2 93 b4 38 ed dd-a3 85 88 48 68 40 2f c0"
ddb.virtualHWVersion = "13"

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

Ниже представлены некоторые стандартные значения всех разделов дескриптора:

Описание всех значений можно посмотреть в спецификации формата: VMware Virtual Disk Format 1.1

VHD. Толстый VHD — тот же самый RAW, но с 512-байтным футером, где описывается геометрия диска. Какого-то отдельного файла-описателя у виртуальной машины Microsoft Hyper-V нет. Описание геометрии диска занимает 4 байта. Собственно, отсюда ограничение на размер диска в 2 Тб.

r4_z04hiog10hoi2l579iyrmd1c.png
Футер. Последние 512 байт диска.

Самое интересное, что если создать файл-описатель и подсунуть в ESXi VHD-диск с футером, то гипервизор VMware проигнорирует этот футер и примет VHD как родной.

При Storage vMotion с конвертацией диска в тонкий он просто отрежет этот футер, и на выходе мы получим тот же RAW без нулей в конце. А при конвертации в толстый диск — честный RAW. Это я и собираюсь продемонстрировать чуть позже.

VHDX. Вся информация о геометрии диска хранится в первых 4096 Кбайтах виртуального диска — в области заголовка.

oxym1rx0yugtthlby1q12svpkhy.png
Общая схема толстого диска VHDX.

Что представляет из себя эта область? В ней содержатся две копии заголовков со своими логами, BAT и область метаданных общие.

qonjv68pmpjykfcltu2rijdy7mg.png
Логическая структура заголовка диска.

В единицу времени только одна копия заголовка активна. Это обеспечивает определенный уровень отказоустойчивости заголовка в случае незапланированных прерываний операций чтения/записи. После каждой операции I/O копия реплицируется, и происходит переключение на нее.

coerbb6uef8wvkb7dsi1kzlcxda.png
Макет области заголовка.

Для конвертации VHDX в RAW нам всего-то нужно отрезать первые 4096 KB.

rijk1-iv3jiez0dicdlns3trqpe.png
Начало данных на 5 МБ.

Внимательный читатель, конечно же, скажет: ок, Женька, а слабо RAW конвертнуть в VHDX? На что я отвечу: зависит от файловой системы и от того, насколько она позволяет записывать данные в начало файла. Вручную на файловой системе NTFS это можно сделать, сместив в MFT начало файла на 4 Мб вперед и дописав в это место заголовок.

По этому же принципу работает утилита vhdxtool.exe. Однако при этом преобразовании мы не получим красивую картинку в виде 4 Мбайт заголовка и RAW. Диск будет виден и даже будет корректно работать как VHDX, но будет и много «мусора» из нулей, появившихся из-за манипуляций со смещениями (offsets). Диск будет не оптимизирован. ВМ с таким диском рекомендуется смигрировать на другой том или оптимизировать через командлеты Convert-VHD или Optimize-VHD. Если этого не сделать, диск будет занимать больше места, чем должен, и, возможно, медленнее работать.

Однако в сценариях миграции с VMware на Hyper-V эта утилита незаменима, так как позволяет провести преобразование на месте, без необходимости побайтового считывания исходного диска и создания рядом копии. Все шероховатости будут сглажены при первом же Storage Live Migration.

Вывод: толстые диски форматов VMDK, VHD, VHDX на деле мало чем отличаются друг от друга. В их основе RAW c различными добавками. Тем же HEX-редактором или функциями ОС для работы с файловой системой мы можем за пару секунд превратить 10 Тб VMDK или VHDХ в диск целевого гипервизора.

Давайте на практике посмотрим, как VMware Exsi справится с VHD. 

  1. В качестве примера я создал образ Windows Server с помощью Convert-WindowsImage с инъекцией драйверов VMware и параметрами:
    • OS Version: Windows Server 2019 Standard,
    • Disk Type: Fixed,
    • Disk Layout: GPT,
    • Disk Size: 30GB.

    7dd463979b824631f72dc3e07d821d87.png
    Обратите внимание на параметры FileSize (реальный размер файла) и Size (размер диска с точки зрения ВМ). Разница между значениями ровно 512 байт — размер футера VHD.
  2. Переименуем диск в Win2019-test2-flat.vmdk для загрузки его на ESXi Datastore.
    2012093e774ea467727395d88ca66dd6.png
  3. Далее я создаю в VMware ESXi пустую ВМ с диском Thick (Eager Zeroed), чтобы дескриптор VMDK создался автоматически и не приходилось высчитывать цилиндры вручную.

    _o7h3r7hzjarnxzu2ulhshxmcxw.png

  4. Подключаемся к хосту через WinSCP и заменяем существующий файл:
    jgi9hh7y3kf2baf6nc6dpty-vci.png
    Все честно: футер на месте.
  5. Включаем ВМ и видим, что ОС без проблем загрузилась. Осталось только установить VMware Tools, что будет просто, так как Convert-WindowsImage позволяет нам установить драйверы устройств.

    hhtd0bx6ca4fzhkr_qjl8z1oizq.png

  6. Переместим диск на другой Datastore через Storage vMotion с конвертацией его в тонкий диск.

    -x2wli_oyqrl9qdy4sabgb2ilpg.png

  7. Проверяем размер — диск стал тонким.

    _bm2vhobiqdotr59i_t1xbu903c.png

  8. Если мы проведем обратную конвертацию в толстый диск или смигрируем ВМ на файловое хранилище, то получим чистейший RAW без заголовков.

     s6p4esa78nxqqwuramt6xyrr7fi.png
    Футер отрезался.

Тот же самый фокус работает и для RAW, созданных через dd. И даже в обратном направлении. Таким образом вы видите, что VMware ESXi принимает диски с футерами или RAW, созданные сторонними средствами.
Если не хочется фокусов, то можно воспользоваться инструментами ниже.

Подведем итоги. Различные форматы толстых виртуальных дисков не такие уж разные. В основе всего RAW с различными «добавками».
Конвертация форматов виртуальных дисков — это не страшно, и, как я показал, иногда можно обходится даже без нее.

Основной профит всего этого — сокращение времени миграции с Hyper-V на VMware и обратно и времени простоя ВМ при миграции. В DataLine мы такое практикуем с простоем ВМ менее 30 минут. Рекорд же — 40 секунд простоя ВМ при миграции между гипервизорами.

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

Полезные ссылки:

© Habrahabr.ru