Миграция виртуальной машины c Linux Debian 8 из среды oVirt в Hyper-V Gen2 с конвертацией диска из формата загрузчика Legacy BIOS (таблица разделов MBR) в формат UEFI (таблица разделов GPT)

Hyper-V VM with Debian Linux and EFI BootБазовая процедура миграции виртуальной машины из среды виртуализации 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.

Create Hyper-V Generation 2 VM

Подключим к созданной виртуальной машине VHDX диск, полученный в результате миграции с платформы oVirt.

Так как внутри виртуальной машины планируется запуск гостевой ОС Linux Debian 8, то согласно рекомендации документа Supported Debian virtual machines on Hyper-V , нам потребуется отключить Secure Boot в свойствах ВМ в разделе настроек Firmware.

Hyper-V VM settings - Disable Secure Boot

Несмотря на то, что наша гостевая система Linux Debian поддерживает работу с UEFI, созданная нами виртуальная машина Hyper-V Gen2 не загрузится, выдав ошибку "Boot Failed. EFI SCSI Devices."

Linux Hyper-V VM 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 выставляем загрузку с привода.

Hyper-V VM Settings - DVD Drive

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

Высвобождение дискового ресурса под раздел EFI System Partition

В нашем случае это один диск /dev/sda размером 30GiB с таблицей разделов MBR. На диске есть один основной загрузочный раздел /dev/sda1 и один расширенный /dev/sda2, содержащий в себе небольшой раздел под swap.

Gparted main window

Нам нужно освободить в начале диска небольшой объём под создание выделенного загрузочного раздела EFI System Partition (ESP).

О размере раздела ESP в разных источниках можно встретить разные рекомендации. По одним данным для загрузчика UEFI достаточно нескольких мегабайт, по другим данным - размер раздела ESP может быть от 100 до 500MB. Предполагаю, что делать большой раздел ESP имеет смысл в том случае, если планируется использовать расширенную загрузку нескольких систем. В нашем случае загружаемая система будет только одна, и поэтому (с учётом некоторой перестраховки) в определении размера мы остановимся на размере в 250MB.

Чтобы у нас появилась возможность создать новый раздел в начале диска, нам предварительно потребуется выполнить сжатие существующего первого раздела диска на объём нового раздела. Выберем в GParted раздел, который нужно сжать, и на верхней панели кнопок или в контекстном меню действий для раздела выберем пункт Resize/Move

Gparted Resize Partition

В открывшейся форме укажем объём дискового пространства, которое мы хотим высвободить. В нашем примере указан высвобождаемый объём в 239MiB, что равно ~250MB, перед разделом, который будет сжиматься.

Gparted Resize Partition Free space

После нажатия кнопки Resize/Move мы получим грозное предупреждение о том, что изменение стартового сектора для некоторых разделов может привести к невозможности загрузки ОС.

Gparted Resize Partition warning

В нижней части главного окна GParted появится выбранная нами операция сжатия и сдвига раздела с нашей гостевой Linux-системой. Нажмём кнопку Apply, чтобы запустить непосредственный процесс выполнения.

Gparted Resize Partition operation pending

Нам ещё раз напомнят о том, что перед выполнением подобных операций неплохо сделать резервную копию данных с диска, так как в случае если "что-то пойдёт не так" мы можем потерять данные.

Gparted Resize boot partition warning

Дождёмся окончания процесса, который может занять некоторое время в зависимости от скорости нашего дискового накопителя и объёма изменяемого раздела

Gparted move boot partition

Конвертация таблицы разделов диска из MBR в GPT

Теперь запустим с рабочего стола загруженной Live-среды окно терминала, перейдём в режим супер-пользователя и с помощью утилиты gdisk получим информацию о текущей таблице разделов интересующего нас диска /dev/sda:

$ sudo su -
# gdisk -l /dev/sda

gdisk list of partitions

Как видим, сейчас таблица разделов имеет формат MBR.

С помощью утилиты gdisk выполним конвертирование таблицы разделов в формат GPT без потери данных на диске. Для этого сначала войдём в режим работы с утилитой, указав ей в качестве входного параметра только имя диска

# gdisk /dev/sda

gdisk MBR table

Запросим у утилиты список возможных операций с помощью команды "help".

Среди списка команд нас интересует вызов режима восстановления и трансформации с помощью клавиши "r".

gdisk main help

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

Выберем клавишу "f" для построения GPT таблицы разделов из имеющейся MBR таблицы.

gdisk covert MBR to GPT

После этого нам будет задан вопрос о том, действительно ли мы хотим удалить текущую таблицу разделов (MBR). Утвердительно жмём "Y".

Сразу после этого жмём "w", чтобы произвести запись новой таблицы разделов (в формате GPT) на диск и утвердительно отвечаем на последующий вопрос "Y".

gdisk covert MBR to GPT write changes

После успешного обновления таблицы разделов на диске утилита gdisk завершит свою работу.

Создание раздела под EFI System Partition

Однако, нам снова потребуется вернуться к утилите gdisk для того, чтобы она помогла нам создать новый раздел под загрузчик EFI в ранее высвобожденном свободном месте в начале диска.

# gdisk /dev/sda

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

gdisk add partition

На последующий запрос о вводе номера раздела, выбираем предлагаемый по умолчанию номер "2".

Следующие два запроса будут определять номер начального и конечного сектора диска для создаваемого раздела. Для того, чтобы использовать всё ранее освобождённое нами дисковое пространство, достаточно согласиться с предлагаемыми по умолчанию значениями номеров секторов и просто два раза нажать Enter.

