Linux KVM 縮減虛擬磁碟容量

在 Linux KVM 虛擬化環境裡,若是想要擴充客體機的磁碟容量,並不是件很麻煩的事,而且通常可以在客體系統無須下線的情況下實現。然而如果是反過來,想要以非破壞性的方式縮減磁碟容量,把用不到的空間重新釋放出來,那麼在程序上就會比較繁雜一些。

 

本文是以 RHEL/CentOS Stream 8 為主要的示範環境,所使用的主體及客體皆是 Linux 系統。倘若所使用的 Linux 發行版並沒有比 RHEL 8 陳舊,則預期在操作上應不會遇到什麼障礙。此外由於 DR 自己在建立 Linux 客體機時,多數情況下都是採用傳統 BIOS 模式,虛擬磁碟會單純地切成兩個分割區,一是系統根目錄,使用 ext4 檔案系統;二則是 swap 分割區。所以本文的操作概念會同樣以此設想為基礎,不會特別涉及到其它更加複雜的情境。

 

磁碟縮減相較於磁碟擴充,基本上無法期待能夠在客體不暫時關閉的情況下實現。DR 個人比較偏好的流程,首先是在客體中使用例如 SystemRescue 這類的 Linux 可開機映像來執行圖形化的 GParted 磁碟分割工具。雖然事實上,也是可以從主體機利用 qemu-nbd 掛載客體機的虛擬磁碟,再進一步從主體機對虛擬磁碟執行 GParted。不過 DR 還是較傾向在客體機內執行 GParted,認為此舉在操作過程上比較單純。

 

無論是使用何種途徑來執行 GParted,在 GParted 裡的主要任務,就是利用它的分割區大小調整功能,在同時以非破壞性方式調整檔案系統的情況下,從虛擬磁碟的末端縮減出一塊未分割空間,也就是預期將刪減的磁碟空間大小。不過在這個階段裡,一種可以考慮的作法,是讓空出來的未分割空間,粗略地大於預計縮減的磁碟容量。比方說如果磁碟容量預計要縮減 10G,則磁碟末端的未分割空間就先空出 11G。

 

這麼做的好處,是操作上無須太精算,就能夠避免後續實際在縮減磁碟容量時,不慎切除到檔案系統的涵蓋範圍。然後在完成磁碟容量調整後,再將分割區及檔案系統重新延展至剩餘的可用空間即可。

 

完成分割區的處理後,接下來的步驟是將客體機關閉。然後在主體機的操作環境中,前往客體機磁碟映像的所在目錄,預設應為 /var/lib/libvirt/images/。假設該客體的磁碟映像檔為 disk.qcow2,則以下指令能夠檢視該映像檔的細部資訊:

  • qemu-img info disk.qcow2

 

將其縮減 10GiB 的指令如下:

  • qemu-img resize disk.qcow2 --shrink -10G

 

完成縮減後,可以再次使用 qemu-img info 指令,來查看映像檔經過更新的容量資訊。然而因著各種不一的因素,容量縮減後的 *.qcow2 映像檔,其實際佔用的檔案大小可能沒有什麼變化。倘若欲一併縮減 *.qcow2 檔案的大小,一種保證有效的作法,是使用 qemu-img convert 指令再生產出一個新的映像檔:

  • mv disk.qcow2 disk_bakup.qcow2
  • qemu-img convert -O qcow2 disk_backup.qcow2 disk.qcow2

 

然後便改用新產出的映像檔來啟動客體機,倘若運作無誤,就可以將舊的映像備份刪除。若是在先前步驟裡,有刻意讓未分割空間略大於欲刪減的空間。那麼再次啟動客體機時,則同樣可以利用 SystemRescue 所提供的 GParted 來延展分割區(及檔案系統)大小,取回剩餘未分割的空間。然後在完成調整後,就可以返回到原先的客體 Linux 系統中。

 

除此之外,倘若在分割區的調整過程中,有涉及到 swap 分割區的移除及重建。那麼就需要在進入到客體 Linux 系統後,做一些復原設定的操作。假設 swap 分割區為 /dev/vda2,首先便是將 swap 重新啟用:

  • mkswap /dev/vda2
  • swapon /dev/vda2

 

接著是系統中有幾個認 UUID 的地方,也要做相應的更新。執行 blkid 指令,來取得新 swap 分割區的 UUID。然後分別編輯 /etc/fstab 和 /etc/default/grub,從中找尋到原先系統所設定的 swap UUID,將其更新成正確值。並且在完成前述變更後,最後再執行以下指令:

  • grub2-mkconfig -o /boot/grub2/grub.cfg

 

分類: