Создать vhd в linux

Обновлено: 04.07.2024

Загрузка Linux с VHD может пригодиться в различных сценариях, например, когда на компьютере установлена Windows и есть необходимость в Linux, но WSL или виртуальной машины с Linux недостаточно, а разбивать диск на разделы нет желания. Microsoft позволяет грузить Windows с VHD «из коробки» начиная со старших редакций Windows 7. Но что делать, если возникла необходимость загрузить таким способом Linux?

На форумах часто можно встретить мнение, что загрузить Linux с VHD либо нельзя, либо очень сложно. Полезной информации в интернете на эту тему действительно мало. Базовая идея, как это осуществить, описана тут. Суть в следующем:

Необходимо убедиться в поддержке NTFS на всех этапах.

Необходимо убедиться в поддержке loop-устройств.

Добавить в загрузочные скрипты ОС команду монтирования loop-устройства.

Убедиться, что все необходимые утилиты добавлены в образ, обновить initramfs внутри VHD.

В случае legacy-зарузки (BIOS) и использования штатного загрузчика Windows добавить grub4dos в меню bootmgr, а в меню grub4dos добавить пункт для загрузки с VHD.

Практическое применение этой идеи для Arch Linux описано тут. В этой статье я проведу аналогичный эксперимент с Debian. Предполагается, что читатель имеет представление о работе с консолью в Windows и в Linux, умеет работать со стандартными системными утилитами, с ПО для виртуализации и т.п. — элементарные вещи подробно не расписаны.

Процесс загрузки будет выглядеть так: bootmgr -> grub4dos -> initramfs -> debian. Рассмотрим подготовку каждого этапа справа налево.

Установка Linux на VHD

Для начала необходимо создать пустой образ VHD с фиксированным размером. Если нужно минимизировать размер образа, то для экспериментов с CLI достаточно создать диск объемом

1,5 Гб. Для рабочей системы с GUI можно ограничиться объемом 10 Гб (с условием хранения пользовательских данных вне VHD).

Создадим VHD с помощью diskpart.exe:

Далее необходимо установить Debian на VHD. Я для этого воспользовался VirtualBox 6.1, устанавливал debian-10.8.0-amd64-netinst.iso. Параметры виртуальной машины — по умолчанию, новый диск создавать не надо, достаточно подключить ранее созданный debian.vhd.


Установка Debian стандартна, обращу внимание только на некоторые моменты.

При разметке диска я создал один загрузочный раздел ext4. Раздел подкачки на VHD я делать не стал, после установки можно разместить файл или раздел подкачки в удобном месте.


При выборе дополнительного ПО для установки я оставил только SSH-сервер и стандартные системные утилиты. Всё остальное можно поставить потом, по необходимости. GRUB установлен в MBR. Если при установке была выбрана русская локаль, то после установки можно добавить локаль en_US командой dpkg-reconfigure locales .

Подготовка Linux к загрузке с VHD

В установленную систему необходимо добавить поддержку NTFS и утилиту partprobe, которая позволяет сообщить ядру ОС о необходимости повторного чтения таблицы разделов жёсткого диска.

Затем надо подготовить скрипты для initramfs.

initramfs — это начальная файловая система в оперативной памяти, которая содержит утилиты и скрипты, требуемые для монтирования файловых систем перед вызовом init, располагающегося в корневой файловой системе.

Скрипты для initramfs созданы на основе документации. Наши дополнения для initramfs мы будем размещать в следующих каталогах.

/etc/initramfs-tools/hooks/ — здесь размещаются скрипты, которые запускаются при генерации initramfs-образа. Тут мы разместим скрипт для добавления в initramfs утилиты partprobe с необходимыми библиотеками.

/etc/initramfs-tools/scripts/local-top/ — после выполнения этих скриптов загрузчик считает, что root-устройство смонтировано. Т.е. здесь будет скрипт для монтирования VHD.

Скрипт для добавления partprobe в initramfs возьмем из этой статьи с добавлением еще одной библиотеки. Надо создать файл partcopy и сделать его исполняемым:

Скрипт для монтирования VHD сделан на основе скрипта для Arch Linux с учетом особенностей выбранного дистрибутива Linux. Скрипт необходимо сохранить под именем loop_boot_vhd и сделать исполняемым:

Немного подробнее поясню логику работы скрипта. Обработка prereqs рекомендована в документации. В переменную cmdline попадает строка инициализации из grub4dos, например, root=/dev/loop0p1 loop_file_path=/debian.vhd loop_dev_path=/dev/sda2 . Далее идет разбор этой строки и из нее определяется номер партиции на loop-устройстве, а в переменные loop_dev_path и loop_file_path сохраняются путь к устройству, на котором хранится VHD-файл, и путь к VHD-файлу на устройстве. Если данные для этих переменных не переданы, то скрипт прекращает работу и система пытается загрузиться в обычном режиме. Если переменные определены, то загружается модуль ядра для подержки loop-устройств с указанием в параметрах максимального количества loop-устройств и максимального количества таблиц разделов на loop-устройстве. Затем командой blkid определяется тип файловой системы диска, на котором хранится VHD-файл. Если VHD лежит на NTFS, то монтирование производится с помощью команды ntfs-3g , иначе — командой mount . Монтирование производится в каталог /host (который при необходимости предварительно создается). После этого VHD подключается в систему командой losetup , а затем partprobe сообщает ядру о новом диске.

После размещения скриптов в нужные каталоги ( /etc/initramfs-tools/scripts/local-top/loop_boot_vhd и /etc/initramfs-tools/hooks/partcopy ) необходимо пересобрать initramfs командой:

Для дальнейшей настройки надо запомнить номер версии ядра: /boot/initrd.img-4.19.0-14-amd64 и /boot/vmlinuz-4.19.0-14-amd64.

На этом образ готов к запуску на реальном железе, можно выключать виртуальную машину и приступать к подготовке загрузчика. Готовый образ debian.vhd надо скопировать в корень диска C:, дальнейшие скрипты написаны исходя из предположения, что VHD находится в корне NTFS-раздела.

Настройка grub4dos

Для начала надо скачать актуальную версию grub4dos. Работа с этой утилитой в различных источниках описана достаточно подробно. Настройка сводится к следующему:

необходимо найти раздел, в корне которого лежит VHD-файл, и сделать его корневым для всех команд в текущем пункте меню (команда find --set-root );

затем загрузить образ жесткого диска (команды map . vhd и map --hook );

далее подключенный образ указать как корневое устройство (команда root );

и указать параметры запуска Linux ( kernel и initrd ).

Получается файл menu.lst с таким содержимым:

Тут надо обратить внимание на один момент: в команде kernel инициализируются переменные, которые передаются в initramfs и используются в ранее созданном скрипте loop_boot_vhd .

В моем примере переменные заполнены исходя из моей конфигурации компьютера: один диск с Windows, разбитый на два раздела (загрузочный "System Reserved" и основной NTFS), а внутри VHD — один раздел ext4.

Настройка загрузчика bootmgr

Обратите внимание: в зависимости от версии Windows и особенностей установки ОС возможны незначительные отличия.

Первое, что надо сделать, — подключить скрытый раздел с bootmgr, в примере ниже я подключаю скрытый раздел "System Reserved" в каталог C:\mnt (каталог должен быть предварительно создан). Команды выполняются в diskpart.exe:

После этого надо распаковать в каталог C:\mnt\ файлы из архива с grub4dos: grldr и grldr.mbr . В этот же каталог надо скопировать файл menu.lst , созданный на предыдущем шаге. После этого раздел можно отключить в diskpart.exe:

Чтобы настроить отображение пункта меню при загрузке Windows, надо сделать следующее:

В ответ будет сообщен GUID нового пункта меню. Полученный GUID используется в следующих командах:

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

На этом всё: можно перезагрузить компьютер, выбрать в меню загрузки grub4dos, затем Debian, после чего должен загрузиться Linux.

Что делать, если не грузится?

В этом случае, скорее всего, неверно указаны параметры с путями к устройству, на котором находится VHD-файл, или раздел на loop-устройстве. Если загрузка останавливается на уровне grub4dos, то в консоли надо последовательно вводить команды, перечисленные в menu.lst , и смотреть на результаты, в зависимости от которых правильно указать параметры для загрузки Linux. Если загрузка останавливается в initramfs, то надо проверить доступность необходимых устройств на этом этапе. Проверить можно, последовательно вводя команды из скрипта loop_boot_vhd (основное: смонтировать нужные разделы, найти VHD, подключить его, проверить присвоенный номер партиции с Linux, в моем примере — loop0p1).

А как же UEFI?

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

Виртуальный жесткий диск в Linux

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

В этой статье мы продемонстрируем, как создать том виртуального жесткого диска, используя файл в Linux. В этом руководстве мы создадим том VHD размером 1 ГБ и отформатируем его в файловой системе EXT4.

Создайте новый образ для хранения тома виртуального диска

  • if=/dev/zero: входной файл для предоставления символьного потока для инициализации хранилища данных
  • of=VHD.img: файл образа, который будет создан как том хранения
  • bs=1M: чтение и запись до 1M одновременно
  • count=1200: копировать только 1200 МБ (1 ГБ) входных блоков


Далее нам нужно файл образа VHD отформатировать в тип файловой системы EXT4 с помощью утилиты mkfs. Когда будет предложено, что /media/VHD.img не является специальным блочным устройством, ответьте y, как показано на скриншоте.

Форматирование образа VHD

