Загрузка Виртуальных Машин Linux С Диска Без Разделов

При создании корневых дисков для виртуальных машин на них обычно создается таблица разделов с помощью fdisk/gdisk с одним разделом для размещения операционной системы.

Это вызывает некоторые проблемы на стороне гипервизора, например:

  • Монтируя диск, нужно помнить, что монтируется не само блочное устройство, а раздел на нем.

    Проблема усугубляется, если используется lvm-диск - ядро не видит разделы на нем без использования инструментов убеждения в виде kpartx.

  • Для восстановления раздела нужна не только резервная копия файловой системы, но и ромб/копия первой дорожки.

  • Изменение размера такого диска требует еще одного раунда ненужных операций по изменению размера раздела на диске.

Избавиться от таблицы разделов можно и непосредственной загрузкой ядра, но этот способ не без греха.

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

Хочу рассказать об альтернативном варианте загрузки с диска без разделов с помощью EFI и GRUB2. Все будет происходить в libvirt, qemu, kvm, Ubuntu.

Краткое содержание

Ниже мы опишем, как загрузить виртуальную машину в режиме EFI с виртуального USB-диска, который отражает каталог с версией grub EFI, настроенной на загрузку меню с диска без разделов.

Уф.

Плюс пара граблей на подходе.

настройка домена libvirt, о котором пойдет речь

  
  
  
  
  
   

<domain type='kvm' id='23'> <name>aster</name> <uuid>d4ee890e-658c-9ff3-6242-9569be3aa154</uuid> <memory unit='KiB'>524288</memory> <currentMemory unit='KiB'>524288</currentMemory> <vcpu placement='static'>1</vcpu> <resource> <partition>/machine</partition> </resource> <os> <type arch='x86_64' machine='pc-i440fx-1.5'>hvm</type> <loader>/opt/ovmf/OVMF.fd</loader> <boot dev='hd'/> </os> <features> <acpi/> <apic/> <pae/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> <emulator>/usr/bin/kvm-spice</emulator> <disk type='block' device='disk'> <driver name='qemu' type='raw'/> <source dev='/dev/mapper/ssd-aster--root'/&qt; <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </disk> <disk type='dir' device='disk'> <driver name='qemu'/> <source dir='/var/spool/efi-grub/'/&qt; <target dev='sda' bus='usb'/> <readonly/> <alias name='usb-disk0'/> </disk> <controller type='pci' index='0' model='pci-root'> <alias name='pci.0'/> </controller> <controller type='usb' index='0'> <alias name='usb0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <memballoon model='virtio'> <alias name='balloon0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </memballoon> </devices> </domain>



ЭФИ БИОС

При чем здесь EFI? Загрузка в режиме EFI позволяет нам размещать grub-efi в обычной файловой системе и не требует MBR. Прежде всего нам нужен биос для qemu с поддержкой EFI. Это называется ОВМФ .

Из всего скачанного богатства нужен только OVMF.fd (здесь и далее предполагается, что он находится в /opt/ovmf/).

OVMF подключается в разделе os домена с помощью тега loader:

<os> <type arch='x86_64' machine='pc-i440fx-1.5'>hvm</type> <loader>/opt/ovmf/OVMF.fd</loader> <boot dev='hd'/> </os>



Погрузчик

Теперь наша виртуальная машина может загружаться по-современному.

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

Давайте подготовим grub-efi:

mkdir -p /var/spool/efi-grub/efi/boot/ grub-mkimage -O x86_64-efi -d /usr/lib/grub/x86_64-efi/ -o /var/spool/efi-grub/efi/boot/bootx64.efi -p "(hd1)/boot/grub/" part_gpt part_msdos fat ext2 normal chain boot configfile linux multiboot efi_gop efi_uga

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

Дело в том, что по умолчанию OVMF-BIOS попытается загрузить файл /efi/boot/bootx64.efi из раздела EFI. Воспользуемся этим и подсунем туда grub-efi, который возьмет свой конфиг со второго диска в системе из /boot/grub/.

В дальнейшем этот загрузчик можно будет использовать для многих виртуальных машин, подключив его к диску, доступному только для чтения, и при условии, что диск с /boot/grub будет вторым в системе.



Раздел EFI и грабли

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

Вы можете создать небольшой диск, разместить таблицу разделов GPT и раздел EFI с загрузчиком.

Если этот диск подключен в режиме «только чтение», то один такой диск можно использовать для нескольких виртуальных машин.

Но здесь есть грабли.

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

Более того, эта оболочка прекрасно увидит наш раздел и загрузит загрузчик командой «bootx64.efi», но без рук сделать это не получится.

Здесь здесь Ребята подробно обсуждают и выясняют почему и сходятся во мнении, что это баг OVMF. Поэтому вам придется подключить диск к шине ide. Это рабочий вариант, но диски не могут быть доступны только для чтения.

Вам нужно будет соблюдать гигиену в отношении этого диска внутри гостя и (возможно) попрощаться с идеей запуска нескольких машин с одним загрузчиком.

Есть лучший вариант.

Зеркальное отображение каталога на диске в Qemu
Qemu может создавать виртуальные диски из каталогов.

Это выглядит так:

<disk type='dir' device='disk'> <source dir='/var/spool/efi-grub/'/&qt; <target dev='sda' bus='usb'/> <readonly/> </disk>

В этом случае в гостевой системе появится диск с таблицей разделов в MBR, раздел в FAT16 с содержимым каталога на нем.

У этого диска есть пара важных для нас особенностей — при его подключении требуется атрибут readonly и раздел на нем имеет тип 0x06, а не 0xEF, как того требует EFI. К счастью, загрузиться с такого раздела можно, если подвесить диск на шину USB. В этом случае OVMF-BIOS будет искать загрузчик в обычном разделе FAT. И тут есть еще грабли.

Вы сильно пострадаете от них, если apparmor работает, а в Ubuntu он работает по умолчанию.

Для каждой виртуальной машины libvirt создает профиль apparmor, который предоставляет ей доступ только к ресурсам, указанным в ее конфигурации.

Для диска, сделанного из каталога, правила создаются некорректно, поэтому стоит добавить в /etc/apparmor.d/abstractions/libvirt-qemu следующие строки:

/var/spool/efi-grub/ r, /var/spool/efi-grub/** r,



Важные заметки

Теперь вы можете создавать виртуальные машины, создавая диски непосредственно на томах lvm, легко и безопасно менять их размер, не заморачиваться установкой загрузчика на новых машинах, развернутых с помощью debootstrap, делать резервные копии корневых систем с помощью дампа и восстанавливать их простым восстановлением.

Однако существуют некоторые ограничения.

OVMF всегда будет размещать диски на шинах USB и IDE раньше, чем диски на virtio, и мы жестко запрограммировали его в grub для загрузки меню и модулей со второго диска (первый — диск с загрузчиком):

grub-mkimage -O x86_64-efi -d /usr/lib/grub/x86_64-efi/ -o /var/spool/efi-grub/efi/boot/bootx64.efi -p "(hd1)/boot/grub/" part_gpt part_msdos fat ext2 normal chain boot configfile linux multiboot efi_gop efi_uga

Мы сделали это с помощью параметра -p "(hd1)/boot/grub/".

Здесь (hd1) как раз указывает на второй диск (первый соответственно (hd0)).

Имейте это в виду, если вы устанавливаете в свой автомобиль диски, отличные от Virtio. Также нужно помнить, что grub может динамически загружать дополнительные модули из /boot/grub корневого раздела, а поскольку гостевые системы могут быть разными, версии этих модулей могут быть несовместимы с загрузчиком из EFI-раздела.

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

Теги: #Виртуализация #libvirt #QEMU #efi

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.