Виртуальный диск - это обычный файл на хосте, который гость видит как блочное устройство. От того, в каком формате этот файл лежит и как устроен, зависит скорость работы гостя, занимаемое место, возможность делать снапшоты и переносимость на другой гипервизор. В этом уроке разбираем форматы raw, qcow2, vmdk, vdi, инструмент qemu-img во всех режимах, тонкие (sparse) образы, цепочки backing-файлов и сжатие. Цель - чтобы вы осознанно выбирали формат под задачу, а не брали qcow2 по привычке.

Как это работает
raw - это байт в байт сырой образ диска без метаданных. Гипервизор обращается к смещению в файле напрямую, оверхеда нет, поэтому raw самый быстрый и предсказуемый по latency. Хитрость в том, что на современных файловых системах (ext4, XFS, Btrfs) raw тоже бывает тонким: если файл создан как sparse, незаписанные блоки не занимают места на хосте, а ядро возвращает гостю нули. То есть raw умеет экономить место за счет файловой системы, но НЕ умеет снапшоты и backing-файлы сам по себе.
qcow2 (QEMU Copy-On-Write v2) - это умный контейнер. Внутри двухуровневая таблица трансляции (L1/L2): гостевой адрес переводится в смещение внутри файла, а блоки (кластеры, по умолчанию 64 KiB) аллоцируются только при первой записи. Отсюда родное thin-provisioning без помощи ФС, внутренние снапшоты, backing-файлы, сжатие zlib/zstd и опциональное шифрование LUKS. Плата - небольшой оверхед на работу с таблицей и фрагментация при росте.
vmdk - формат VMware, vdi - формат VirtualBox. QEMU их читает и пишет, но это нужно в первую очередь для миграции образов между гипервизорами, а не как рабочий формат под KVM.
Ключевые понятия. Sparse-файл - файл с дырами (holes): логический размер большой, физически на диске занято только записанное. Thin provisioning (тонкий образ) - диск показывает гостю, скажем, 100 GiB, но растет по мере записи. Backing file (цепочка) - overlay-образ, который хранит только отличия от родителя; чтение неизмененного блока уходит в backing, запись остается в overlay. Так делают golden image плюс тонкие копии на каждую ВМ.
Команды и примеры
Установка инструмента. В Debian 13 / Ubuntu 24.04:
Код: Выделить всё
apt install qemu-utilsКод: Выделить всё
dnf install qemu-imgКод: Выделить всё
qemu-img create -f qcow2 disk.qcow2 50GКод: Выделить всё
qemu-img create -f raw -o preallocation=off disk.raw 50G
ls -lh disk.raw # логический размер 50G
du -h disk.raw # реально занято ~0Код: Выделить всё
qemu-img create -f qcow2 -o preallocation=metadata,cluster_size=64k fat.qcow2 50GКод: Выделить всё
qemu-img info disk.qcow2
qemu-img info --backing-chain overlay.qcow2Код: Выделить всё
qemu-img convert -p -O qcow2 -c -o compression_type=zstd src.vmdk dst.qcow2Изменение размера. Увеличение - безопасно, уменьшение - только с -shrink и риском:
Код: Выделить всё
qemu-img resize disk.qcow2 +20G
qemu-img resize --shrink disk.qcow2 30GBacking-файлы. Делаем golden image только для чтения и тонкий overlay поверх:
Код: Выделить всё
qemu-img create -f qcow2 -b base.qcow2 -F qcow2 vm1.qcow2Код: Выделить всё
qemu-img commit vm1.qcow2Код: Выделить всё
qemu-img snapshot -c before-update disk.qcow2 # создать
qemu-img snapshot -l disk.qcow2 # список
qemu-img snapshot -a before-update disk.qcow2 # откатиться
qemu-img snapshot -d before-update disk.qcow2 # удалитьКод: Выделить всё
qemu-img check -r all disk.qcow2Код: Выделить всё
virt-sparsify --in-place disk.qcow2- qcow2-образ с backing-файлом нельзя двигать или переименовывать родителя - путь к backing хранится в overlay. Перенесли base.qcow2 - overlay сломался. Чините через qemu-img rebase.
- du и ls показывают разное: ls -lh это логический размер, du -h реально занятое. Не пугайтесь sparse-файла на 50G, который весит 200K.
- qemu-img resize меняет только контейнер. Без growpart и resize2fs/xfs_growfs внутри гостя новое место невидимо.
- Нельзя редактировать образ работающей ВМ через qemu-img - получите повреждение. Гость должен быть выключен или используйте QMP/blockdev-снапшоты live.
- Тонкий образ может неожиданно вырасти и упереть хост в no space left. Thin без мониторинга места - бомба замедленного действия в проде.
- Сжатие qcow2 (-c) применяется к уже записанным кластерам при convert, но новые записи в работающем образе НЕ сжимаются. compression это для архивов и шаблонов, не для рабочего диска.
- Забытый -F при backing-файле в новых QEMU вызовет ошибку или предупреждение - формат родителя теперь указывают явно.
- Создайте тонкий raw на 10G и qcow2 на 10G. Сравните du и ls для обоих, объясните разницу.
- Запишите в qcow2 пару гигабайт (например, dd внутри смонтированного образа или через гостя) и посмотрите, как растет disk size в qemu-img info.
- Сделайте base.qcow2, создайте поверх overlay через -b и -F, запишите данные только в overlay. Проверьте qemu-img info --backing-chain.
- Сделайте внутренний снапшот, измените данные, откатитесь на снапшот, убедитесь, что изменения исчезли.
- Сконвертируйте qcow2 в raw и обратно, на обратном пути включите zstd-сжатие. Сравните размеры файлов.
- Увеличьте образ на +5G через resize и проследите, что внутри гостя ФС этого пока не видит.
- Чем отличается thin-provisioning в raw (через sparse-файл) от thin в qcow2 (через L1/L2-таблицу)? Где экономия места не зависит от хостовой ФС?
- Почему qemu-img convert разрывает цепочку backing-файлов, а qemu-img commit и rebase - нет?
- Какие возможности qcow2 принципиально недоступны формату raw и почему это важно для снапшотов?
- Что произойдет, если переместить backing-файл в другой каталог, не тронув overlay? Как восстановить связь?
- Когда оправдан raw, а когда qcow2 в продакшене? Приведите по одному сценарию для каждого.
- Чем preallocation=metadata отличается от preallocation=full для qcow2 и как это влияет на первую запись?