Neste artigo, vou falar sobre a situação em que você precisa reduzir a imagem qcow2 da máquina virtual KVM o mais rápido possível.
Formato de dispositivo de bloco - qcow2
Mas, no entanto, este esquema pode ser feito com imagens raw, basta convertê-lo para qcow2. Em geral, a instrução será relevante para tudo o que é convertido para qcow2.
Uma maneira fácil de reduzir o disco no KVM é a seguinte:
- Compactando um dispositivo de bloco qcow2 (disco VM)
- Fazendo um disco menor
- Montagem de imagem gparted, disco antigo e novo
- Preparando para inicializar o sistema operacional
- Especificações de VM e máquina host:
Host: CentOS 7 + QEMU 2.12 + LIBVIRT 4.5.0 + Kernel UEK5 v. 4.14
VM: CentOS 7 + 80GB HDD + Kernel std v. 3.10
O doador será uma máquina virtual CentOS 7 com uma imagem de disco rígido de 80 GB, ocupada na verdade por 20 GB e fisicamente por 80 GB. Vamos reduzir para 40 GB.
Qual é a diferença entre o tamanho da imagem, tamanho real e físico?
Digamos que a imagem qcow2 foi criada com um tamanho de 80 GB e sabemos sobre isso. Durante a operação, a imagem ficou obstruída com dados, alguns dados foram excluídos. Em termos gerais, devido às peculiaridades do processo de gravação e exclusão de dados, para o SO, os dados excluídos parecem não existir, mas permanecem gravados na imagem até que sejam substituídos por outros dados. Assim, mesmo no sistema operacional, você verá 20 GB de dados realmente ocupados, o host KVM mostrará uma imagem maravilhosa (usamos o utilitário qemu-img para obter informações):
qemu-img info qcow2_image.img
image: qcow2_image.img
file format: qcow2
virtual size: 80G (85899345920 bytes)
disk size: 80G
cluster_size: 65536
Format specific information:
compat: 0.10
refcount bits: 16
Você pode ver que tamanho virtual = tamanho do disco, bem como du -sh da imagem irá mostrar que ocupa 80G reais:
du -sh qcow2_image.img
80G qcow2_image.img
E como precisamos reduzir o tamanho da imagem para 40 GB, vamos iniciar o processo.
Estágio 1 - Comprimir o dispositivo de bloco (imagem)
Antes de iniciar o procedimento de redução do disco, você precisa se certificar de que o espaço ocupado dentro do sistema operacional é menor do que o volume para o qual o disco será reduzido de uma forma ou de outra.
df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/vda2 80G 18G 63G 22% /
Como podemos ver, 18 GB estão ocupados, o que é menos de 40 GB. Desligue a VM com o comando
shutdown -h now
E vá para a máquina host, verifique:
- quanto a imagem pega fisicamente
- quanto na verdade
# qemu-img info qcow_shrink
image: qcow_shrink
file format: qcow2
virtual size: 80G (85899345920 bytes)
disk size: 80G
cluster_size: 65536
Format specific information:
compat: 0.10
refcount bits: 16
# virt-df -h qcow_shrink
du -sh Filesystem Size Used Available Use%
qcow_shrink:/dev/sda1 488M 101M 351M 21%
qcow_shrink:/dev/sda2 79G 17G 62G 22%
# du -sh qcow_shrink
80G qcow_shrink
Para compactar a imagem, precisamos de um utilitário simples chamado virt-sparsify . Certifique-se de que a VM esteja inativa e execute o comando no diretório junto com a imagem do disco (observação importante: antes de iniciar o virt-sparsify , certifique-se de que haja espaço livre suficiente em / tmp e no armazenamento de imagem para realizar a operação)
virt-sparsify qcow_shrink qcow_shrink-new
A conclusão bem-sucedida da operação resultará na seguinte saída:
[ 0.0] Create overlay file in /tmp to protect source disk
[ 0.1] Examine source disk
[ 1.2] Fill free space in /dev/sda1 with zero
[ 1.5] Fill free space in /dev/sda2 with zero
100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00
[ 72.5] Copy to destination and make sparse
[ 81.9] Sparsify operation completed with no errors.
virt-sparsify: Before deleting the old disk, carefully check that the
target disk boots and works correctly.
Em seguida, trocamos o disco (movemos qcow_shrink para algum lugar ao lado, por exemplo qcow_shrink-old e qcow_shrink-new em seu lugar - qcow_shrink ).
mv qcow_shrink qcow_shrink-old && mv qcow_shrink-new qcow_shrink
Começamos a VM. Se tudo começou, apagamos a VM e continuamos trabalhando.
Etapa 2 - Criar um disco menor
Um procedimento simples com apenas um comando:
qemu-img create -f qcow2 -o preallocation=metadata qcow_shrinked 40G
qcow_shrinked - novo nome de imagem
40G - novo tamanho
Estágio 3 - conectando gparted
Como às vezes os administradores preferem maneiras mais fáceis de resolver o problema, o pandeiro é colocado de lado (kpartx) e ISO e VNC vêm em seu lugar. Felizmente, não é muito difícil conectá-lo ao KVM.
O que estamos fazendo:
- Conecte a imagem ISO GParted
- Conecte qcow2_shrinked à VM
- Inicie a VM, inicialize do ISO
Como fazer isso, irei omitir deste artigo, pois presume-se que quem está fazendo tudo isso já sabe como acontece, mas o resultado será o seguinte:

