web-dev-qa-db-fra.com

libérer de l'espace non utilisé sur un fichier image qcow2 sur kvm / qemu

nous utilisons kvm/qemu avec qcow2-images pour nos machines virtuelles.

qcow2 a cette fonctionnalité intéressante où le fichier image alloue uniquement l'espace réellement nécessaire par la machine virtuelle. mais comment puis-je réduire le fichier image, si l'espace alloué à la machine virtuelle devient plus petit?

exemple:

1.) je crée une nouvelle image au format qcow2, taille 100 Go

2.) J'utilise cette image pour installer Ubuntu. l'installation nécessite environ 10 Go, le fichier image augmente jusqu'à environ 10 Go. rien d'inattendu jusqu'à présent.

3.) je remplis l'image avec environ 40 Go de données supplémentaires. le fichier image atteint 50 Go. je suis d'accord avec ça :-)

4.) c'est là que ça devient étrange: je supprime toutes les données de 40 Go sur l'image, mais la taille de l'image mange toujours 50 Go.

question: comment puis-je libérer ces 40 Go de données et réduire l'image aux 10 Go nécessaires?

merci d'avance, berni

24
bmaeser

L'image ne rétrécit pas automatiquement, car lorsque vous supprimez des fichiers, vous ne supprimez pas réellement les données (c'est pourquoi la restauration fonctionne). Qemu a la possibilité de réduire les images qcow2, mais ce que l'utilitaire fait est vraiment de dédupliquer les zéros du disque, en laissant toutes les autres informations intactes. L'idée serait donc de:

  1. Remplissez le lecteur à zéro (dd if=/dev/zero of=/some/file jusqu'à ce que vous manquiez d'espace)
  2. supprimer/certains/fichiers
  3. arrêtez la machine virtuelle
  4. cd où les images pour le VM sont conservées et exécutées qemu-img convert -O qcow2 original_image.qcow2 deduplicated_image.qcow2
  5. modifiez les paramètres VM pour utiliser le nouveau deduplicated_image.qcow2, testez le VM fonctionne et supprimez l'ancienne image)

Cela, afaik, ne fonctionnera qu'avec des images qcow2, je n'ai pas testé d'autres formats.

27
dyasny

virt-sparsify peut faire tout cela avec moins de tracas de votre part: http://libguestfs.org/virt-sparsify.1.html

18
Eric Blake

virt-sparsify --compress fileA fileB réduira la taille de l'image, mais il crée l'image qcow2 comme un autre fichier, vous devrez donc renommer et déplacer les choses. Vous ne pouvez pas utiliser --compress et --in-place à la fois. Voir le lien suivant pour en savoir plus. http://libguestfs.org/virt-sparsify.1.html

1
cmyster

En plus de la réponse acceptée (qui décrit la méthode générale la plus courante pour réduire un fichier qcow2), la version moderne (ie: RHEL7 +) de la pile libvirt/qemu/qcow2 prend en charge la virtio-scsi pilote prenant en charge discard='unmap' option.

Si la machine virtuelle utilise virtio-scsi et la définition de libvirt inclut discard='unmap', un simple fstrim sur le système de fichiers invité libérera de l'espace libre attribué mais non utilisé sur l'hôte. Cela peut être vérifié avec du -hs <guestdisk> côté hôte (remarque: ls -al <guestdisk> affichera pas la taille réelle allouée, juste la taille logique).

Pour les instances libvirt/qemu encore plus récentes (ie: RHEL8 +), la taille du fichier invité peut être réduite même si le système d'exploitation invité ne prend pas en charge le trim: en activant les deuxdiscard='unmap' et discard_zeroes='unmap' (et en utilisant le virtio-scsi driver), en écrivant un flux séquentiel de zéro côté invité (ie: via dd if=/dev/zero of=/zero.img bs=1M count=1024) déclenchera le découpage de la taille de l'hôte des plages LBA affectées. Cependant, veuillez noter que cela peut être gourmand en CPU pour l'hôte (qui a dû "analyser" tout écrit d'invité à la recherche de zéros répétés), il ne doit donc être activé que dans des cas spécifiques.

Les deux méthodes réduiront la taille allouée physique (ce que du -hs montre). Pour réduire la taille logique (quel simple ls -al donne) vous devez utiliser virt-spasify ou qemu-img (comme décrit dans les autres réponses).

1
shodanshok