Освободить неиспользуемое пространство в файле-образе qcow2 в kvm/qemu
Мы используем kvm/qemu с qcow2-образами для наших виртуальных машин.
У qcow2 есть эта приятная особенность, когда файл образа выделяет только фактически необходимое пространство для виртуальной машины. но как мне сжать файл образа, если выделенное пространство виртуальной машины становится меньше?
пример:
1.) Я создаю новое изображение в формате qcow2, размером 100 ГБ.
2.) Я использую этот образ для установки Ubuntu. для установки требуется около 10 ГБ, файл образа увеличивается до 10 ГБ. пока ничего неожиданного.
3.) Я заполняю изображение примерно 40 ГБ дополнительных данных. файл изображения увеличивается до 50 ГБ. я в порядке с этим:-)
4.) это то, где это становится странным: я удаляю все данные 40 ГБ на изображении, но размер изображения все еще съедает 50 ГБ.
Вопрос: как освободить эти 40 ГБ данных и уменьшить изображение до необходимых 10 ГБ?
спасибо заранее, Берни
3 ответа
Изображение не будет автоматически уменьшаться, так как при удалении файлов вы фактически не удаляете данные (вот почему работает undelete). В Qemu есть возможность сжимать изображения qcow2 обратно, но утилита действительно дедуплицирует нули с диска, оставляя всю остальную информацию нетронутой. Таким образом, идея заключается в следующем:
- Ноль заполнить диск (
dd if=/dev/zero of=/some/file
пока не кончится космос) - удалить / некоторые / файл
- выключить виртуальную машину
- перейдите туда, где хранятся и запускаются образы для виртуальной машины
qemu-img convert -O qcow2 original_image.qcow2 deduplicated_image.qcow2
- измените настройки виртуальной машины, чтобы использовать новый deduplicated_image.qcow2, проверьте работоспособность виртуальной машины и удалите старый образ
Это, afaik, будет работать только с изображениями qcow2, я не тестировал другие форматы.
Virt-sparsify может сделать все это с меньшими хлопотами с вашей стороны: http://libguestfs.org/virt-sparsify.1.html
Для этого вы можете использовать virt-sparsify. Он автоматически обнуляет и разрежает свободное пространство в большинстве файловых систем, которые он находит в образе исходного диска (поддерживает ext2/3/4, btrfs, NTFS и т. Д.) .
Пошаговые инструкции по конвертации на месте
Выключите виртуальную машину
Сохраните резервную копию
Конвертировать:
virt-sparsify --in-place disk.img
Пошаговые инструкции по преобразованию в другой файл (это безопаснее, но требует больше свободного места):
Выключите виртуальную машину
Конвертировать:
virt-sparsify disk.img new-file.img
Заменить старый файл новым изображением:
mv disk.img disk.img.bak && mv new-file.img disk.img
Если виртуальная машина запускается нормально, вы можете удалить резервную копию:
rm disk.img.bak
PS: Вы также можете конвертировать между форматами, используя virt-sparsify:
virt-sparsify disk.raw --convert qcow2 disk.qcow2
В дополнение к принятому ответу (который описывает более распространенный, общий метод сжатия файла qcow2) современная версия (например, RHEL7+) стека libvirt/qemu/qcow2 поддерживает
virtio-scsi
драйвер, который поддерживает
discard='unmap'
вариант.
Если виртуальная машина использует
virtio-scsi
а определение libvirt включает
discard='unmap'
, просто
fstrim
в гостевой файловой системе освободит назначенное, но неиспользуемое свободное пространство на хосте. Это можно проверить с помощью
du -hs <guestdisk>
на стороне хозяина (примечание:
ls -al <guestdisk>
не будет показывать реальный выделенный размер, только логический).
Для даже более новых экземпляров libvirt / qemu (например, RHEL8+) размер гостевого файла можно уменьшить, даже если гостевая ОС не поддерживает обрезку: включив оба
discard='unmap'
и
discard_zeroes='unmap'
(и используя
virtio-scsi
драйвер), записывая последовательный нулевой поток на гостевой стороне (то есть через
dd if=/dev/zero of=/zero.img bs=1M count=1024
) вызовет обрезку затронутых диапазонов LBA по размеру хоста. Однако обратите внимание, что это может потребовать значительных ресурсов процессора для хоста (который должен был "анализировать" любую гостевую запись в поисках повторяющихся нулей), поэтому его следует включать только в определенных случаях.
Оба метода уменьшат физический выделенный размер (что
du -hs
показывает). Для уменьшения логического размера (какой простой
ls -al
дает) вам нужно использовать
virt-spasify
или же
qemu-img
(как описано в других ответах).
В дополнение к другим ответам о
virt-sparsify
:
Временная папка
virt-sparsify использует вашу папку /tmp для создания / управления новым образом диска, прежде чем помещать его в папку назначения. Итак, на вашем разделе / должно быть свободное место, даже если файл тома находится в другом разделе.
Если у вас нет свободного места, вы можете установить новую временную папку с помощью
--tmp my_tmp_folder
вариант. Пример:
mkdir my_tmp_folder
virt-sparsify \
--tmp my_tmp_folder \
ubuntu.qcow2 new_ubuntu.qcow2
- Это не сработает с
--in-place
; - Вы можете удалить папку tmp после завершения процесса.
Подробный
Есть подробный вариант, который поможет вам понять, что происходит. Пример:
virt-sparsify \
-v \
ubuntu.qcow2 new_ubuntu.qcow2
Проверить перед удалением
Как было сказано ранее, всегда загружайте виртуальную машину и проверяйте, все ли работает, прежде чем удалять исходный образ диска.
virt-sparsify fileA fileB
сделает все это, но на самом деле не уменьшит размер изображения. Для этого нужно добавить --compress
,
Измените размер раздела в виртуальной машине до целевого размера, например, измените размер до 50 ГБ для данных 45 ГБ. После этого с базовой машины:
qemu-img convert -f qcow2 -O raw source.qcow2 | dd of=target.raw bs=4M count=12800 status=progress
вероятно будет работать. Возможно, вам потребуется добавить iflag=sync или что-то еще, хотя...
тщательно протестируйте его перед использованием на всем...