Чтобы получить доступ к тому VHD, нам нужно подключиться к каталогу (точке монтирования). Для создания точки монтирования и чтобы смонтировать том VHD, выполните следующие команды. Для задания параметров для монтажа используйте -o. Опция loop здесь указывает привязку к /dev/ директории.

Примечание. Файловая система VHD будет оставаться подключенной только до следующей перезагрузки. Чтобы подключать ее при загрузке системы, добавьте эту запись в файл /etc/fstab.

Теперь можно проверить вновь созданную файловую систему VHD с точкой монтирования, используя команду df.

Отображение разделов диска вLinux

Удаление тома виртуального диска

Если вам больше не нужен том VHD, выполните следующие команды для размонтирования файловой системы VHD, а затем удалите файл образа:

Вот и все! В этом руководстве мы продемонстрировали, как создать том виртуального жесткого диска, используя файл в Linux. Если у вас есть какие-либо мысли или вопросы, свяжитесь с нами через форму комментариев ниже.

Еще раз, я должен прибегнуть к экспертам здесь в SuperUser, так как другие мои источники (в основном Google ;-)) не оказались очень полезными .

Однако все решения, с которыми я сталкивался, либо используют disk2vhd либо используют команду dd в linux, которая делает полную копию диска (то есть даже пустые блоки) и не выводит файл VHD. Есть ли инструмент / программа под Linux, которая может напрямую создавать VHD-файл? Или возможно преобразовать необработанный образ диска, созданный с помощью dd, в файл VHD, не выделяя место для пустых блоков? Как бы вы поступили?

Как всегда, любой совет или комментарий высоко ценится!

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

1. Загрузите машину с работающей системой Linux

Первым шагом была загрузка машины с диском в образ с использованием живой системы Linux.

2. Создайте образ диска с помощью dd и передайте данные через ssh

Затем я скопировал все содержимое диска в образ файла на моем локальном сервере, используя dd и передав данные через ssh :

Несколько комментариев здесь: этот метод будет читать все содержимое диска, поэтому это может занять очень много времени (мне потребовалось 5 часов для диска 80 Гб). Узким местом является не сеть, а скорость чтения с диска. Перед запуском копии я советую проверить параметры BIOS/ диска / системы, чтобы убедиться, что диск и материнская плата работают с максимально возможной скоростью (это можно проверить с помощью команды hdparm -i и запустив тест с помощью hdparm -Tt /dev/hdX ).

ПРИМЕЧАНИЕ: dd не выводит ход операции, но мы можем заставить его сделать это, отправив сигнал USR1 в PID процесса dd с другого терминала:

3. Восстановить неиспользуемое пространство

На этом этапе исходный компьютер больше не нужен, и мы будем работать исключительно на конечном сервере (также под управлением Linux). VirtualBox будет использоваться для преобразования необработанного образа диска в формат VHD, но перед этим мы можем обнулить неиспользуемые блоки, чтобы VirtualBox не выделял для них место в конечном файле.

Для этого я смонтировал изображения как устройство с обратной связью:

ПРИМЕЧАНИЕ. Смещение, обозначающее начало раздела в образе диска, можно получить, используя parted в файле образа:

ПРИМЕЧАНИЕ 2. Драйвер NTFS для ядра Linux по умолчанию обеспечивает доступ только для чтения, поэтому необходимо установить и использовать драйвер ntfs-3g userspace, иначе запись на диск вызовет ошибку!

4. Создайте образ VHD с помощью VBoxManage

На этом этапе мы можем использовать утилиты VirtualBox для преобразования необработанного изображения в файл VHD:

Я пытался сделать то же самое, что и OP (спасая установку Windows), и закончил тем, что создал для него новый инструмент, ntfsclone2vhd .

Вы бы тогда просто сделали что-то вроде этого:

Одним из подходов является использование нескольких удобных технологий: VirtualBox и пакета ntfsprogs .

Последние версии VirtualBox позволяют создавать файлы жесткого диска VHD, в то время как ntfsprogs предоставляет утилиту ntfsclone . Как следует из его названия, ntfsclone клонирует файловые системы NTFS, и я считаю, что он делает это на уровне файловой системы, пропуская неиспользуемые блоки диска.

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

Затем найдите Linux live CD, который содержит пакет ntfsprogs , а также openssh-server . Мне нравится System Rescue CD для этого, но почти все живые CD на основе Debian или Ubuntu также должны работать.

Загрузите виртуальную машину VirtualBox с живого компакт-диска Linux и запустите sshd внутри виртуальной машины, чтобы вы могли выполнять команды на ней удаленно. Разделите пустой VHD-диск по назначению, используя любой инструмент для создания разделов, который вы предпочитаете (мне нравится обычный старый fdisk , но я немного староват).