Inicie a VM e veja a tela de boot do GParted:

Selecione o primeiro item e siga as instruções na tela. Eu geralmente pressiono Enter até o fim.

Vendo o próprio GParted, vamos começar a agir. Verificamos rapidamente se / dev / vda tem uma tabela de partição - msdos ou gpt . Isso é importante:

Mude para o segundo disco / dev / vdb e crie a tabela de partição:


Ao criar a tabela, selecione o tipo msdos como aprendemos anteriormente.
Em seguida, volte para / dev / vdae sequencialmente, a partir dos primeiros discos, começamos a copiar partições, alternando entre vda e vdb :

O resultado final será:

Pressione Aplicar e espere o resultado terminar:

Como resultado:

Isso já parece verdade. Mas como fizemos alguma manipulação que levará a uma alteração no UUID dos discos, potencialmente não inicializaremos no sistema operacional. Por quê? O CentOS 7 usa UUIDs de disco no fstab, Grub2 usa UUIDs de disco, então entre no console e faça magia negra.
Gparted funciona inicialmente como um usuário, então nós saltamos para root com o comando sudo su - root :

Vamos blkid para ter certeza que o UUID das partições mudou

Pode-se ver que o UUID vda1 = vdb1, mas para vdb2 mudou. Tudo bem - você pode viver com isso.
Monte o vdb completamente, junto com a partição / boot, e monte algumas partições para nossa conveniência.
mkdir vdb2
mount /dev/vdb2 vdb2
mount /dev/vdb1 vdb2/boot
cd vdb2
mount --bind /dev dev
mount --bind /sys sys
mount --bind /proc proc
chroot .
Vamos começar com fstab - uma vez que não é muito conveniente digitar o UUID no VNC, vamos substituí-lo pelo nome de dispositivo familiar.

Substituímos a linha por UUID = ... por, atenção :
especificamos / dev / vdb2 , se o disco antigo não foi planejado para ser desconectado,
especificamos / dev / vda2 , se o disco antigo foi desconectado.
Visto que desconectamos o disco antigo antes de carregar o SO, então escrevemos / dev / vda2
Próximo vamos mudar o bootloader, colocá-lo em ordem. Suponha que tudo esteja em / boot / grub2, grub.cfg está no mesmo lugar, mas efi não (tabela msdos, que é efi :)):
grub2-install /dev/vdb
cd /boot/grub2
grub2-mkconfig -o grub.cfg
Com isso, você pode ficar feliz por si mesmo e ao desabilitar o gparted, inicialize no sistema operacional.
Etapa 4 - inicializar o sistema operacional
Antes de carregar o sistema operacional, ainda recomendo desconectar o disco antigo do servidor. Portanto, no estágio anterior, vda2 tinha que ser registrado no fstab, mas se você for um usuário de PC atento e não desconectou nada, então não deverá haver problemas. Com um disco antigo, é muito provável que você inicialize a partir dele.
Não houve problemas durante o processo de inicialização, o servidor inicializou conforme o esperado. Vamos verificar isso:
[root@shrink ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 484M 0 484M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 6.7M 489M 2% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/vdb2 40G 18G 23G 44% /
/dev/vdb1 488M 101M 352M 23% /boot
tmpfs 100M 0 100M 0% /run/user/0
[root@shrink ~]# blkid
/dev/vda1: UUID="ea505196-32fb-4df6-8bed-0a0ab2d0b726" TYPE="ext4"
/dev/vda2: UUID="30ec1bc6-658f-4611-8708-5e3b7ebaa467" TYPE="xfs"
/dev/vdb1: UUID="ea505196-32fb-4df6-8bed-0a0ab2d0b726" TYPE="ext4"
/dev/vdb2: UUID="c8548834-272b-4331-a9bf-aa99fb41a434" TYPE="xfs"
/dev/sr0: UUID="2019-03-21-13-42-32-00" LABEL="GParted-live" TYPE="iso9660" PTTYPE="dos"
Vemos que / boot e / são necessários, 40 GB de tamanho, o sistema operacional está em execução. Felicidade, de outra forma não!
Bônus
Algo que você terá que enfrentar em algumas situações.
- VM Windows, virt-sparsify . , , ( blkid), Windows , . ( ) fixmbr + rebuildbcd. — man
- — xfs Superblock has unknown read-only compatible features (0x4) enabled. read-only, . :
Provavelmente, quando tudo foi feito no gparted ou outro ambiente, a versão do kernel deste ambiente era muito nova, no qual o xfs foi ligeiramente alterado, ou seja, os metadados e sua versão são diferentes. Como resultado, o xfs feito no novo kernel se transforma em uma abóbora no antigo. O que fazemos é inicializar novamente no resgate gparted, aumentar a rede neste ambiente de resgate e instalar o kernel mais recente no sistema operacional. Instalei o 5.x no CentOS 7, talvez o 4.x sirva, ainda não testei, mas no final deu certo. Além disso, sem problemas.
Isso é tudo!
Como você pode ver, não há nada de complicado nisso. Claro, você pode usar LVM, resize2fs e outras coisas, mas ainda assim qcow2 é usado em outro lugar e até mesmo necessário por alguém.
Se você conhece um método ainda mais simples, escreva sobre ele nos comentários.