Базовая процедура миграции виртуальной машины из среды виртуализации oVirt в среду Hyper-V была рассмотрена ранее в статье Миграция виртуальной машины oVirt 4.2 на Hyper-V (конвертация в VHDX). То есть сначала виртуальная машина экспортируется из oVirt в качестве контейнера OVA, затем файл *.ova распаковывается и вложенный в него RAW-диск с помощью утилиты qemu-img конвертируется в формат VHDX. Запуск виртуальной машины Hyper-V с полученным в результате миграции VHDX-диском не представляет сложностей в том случае, если ВМ была создана в формате Hyper-V Gen1. Проблема может возникнуть, если мы захотим без предварительных манипуляций создать на основе полученного диска виртуальную машину Hyper-V Gen2. Далее мы рассмотрим такую ситуацию с вариантом решения поставленной задачи, опирающимся на статью Jens Getreu - Switch Debian from legacy to UEFI boot mode.
Создание виртуальной машины Hyper-V Gen2
Поколение виртуальной машины Hyper-V определяется на этапе её создания. Создадим новую ВМ в формате Generation 2.
Подключим к созданной виртуальной машине VHDX диск, полученный в результате миграции с платформы oVirt.
Так как внутри виртуальной машины планируется запуск гостевой ОС Linux Debian 8, то согласно рекомендации документа Supported Debian virtual machines on Hyper-V , нам потребуется отключить Secure Boot в свойствах ВМ в разделе настроек Firmware.
Несмотря на то, что наша гостевая система Linux Debian поддерживает работу с UEFI, созданная нами виртуальная машина Hyper-V Gen2 не загрузится, выдав ошибку "Boot Failed. EFI SCSI Devices."
Связано это с тем, что структура разделов на диске не соответствует ожиданиям стандарта UEFI. То есть проблема заключается в том, что на диске используется старая таблица разделов MBR, вместо нужной для EFI таблицы разделов GPT, и, что на диске нет выделенного раздела с EFI загрузчиком.
Соответственно для того, чтобы попытаться завести нашу Linux систему в виртуальной машине Hyper-V второго поколения, нам потребуется для начала без потери данных преобразовать таблицу разделов из MBR в GPT, а затем выполнить создание загрузочного раздела с последующей настройкой гостевой ОС Linux.
Учитывая то, что конвертация таблицы разделов на диске - операция серьёзная, а возможные проблемы в процессе этой операции могут привести в потере данных, перед началом процедуры крайне рекомендуется сделать резервную копию виртуального диска, с которым мы будем проводить работу.
Все нужные действия мы сможем выполнить с помощью загрузочного Live Boot CD с OC Linux с поддержкой UEFI и присутствием таких инструментов как gparted. В нашем случае в качестве загрузочного диска выбран ISO-образ GParted Live Boot CD, актуальную версию которого можно загрузить по ссылке GNOME Partition Editor - Downloads
В нашем примере будет использоваться актуальная на данный момент версия GParted Live Boot CD 0.33.0-1 (64-bit)
В конфигурации виртуальной машины на SCSI Controller добавляем в DVD-привод, укладываем в него ISO образ и в разделе Firmware выставляем загрузку с привода.
Включаем виртуальную машину и дожидаемся загрузки рабочей среды GParted Live Boot CD. После автоматического входа в систему будет загружена графическая утилита GParted, в которой мы увидим расположение разделов на нашем виртуальном диске.
Высвобождение дискового ресурса под раздел EFI System Partition
В нашем случае это один диск /dev/sda размером 30GiB с таблицей разделов MBR. На диске есть один основной загрузочный раздел /dev/sda1 и один расширенный /dev/sda2, содержащий в себе небольшой раздел под swap.
Нам нужно освободить в начале диска небольшой объём под создание выделенного загрузочного раздела EFI System Partition (ESP).
О размере раздела ESP в разных источниках можно встретить разные рекомендации. По одним данным для загрузчика UEFI достаточно нескольких мегабайт, по другим данным - размер раздела ESP может быть от 100 до 500MB. Предполагаю, что делать большой раздел ESP имеет смысл в том случае, если планируется использовать расширенную загрузку нескольких систем. В нашем случае загружаемая система будет только одна, и поэтому (с учётом некоторой перестраховки) в определении размера мы остановимся на размере в 250MB.
Чтобы у нас появилась возможность создать новый раздел в начале диска, нам предварительно потребуется выполнить сжатие существующего первого раздела диска на объём нового раздела. Выберем в GParted раздел, который нужно сжать, и на верхней панели кнопок или в контекстном меню действий для раздела выберем пункт Resize/Move
В открывшейся форме укажем объём дискового пространства, которое мы хотим высвободить. В нашем примере указан высвобождаемый объём в 239MiB, что равно ~250MB, перед разделом, который будет сжиматься.
После нажатия кнопки Resize/Move мы получим грозное предупреждение о том, что изменение стартового сектора для некоторых разделов может привести к невозможности загрузки ОС.
В нижней части главного окна GParted появится выбранная нами операция сжатия и сдвига раздела с нашей гостевой Linux-системой. Нажмём кнопку Apply, чтобы запустить непосредственный процесс выполнения.
Нам ещё раз напомнят о том, что перед выполнением подобных операций неплохо сделать резервную копию данных с диска, так как в случае если "что-то пойдёт не так" мы можем потерять данные.
Дождёмся окончания процесса, который может занять некоторое время в зависимости от скорости нашего дискового накопителя и объёма изменяемого раздела
Конвертация таблицы разделов диска из MBR в GPT
Теперь запустим с рабочего стола загруженной Live-среды окно терминала, перейдём в режим супер-пользователя и с помощью утилиты gdisk получим информацию о текущей таблице разделов интересующего нас диска /dev/sda:
$ sudo su -
# gdisk -l /dev/sda
Как видим, сейчас таблица разделов имеет формат MBR.
С помощью утилиты gdisk выполним конвертирование таблицы разделов в формат GPT без потери данных на диске. Для этого сначала войдём в режим работы с утилитой, указав ей в качестве входного параметра только имя диска
# gdisk /dev/sda
Запросим у утилиты список возможных операций с помощью команды "help".
Среди списка команд нас интересует вызов режима восстановления и трансформации с помощью клавиши "r".
Перейдя в режим трансформации, у которого есть собственный набор ключевых клавиш, получим их список командой "?".
Выберем клавишу "f" для построения GPT таблицы разделов из имеющейся MBR таблицы.
После этого нам будет задан вопрос о том, действительно ли мы хотим удалить текущую таблицу разделов (MBR). Утвердительно жмём "Y".
Сразу после этого жмём "w", чтобы произвести запись новой таблицы разделов (в формате GPT) на диск и утвердительно отвечаем на последующий вопрос "Y".
После успешного обновления таблицы разделов на диске утилита gdisk завершит свою работу.
Создание раздела под EFI System Partition
Однако, нам снова потребуется вернуться к утилите gdisk для того, чтобы она помогла нам создать новый раздел под загрузчик EFI в ранее высвобожденном свободном месте в начале диска.
# gdisk /dev/sda
Обратите внимание на то, что теперь утилита отображает информацию о том, что на нашем диске используется таблица разделов GPT, а из перечня ключевых клавиш нам нужно выбрать "n" для создания нового раздела.
На последующий запрос о вводе номера раздела, выбираем предлагаемый по умолчанию номер "2".
Следующие два запроса будут определять номер начального и конечного сектора диска для создаваемого раздела. Для того, чтобы использовать всё ранее освобождённое нами дисковое пространство, достаточно согласиться с предлагаемыми по умолчанию значениями номеров секторов и просто два раза нажать Enter.
На следующий запрос о выборе типа раздела укажем значение "ef00".
Теперь с помощью ключа "p" запросим информацию об имеющихся на диске разделах и убедимся в наличии раздела для EFI.
Записываем отредактированную нами таблицу разделов диска с помощью ключевой клавиши "w" и утвердительно отвечаем на вопрос о перезаписи существующей таблицы разделов – "Y".
В результате успешного обновления таблицы разделов утилита завершит свою работу.
Следующим шагом нам нужно отформатировать только что созданный ESP-раздел в файловую систему FAT32.
Выполним команду partprobe, чтобы проинформировать нашу Live-систему об изменении таблицы разделов.
С помощью lsblk ещё раз проверим имя раздела, который нужно отформатировать и выполним его форматирование.
# partprobe -s /dev/sda
# mkfs.vfat /dev/sda2
Итак, на данный момент мы имеем сконвертированную в формат GPT таблицу разделов диска, имеем специальный выделенный раздел под загрузчик EFI, однако этот раздел пока пуст и в самой гостевой Linux системе нет упоминаний об этом разделе. Решим этот вопрос с помощью монтирования гостевой Linux системы в chroot-окружение и выполним в этом окружении нужное нам конфигурирование гостевой ОС.
Подготовка гостевой Linux Debian под EFI загрузчик
Корневой загрузочный раздел гостевой ОС Linux в нашем примере в загруженной Live-системе определён, как /dev/sda1 и имеет файловую систему ext4. Смонтируем его в каталог /mnt загруженной Live-системы.
# mount -t ext4 /dev/sda1 /mnt
В каталоге /boot гостевой системы (/mnt/boot) создадим подкаталог efi и смонтируем туда ранее созданный и отформатированный в FAT раздел ESP:
# mkdir /mnt/boot/efi
# mount /dev/sda2 /mnt/boot/efi
Смонтируем из гостевой ОС в /mnt в Live-систему служебные каталоги для работы chroot окружения
# mount --bind /sys /mnt/sys
# mount --bind /proc /mnt/proc
# mount --bind /dev /mnt/dev
# mount --bind /dev/pts /mnt/dev/pts
Все выше обозначенные команды должны отработать без ошибок.
Теперь нам нужно внести правку в fstab гостевой системы, добавив туда директиву для монтирования загрузочного раздела EFI. Но для этого нам понадобиться узнать идентификатор UUID этого раздела. Выясним идентификатор UUID ESP-раздела командой вида:
# ls -lh /dev/disk/by-uuid
Как видим, в нашем случае ESP-раздел /dev/sda2 имеет идентификатор UUID равный "EB1A-1D3F"
Откроем на редактирование принадлежащий гостевой системе конфигурационный фaйл fstab ...
# nano /mnt/etc/fstab
... добавим в конец файла запись о EFI разделе, указав соответствующий идентификатор UUID этого раздела. В нашем случае строка монтирования раздела будет выглядеть так:
# EFI Partition
UUID=EB1A-1D3F /boot/efi vfat umask=0077 0 1
Сохраняем внесённые в файл fstab изменения и переходим к этапу работы в chroot окружении.
Монтируем chroot окружение
# chroot /mnt
Перед тем как продолжить, мы должны обеспечить нашей системе, загруженной в chroot-окружении доступ в Интернет, так как потребуется установка загрузчика GRUB, отличного от того, что сейчас имеется в гостевой системе.
Если наша Live-система была загружена в сетевом окружении, не имеющем DHCP, то сейчас нам потребуется настроить статическую адресацию IP.
Проверим текущие настройки IP:
# ip addr
Как видим, в нашем случае сеть не настроена. Выполним временные настройки сети, то есть включим интерфейс, зададим ему временный IP адрес и укажем адрес шлюза по умолчанию.
# ip link set eth0 up
# ip addr add 10.0.0.250/255.255.255.0 dev eth0
# ip route add default via 10.0.0.1
Обеспечим для назначенного IP адреса доступ в Интернет.
Проверим работоспособность клиента DNS, убедившись в успешности разрешения интернет-имён:
Замена загрузчика GRUB
Удаляем из гостевой системы пакет grub, ориентированный на старый тип загрузки Legacy BIOS с MBR.
# apt-get remove grub-pc
Устанавливаем новый загрузчик, ориентированный на EFI.
# apt-get install grub-efi
Выполняем инициализацию загрузчика, указав ему наш диск.
# grub-install /dev/sda
Убеждаемся в том, что в каталоге /boot/efi появился соответствующей нашей гостевой ОС файл загрузчика.
# file /boot/efi/EFI/debian/grubx64.efi
Утилита управления EFI-загрузчиком efibootmgr покажет возможные источники загрузки и их текущий порядок. Убедимся в том, что там присутствует debian
# efibootmgr
На этом подготовку ESP-раздела к работе можно считать законченной.
Выходим из chroot-окружения и выключаем Live-систему
# exit
# poweroff
Загрузка ВМ с EFI загрузчика
Откроем свойства ВМ и обратим внимание на настройки порядка загрузки в разделе Firmware. После наших манипуляций с ВМ в перечне источников загрузки появился объект типа File, имеющий ссылку на EFI-загрузчик в ESP-разделе, который мы только что создали на диске ВМ.
Этот EFI-загрузчик нужно выставить первым по порядку загрузки.
Теперь с текущими настройками EFI снова пробуем запустить виртуальную машину и убеждаемся в том, что гостевая ОС Linux Debian успешно запускается.
В случае возникновения проблем с работой сети в гостевой ОС Linux, связанных с изменением MAC адреса сетевого интерфейса, способ решения можно найти в заметке про настройку статического MAC адреса в Hyper-V. Не смотря на то, что в нашем случае данной проблемы не возникает, стоит помнить про документ о лучших практиках (Best Practices for running Linux on Hyper-V), где есть рекомендация фиксировать MAC адрес для ВМ с Linux в том случае, если ВМ выполняется в кластере Hyper-V.
Компоненты интеграции Hyper-V
Виртуальная гостевая система успешно запущена и нам остаются последние штрихи, касающиеся интеграции со средой виртуализации Hyper-V.
Удаляем ПО предыдущей среды управления виртуализацией - агента oVirt
# apt-get remove ovirt-guest-agent -y
# apt-get remove qemu-guest-agent -y
Устанавливаем компоненты интеграции Hyper-V
# apt-get install hyperv-daemons -y
# reboot
После этого загрузка гостевой ОС должна выполняться быстрей.
Работоспособность основных важных компонент интеграции Hyper-V, таких как служба VSS, можем проверить как описано в заметке Вики: Установка и проверка компонент интеграции Hyper-V в Debian GNU/Linux.
Вместо заключения
По большому счёту описанная последовательность действий может быть применима не только в случае необходимости миграции ВМ из других сред виртуализации в ВМ Hyper-V G2, но и в случае необходимости миграции гостевых Linux систем с поддержкой UEFI из ВМ Hyper-V Gen1 в ВМ Hyper-V G2. Сам же принцип миграции Legacy BIOS -> UEFI с некоторыми оговорками может быть применён и на физических Linux-системах.
Дополнительные источники информации:
- Jens Getreu - Switch Debian from legacy to UEFI boot mode
- LinuxTopic - Steps to Convert MBR to GPT Ubuntu / Debian with Images
- AskUbuntu - Which commands to convert a Ubuntu BIOS install to EFI/UEFI without boot-repair on single boot hardware?
- Ubuntu Wiki - Особенности установки на платы с UEFI
- Debian Wiki - UEFI
Алексей, а почему Вам потребовалось переносить linux vm на hyper-v? Вы разочаровались в ovirt?
Ваше любопытство меня удивляет :). Потребовалась и всё. Безотносительно моего отношения к oVirt. oVirt - это серьёзная самодостаточная платформа виртуализации, которая, к тому же, постоянно развивается. И рассуждать о разочаровании в этой платформе может лишь тот, кто "не осилил".
Спасибо.
На самом деле ничего удивительного.
Во-первых изначально Вы позиционировали ovirt как виртуализацию для linux vm, hyper-v не устраивал (кажется подвисали вм).
Во-вторых я не оставляю мысли о переходе когда-нибудь на oVirt. Я пытаюсь собрать и держать по нему актуальную информацию. Т. е. для каких целей может понадобиться держать и использовать 2-е виртуализации, в том числе и перенос linux vm на hyper-v. В идеале использовать одну ovirt и не тратиться на hyper-v.
Я рад слышать, что на текущий момент ovirt Вас устраивает.
Обратная ссылка: Миграция виртуальной машины c Linux CentOS 6 (Avaya IP Office Server) из среды oVirt в Hyper-V Gen2 с конвертацией диска из формата загрузчика Legacy BIOS (таблица раздело /
После развертки образа debian (с legacy bios как выяснилось потом) с помощью Clonezilla на VM формата hyper-v gen 2, система не загрузилась. Сделал все по инструкции. Только пара отличий: выполнение grub-install /dev/sda выдавало сообщение
"grub-install efi variables are not supported on this system",
но без ошибок; файл /boot/efi/EFI/debian/grubx64.efi создался, но при выполнении
efibootmgr
опять вышло "grub-install efi variables are not supported on this system" и ничего более.
В конфигурации загрузки ВМ опции с grubx64.efi не появилось.
Проделал то же самое только с изначальным VM gen 1, результат такой же.
В итоге, на шаге формирования файла загрузчика выполнил
grub-install --removable /dev/sda
Создался /boot/efi/EFI/BOOT/BOOTX64.efi и ВМ самостоятельно загрузилась.