Загрузите компьютер, содержащий физический диск, который вы хотите клонировать, с другой копией Live CD. Я предполагаю, что виртуальная машина VirtualBox и эта машина доступны друг другу по сети. На этом компьютере выполните следующую команду (все в одной строке):

Объяснение: Первая команда ntfsclone в конвейере извлекает образ исходной файловой системы NTFS и отправляет его через туннель ssh, а вторая команда ntfsclone получает образ и восстанавливает его на диске VHD.

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

Последнее, что вы можете сделать, это запустить Windows chkdsk на диске VHD, просто чтобы убедиться, что клонирование не принесло никаких проблем (этого не должно быть, но, эй, я немного параноидален в этих вещах),

В этом разделе предполагается, что вы уже установили на виртуальный жесткий диск (VHD) операционную систему Debian Linux из ISO-файла, полученного с веб-сайта Debian. Существует несколько средств для создания VHD-файлов. Hyper-V — это лишь один из примеров. Инструкции по работе с Hyper-V см. в разделе Установка роли Hyper-V и настройка виртуальной машины.

Замечания по установке

  • См. дополнительные сведения о подготовке Linux для Azure.
  • Более новый формат VHDX не поддерживается в Azure. Можно преобразовать диск в формат VHD с помощью диспетчера Hyper-V или командлета convert-vhd .
  • При установке Linux рекомендуется использовать стандартные разделы, а не LVM — значение по умолчанию во многих дистрибутивах. Это позволит избежать конфликта имен LVM при клонировании виртуальных машин, особенно если диск с OC может быть подключен к другой ВМ в целях устранения неполадок. Для дисков данных можно использовать LVM или RAID.
  • Не настраивайте раздел подкачки на диске с ОС. Можно настроить агент Linux для Azure для создания файла подкачки на временном диске ресурсов. Дополнительные сведения можно найти в инструкциях ниже.
  • Размер виртуальной памяти всех VHD в Azure должен быть округлен до 1 МБ. При конвертации неподготовленного диска в формат VHD убедитесь, что размер этого диска в несколько раз превышает 1 МБ. См. дополнительные сведения об установке Linux.

Создание виртуальных жестких дисков Debian с помощью Azure-Manage

Создавать виртуальные жесткие диски Debian для Azure можно с помощью скриптов azure-manage от Credativ. Рекомендуется использовать их, а не создавать образ с нуля. Например, чтобы создать виртуальный жесткий диск Debian 8, выполните следующие команды для скачивания средства azure-manage (и зависимостей) и выполнения скрипта azure_build_image :

Подготовка образа Debian для Azure

Вы можете создать базовый облачный образ Debian для Azure с помощью конструктора облачных образов FAI.

(Следующие команды git clone и apt install извлечены из репозитория облачных образов Debian.) Начните с клонирования репозитория и установки зависимостей:

При необходимости настройте сборку, добавив скрипты (например, скрипты оболочки) в ./config_space/scripts/AZURE .

Пример скрипта для настройки образа:

Обратите внимание, что важно добавлять ко всем командам, с помощью которых требуется настроить образ, префикс $ROOTCMD , поскольку используется псевдоним chroot $target .

В результате в текущий каталог будут записаны несколько файлов, в частности файл образа image_buster_azure_amd64.raw .

Чтобы преобразовать образ в формате RAW в формат VHD для Azure, выполните следующие действия:

Будет создан виртуальный жесткий диск (VHD) image_buster_azure_amd64.vhd с округленным размером, чтобы этот диск можно было успешно скопировать на диск Azure.

Теперь нужно создать ресурсы Azure для этого образа (используется переменная $rounded_size_adjusted , поэтому это действие нужно выполнять в том же процессе оболочки, что и выше).

Если из-за низкой пропускной способности обработка отправки с локального компьютера на диск Azure с помощью azcopy занимает слишком много времени, для ускорения процесса можно использовать jumpbox виртуальной машины Azure. Это можно реализовать следующим образом:

  1. Создайте tarball виртуального жесткого диска на локальном компьютере: tar -czvf ./image_buster_azure_amd64.vhd.tar.gz ./image_buster_azure_amd64.vhd .
  2. Создайте виртуальную машину Linux в Azure (дистрибутив по вашему усмотрению). При создании обязательно укажите достаточно большой размер диска для хранения извлеченного виртуального жесткого диска.
  3. Скачайте служебную программу azcopy на виртуальную машину Linux в Azure. Ее можно получить здесь.
  4. Скопируйте tarball на виртуальную машину: scp ./image_buster_azure_amd64.vhd.tar.gz <vm>:

Дальнейшие действия: Теперь вы можете использовать виртуальный жесткий диск Debian Linux для создания новых виртуальных машин в Azure. Если вы отправляете VHD-файл в Azure впервые, см. раздел Вариант 1. Передача VHD.

Читайте также: