如何「真正」減少KVM虛擬機器鏡像的大小?

如何「真正」減少KVM虛擬機器鏡像的大小?

我花了很多時間在網路上搜尋如何縮小 KVM 虛擬磁碟映像,特別是 Windows 用戶機,但沒有成功。

我所發現的就是將虛擬機器可用空間歸零,對虛擬磁碟進行碎片整理(從 Windows),然後運行qemu-img convert -c ...-c標記為壓縮)。

我有一個 Windows 7 VM,虛擬磁碟機大小為 100 GB。最初,該 VDD 在主機儲存上花費了 40 GB。一旦歸零,VDD 就會在主機上佔用真正的 100 GB 空間。並qemu-img -c ...創建了 91 GB,這根本不是我所期望的。

在modernie網站上,我們可以下載小於10GB的W7虛擬機,這怎麼可能呢?有沒有辦法「真正」壓縮虛擬機器映像?


感謝@dyasny,我用 做了一個小測試virt-sparsity。我清理了 W7 VM 磁碟,以停用休眠,因此 VDD 僅消耗 20 GB。再次降級磁碟,再次運作sdelete -zvirt-sparsity使用此標誌運作--compress會提供 80 GB 的虛擬磁碟機。與我所希望的相差甚遠。


EDIT-2016-02-16:「刷新」這個問題,因為這裡討論的縮小虛擬機器的方法非常有效,但有一個主要缺點:它會刪除所有虛擬機器快照。如果有人知道如何在保留快照的同時縮小虛擬機,請隨時分享!

答案1

要縮小 Windows 來賓作業系統,您必須縮小來賓內部的分割區,關閉虛擬機,建立所需大小的新的較小磁碟,將資料從舊磁碟複製到新的較小磁碟,交換磁碟名稱並重新啟動虛擬機。

這很簡單,但如果操作不當可能會導致數據和頭髮丟失。

以下是針對具有 100 GB 容量的 Windows Server 2012 用戶端的 KVM(我們希望使用 QCOW2 格式將其縮小至 35 GB)的步驟。

重要的: 這個方法涉及到不修改虛擬機定義。相反,它只需要磁碟映像操作

對客人的假設:

  • 來賓是Windows Server 2012
  • QCOW2 格式的 100 GB 磁碟映像
  • 兩個分區:
    • 350 MB 引導空間
    • 99.6 GB C:具有 20 GB 已用空間的驅動器
  • 我們想要將 C: 從 99.6 GB 縮小到 34 GB

對主機的假設:

  • Ubuntu 16 LTS 伺服器
  • KVM(libvirt)
  • 250 GB 驅動器
  • 虛擬映像位於 /var/lib/libvirt/images

步驟1:準備Windows Guest,縮小主C:分割區

在此步驟中,我們將直接從 Windows 減少 Windows 分割區。此步驟結束時產生的磁碟映像將是啟動分割區、C: 磁碟機(減少)和我們將刪除的剩餘未使用空間(透過不將其複製到新磁碟)的總和。

  1. 登入 Windows 來賓
  2. 打開“電腦管理”實用程序,透過開始功能表搜尋功能找到它。
  3. 在左側點擊“存儲->磁碟管理”儲存磁碟管理截圖
  4. 在新畫面上,右鍵單擊 C: 分割區,點選“Shrink Volume...”,這應該需要一點時間才會出現對話框。要有耐心。
  5. 出現「Shrink C:」對話方塊視窗後,在「要縮小的空間量」中輸入使「收縮後的總大小(以 MB 為單位)」值接近所需的 35 GB 的空間量。然後點擊“縮小”。

    筆記:如果新空間太小,您可能會收到錯誤訊息,在這種情況下,您應該將「要收縮的空間量」逐漸減少1GB,直到錯誤消失並發生收縮。實際上,我們喜歡保留 10 GB 的可用空間。

    假設您能夠將 C: 分割區縮小到 34 GB。

  6. 完成後,透過開啟命令提示字元並鍵入以下內容來關閉虛擬機器:shutdown /s /t 0

  7. 您的 Windows 訪客已準備就緒。

步驟 2:VM 主機上磁碟的收縮

這個過程並不是真正的收縮,而是我們將創建一個新磁碟(最終大小),在其中我們將從原始磁碟複製兩個分割區,並跳過保留未使用的空間。

目標是建立一個總大小 = boot 分割區 + C: 分割區的磁碟。我們最終也會得到一些微小的剩餘空間(除非你的數學是完美的),不用擔心,因為我們將在最後一步中處理。

  1. 登入linux主機
  2. 切換到超級用戶:sudo su
  3. 轉到儲存虛擬映像的位置:cd /var/lib/libvirt/images
  4. 列出文件:ls -l
  5. 找到您的訪客圖像(其他地方有大量相關教學)。假設我們的 Windows 來賓映像名為“windows.qcow2”
  6. 我們進行備份:

    mkdir backup
    cp windows.qcow2 backup/windows.qcow2.bak
    

    (去喝咖啡吧,因為對於大磁碟來說這需要一段時間)

  7. 安裝您可能缺少的 guestfs 軟體包:

    apt-get install libguestfs-tools
    
  8. 好吧,讓我們透過瀏覽 Windows 映像來仔細檢查我們的 Windows 磁碟virt-filesystems

    virt-filesystems --long --parts --blkdevs -h -a windows.qcow2
    

    輸出如下:

    Name       Type       MBR  Size  Parent 
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   34G   /dev/sda
    /dev/sda   device     -    100G  -
    

    請注意,/dev/sda1我們的 Windows 啟動分割區為 350 MB,/dev/sda2C: 分割區現在為 34 GB,總磁碟映像/dev/sda/為 100 G,留給我們大量空間需要修剪。

    所以這裡是重要的一步:計算一下:34 G + 350M 相當於 35 G,因此我們將建立一個 35 GB 的映像。我們不可避免地會留下一些剩餘空間——除非你的數學是完美的——但不用擔心,我們將在下面處理它。

  9. 讓我們建立總大小為 35 GB 的新虛擬 QCOW2 磁碟newdisk.qcow2

    qemu-img create -f qcow2 -o preallocation=metadata newdisk.qcow2 35G
    

    其輸出:

    Formatting 'newdisk.qcow2', fmt=qcow2 size=37580963840 encryption=off cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16`
    
  10. 讓我們透過將舊磁碟複製到新分配的磁碟來調整磁碟大小。這是絕對很棒的一點。大多數其他指南都會展示一些非常複雜的內容。這只需透過以下命令即可完成,之後您應該去喝更多咖啡 - 這可能需要一段時間:

    virt-resize windows.qcow2 newdisk.qcow2`
    

    輸出如下:

    [   0.0] Examining windows.qcow2
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? --:--
    **********
    Summary of changes:
    /dev/sda1: This partition will be left alone.
    /dev/sda2: This partition will be left alone.
    There is a surplus of 439.8M.  An extra partition will be created for the surplus.
    **********
    [   8.8] Setting up initial partition table on newdisk.qcow2
    [   9.9] Copying /dev/sda1
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? 00:00
    [  15.1] Copying /dev/sda2
    100% ?¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦? 00:00
    Resize operation completed with no errors.  Before deleting the old disk, carefully check that the resized disk boots and works correctly.
    

    請注意,該工具發現了剩餘的空間...回想一下有關 Math 的註釋...因此您可以取消該操作並重新創建磁碟,或者像我們在這裡所做的那樣繼續,並sda2像步驟3 中所做的那樣擴展分區。

  11. 一旦完成。檢查生成的圖像:

    virt-filesystems --long --parts --blkdevs -h -a newdisk.qcow2
    

    輸出如下:

    Name       Type       MBR  Size  Parent
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   34G   /dev/sda
    /dev/sda3  partition  83  439.8M   /dev/sda
    /dev/sda   device     -    35G  -
    

    /dev/sda3請注意剩餘空間的類型是 linux 類型。剩餘空間是可以的,除非你的數學計算完全正確。我們將在下面進一步處理 Windows 來賓的這個額外分割區。現在,就忽略它吧。

  12. 交換磁碟映像:

    mv windows.qcow2 backup/
    mv newdisk.qcow2 windows.qcow2
    
  13. 啟動您的虛擬機器。

步驟 3:在 Window Guest 上完成磁碟操作

在此步驟中,我們將確認 Windows 啟動正常,並將 C 分割區擴展到額外的空間。

  1. 登入 Windows 訪客

  2. 打開“電腦管理”實用程序,透過開始功能表搜尋功能找到它。

  3. 在左側點擊“存儲->磁碟管理”

  4. 您應該會看到 3 個分割區:boot、C: 和一個 439 MB 的小分割區(最右邊)。顯示 3 個分區的電腦管理螢幕截圖

  5. 右鍵->刪除磁碟區刪除linux分割區。 (對於任何提示單擊“是”)

  6. 右鍵單擊 C: 分割區,然後按一下“擴充”,然後在對話方塊中按“下一步”和“確定”。它應該只提供擴展最後一個分區的數量。完成後,您已經調整了 C: 的大小,並且只剩下兩個分割區。

  7. 就是這樣。您的 Windows 用戶端現在只使用 35 GB 左右。請記住,由於所有開銷等原因,實際磁碟映像可能更大(可能接近 38 GB)。

檢查一切是否正常,然後刪除您的映像備份或將它們離線移至儲存中。

答案2

我終於成功地縮小了虛擬機器空間。一開始,W7 VM 在主機儲存上佔用了 107 GB。虛擬 HDD 大小為 100 GB,目前,VM 僅佔用 18 GB 的虛擬儲存。

這是我所做的:

  1. 清理虛擬磁碟機(刪除暫存檔案等)
  2. 使用具有「全面最佳化」功能的開源 UltraDefrag 軟體進行片段整理
  3. 跑步sdelete -c c:
  4. 跑步sdelete -z c:
  5. 跑步qemu-img convert -c -f qcow2 w7-64.qcow2 -O qcow2 w7-64-compressed.qcow2

這樣,qcow2 檔案就從 107 GB 縮小到...7 GB!

答案3

當您運行時qemu-img -c,您會壓縮映像,雖然能夠減少一些空間,但確實會損害效能。如果要對磁碟上的重複零進行刪除,則需要運行qemu-img convert,基本上就像您嘗試將映像從一種格式轉換為另一種格式一樣(即使 src 和 dst 格式相同)。

此過程將寫入一個新的轉換後的映像,不含零,從而有效地對磁碟機上的歸零空間進行重複資料刪除。

另一種選擇是簡單地使用virt-sparsifycourse。

答案4

virt-sparsify在 Xenial 和 Bionic 中,套件中的實用程序libguestfs 工具應該管用。注意:

  • 您不必sdelete事先在來賓內部運行類似的工具(但這不會有什麼壞處)
  • 您可以使用該--in-place標誌來釋放空間而不複製檔案(如果磁碟映像已經大於磁碟機上的剩餘可用空間,則非常有用!)
  • 此工具支援qcow2和raw格式影像

相關內容