Comment libérer de l'espace dans une image dynamic qcow2 VM?

Cela est arrivé à l'une de mes machines virtuelles qui exécute CentOS sous Proxmox.

J'ai copié environ 40 Go de données dans une machine virtuelle. J'ai ensuite supprimé ces données 40 Go un jour plus tard. La sauvegarde d'une même machine virtuelle prend maintenant plus de 30 minutes et dépasse 40 Go lorsqu'il n'y a que 9 Go dans la machine virtuelle.

Des questions

  • Alors, comment puis-je libérer cet espace après la suppression de ce file?
  • Existe-t-il une command que je peux exécuter sur la VM pour libérer cet espace?
  • Une command au niveau de l'hyperviseur pour le libérer?

qcow2 fonctionne de manière unique, mais il est plutôt compréhensible. Une fois que l'OS invité request une écriture sur un bloc précédemment non alloué (non alloué par la machine virtuelle dans le file qcow2), la machine virtuelle alloue de l'espace au système de files hôte et l'utilise pour stocker des informations pour l'invité. Lorsque l'OS invité supprime le file, il n'indique pas à la machine virtuelle qu'elle n'a plus besoin du bloc. Et même si c'est le cas, il faut se callbacker que pour des raisons de performance, les blocs sont alloués en groupes – c'est-à-dire si l'OS invité request 10 blocs 512B en général, un espace beaucoup plus grand est alloué; voir l'option cluster_size dans la page de manuel qemu-img(1) . Cela signifie qu'une fois qu'un bloc adjacent est écrit, il est déjà alloué. Considérons maintenant le cas, lorsque l'invité écrit deux files dans le même «cluster». Les deux devraient être supprimés pour récupérer l'espace dans le file image VM.

Cela dit, il existe un moyen de récupérer l'espace, même si je ne suis pas sûr que cela puisse se produire pendant qu'une VM tourne à partir de l'image. La procédure est la suivante:

Dans la VM

  1. enlève ce que tu ne veux plus
  2. défragmenter le système de files
  3. remplissez l'espace libre avec des zéros, par exemple avec

     dd if=/dev/zero of=/tmp/zeros 
  4. assurez-vous que les zéros sont envoyés sur le disque (virtuel) (i, e, non mis en cache par le operating system invité) – ils doivent apparaître dans l'image de la machine virtuelle

  5. supprimer le file créé
  6. arrêtez le système (peut-être pas nécessaire)

Puis remballez l'image VM sur le système hôte en utilisant qemu-img convert (de qcow2 à qcow2) sur le système hôte. Vous pouvez utiliser l'option -S pour spécifier la taille d'un bloc à zéro, à considérer pour l'optimization à l'aide d'un file fragmenté. -o preallocation=off également attention à l' -o preallocation=off convert pour empêcher la création de files en taille réelle au démarrage.

Cela signifie évidemment qu'à un certain moment, vous aurez besoin d'un espace libre supérieur à (taille maximale de l'image) + (taille réelle de l'image) libre sur l'hôte. D'un autre côté, c'est probablement la seule façon d'assurer une compactification maximale de l'image finale.

Vous pouvez également essayer de mettre à zéro chaque file que vous souhaitez supprimer avant de le supprimer, par exemple avec shred -n 0 -z . Cependant, vous ne pourrez pas récupérer autant d'espace que dans le cas du disque complet.

En outre, sur certains filesystems, cela peut ne pas avoir la sortie souhaitée. Par exemple, avec btrfs, vous êtes quand même condamné car il a sa propre couche de copy sur écriture – à less que vous ne le désactiviez dans l'invité (et je ne suis pas sûr que cela soit possible, car beaucoup de fonctionnalités de ce système de files en dépendent ), vous n'avez pas de chance.

Eh bien, si vous avez une licence pour certains outils de clonage de disque, utilisez-les pour faire un clone de disque à disque sur un PC virtuel est généralement beaucoup plus rapide (s'ils include la sémantique du FS au lieu de la copy verbatim). (J'utilise Symantec Ghost pour mes machines virtuelles invitées Windows mais je ne suis pas sûr s'il supporte les filesystems EXT).