На следующий запрос о выборе типа раздела укажем значение "ef00".

gdisk add EFI partition

Теперь с помощью ключа "p" запросим информацию об имеющихся на диске разделах и убедимся в наличии раздела для EFI.

Записываем отредактированную нами таблицу разделов диска с помощью ключевой клавиши "w" и утвердительно отвечаем на вопрос о перезаписи существующей таблицы разделов – "Y".

gdisk write partiton table to disk

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

Следующим шагом нам нужно отформатировать только что созданный ESP-раздел в файловую систему FAT32.

Выполним команду partprobe, чтобы проинформировать нашу Live-систему об изменении таблицы разделов.

С помощью lsblk ещё раз проверим имя раздела, который нужно отформатировать и выполним его форматирование.

# partprobe -s /dev/sda
# mkfs.vfat /dev/sda2

Linux format partition to FAT32

Итак, на данный момент мы имеем сконвертированную в формат 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

Все выше обозначенные команды должны отработать без ошибок.

mount system dirs for chroot

Теперь нам нужно внести правку в fstab гостевой системы, добавив туда директиву для монтирования загрузочного раздела EFI. Но для этого нам понадобиться узнать идентификатор UUID этого раздела. Выясним идентификатор UUID ESP-раздела командой вида:

# ls -lh /dev/disk/by-uuid

Linux get partition 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

Linux EFI partition in fstab

Сохраняем внесённые в файл fstab изменения и переходим к этапу работы в chroot окружении.

Монтируем chroot окружение

# chroot /mnt

Перед тем как продолжить, мы должны обеспечить нашей системе, загруженной в chroot-окружении доступ в Интернет, так как потребуется установка загрузчика GRUB, отличного от того, что сейчас имеется в гостевой системе.

Если наша Live-система была загружена в сетевом окружении, не имеющем DHCP, то сейчас нам потребуется настроить статическую адресацию IP.

Проверим текущие настройки IP:

# ip addr

Linux chroot

Как видим, в нашем случае сеть не настроена. Выполним временные настройки сети, то есть включим интерфейс, зададим ему временный 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

Linux Debian set static IP address

Обеспечим для назначенного IP адреса доступ в Интернет.

Проверим работоспособность клиента DNS, убедившись в успешности разрешения интернет-имён:

Linux check host name resolution

Замена загрузчика GRUB

Удаляем из гостевой системы пакет grub, ориентированный на старый тип загрузки Legacy BIOS с MBR.

# apt-get remove grub-pc

Linux delete Legacy BIOS GRUB

Устанавливаем новый загрузчик, ориентированный на EFI.

# apt-get install grub-efi

Linux install EFI GRUB

Выполняем инициализацию загрузчика, указав ему наш диск.

# grub-install /dev/sda

Linux grub-install

Убеждаемся в том, что в каталоге /boot/efi появился соответствующей нашей гостевой ОС файл загрузчика.

# file /boot/efi/EFI/debian/grubx64.efi

Linux EFI boot file

Утилита управления EFI-загрузчиком efibootmgr покажет возможные источники загрузки и их текущий порядок. Убедимся в том, что там присутствует debian

# efibootmgr

Linux EFI boot order

На этом подготовку ESP-раздела к работе можно считать законченной.

Выходим из chroot-окружения и выключаем Live-систему

# exit
# poweroff
Загрузка ВМ с EFI загрузчика

Откроем свойства ВМ и обратим внимание на настройки порядка загрузки в разделе Firmware. После наших манипуляций с ВМ в перечне источников загрузки появился объект типа File, имеющий ссылку на EFI-загрузчик в ESP-разделе, который мы только что создали на диске ВМ.

Hyper-V VM Settings EFI boot file for Linux

Этот EFI-загрузчик нужно выставить первым по порядку загрузки.

Теперь с текущими настройками EFI снова пробуем запустить виртуальную машину и убеждаемся в том, что гостевая ОС Linux Debian успешно запускается.

Linux Debian 8 EFI Boot in Hyper-V VM

В случае возникновения проблем с работой сети в гостевой ОС 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-системах.

Дополнительные источники информации:

Всего комментариев: 4 Комментировать

  1. AlektroNik /

    Алексей, а почему Вам потребовалось переносить linux vm на hyper-v? Вы разочаровались в ovirt?

    1. Алексей Максимов / Автор записи

      Ваше любопытство меня удивляет :). Потребовалась и всё. Безотносительно моего отношения к oVirt. oVirt - это серьёзная самодостаточная платформа виртуализации, которая, к тому же, постоянно развивается. И рассуждать о разочаровании в этой платформе может лишь тот, кто "не осилил".

      1. AlektroNik /

        Спасибо.

        На самом деле ничего удивительного.

        Во-первых изначально Вы позиционировали ovirt как виртуализацию для linux vm, hyper-v не устраивал (кажется подвисали вм).

        Во-вторых я не оставляю мысли о переходе когда-нибудь на oVirt. Я пытаюсь собрать и держать по нему актуальную информацию. Т. е. для каких целей может понадобиться держать и использовать 2-е виртуализации, в том числе и перенос linux vm на hyper-v. В идеале использовать одну ovirt и не тратиться на hyper-v.

        1. AlektroNik /

          Я рад слышать, что на текущий момент ovirt Вас устраивает.

Добавить комментарий