縮減Azure上Linux虛擬機系統盤容量


【話在前頭】

這么些年微軟 Azure 創建虛擬機一直不能修改系統盤大小,但很多時候實際又用不了這么大的操作系統磁盤。微軟自己甚至還針對 Windows 服務器鏡像推出一個 smalldisk 的鏡像版本(https://azure.microsoft.com/en-us/blog/new-smaller-windows-server-iaas-image/),在原有 127GB 的鏡像外提供一個 32GB 版本的操作系統鏡像,可以根據自己的需要進行擴容。但是 Azure 提供的 Linux 服務器鏡像卻都是 30GB 的版本,網上其他人的解決辦法通常是下載磁盤 vhd 文件,然后本地打開后用 Hyper-V 進行縮小后再上傳,或者直接用 Azure 的存儲賬戶進行在線編輯 vhd 文件(見相關鏈接12)。本文通過創建小容量磁盤,直接復制磁盤分區的方式來解決這個問題。

 

【文章索引】

  1. 縮減操作系統分區容量
  2. 復制分區到小容量磁盤
  3. 修改小容量磁盤配置
  4. 相關鏈接

 

【一、縮減操作系統分區容量】

Azure 支持修改托管磁盤的容量,但是只支持擴大,不支持縮小,如果調整磁盤大小時設置了比之前更小的容量,則會提示下圖所示的內容。

首先,與其他方案相同,需要先准備一份已縮減分區容量的系統盤。Linux 不像 Windows 提供了磁盤管理工具,可以在線縮減系統盤容量,需要創建一個當前操作系統磁盤的副本並掛載到系統上進行調整。這里先對當前系統盤創建一份快照,如下圖。

然后對這個快照創建磁盤,如下圖。

完成后就可以將創建好的系統盤副本附加到虛擬機中,同時再附加一個小容量的空磁盤用於創建最終的小容量系統盤。

由於復制后的磁盤分區的Uuid與之前的磁盤分區完全一樣,所以如果在虛擬機啟動前附加的磁盤,虛擬機啟動后根目錄(/)掛載點會被后附加的這塊磁盤掛載,所以如果要縮減分區需要對第一塊磁盤(/dev/sda)進行操作;反之如果是虛擬機啟動后附加的磁盤,根目錄掛載點還是第一塊磁盤(/dev/sda1),如果要縮減分區需要對后掛載的磁盤(/dev/sdc 或 /dev/sdd)進行操作。

這里以啟動后附加磁盤為例,小容量空磁盤是 /dev/sdc,操作系統副本磁盤是 /dev/sdd。首先需要縮減文件系統容量,分別執行“e2fsck”和“resize2fs”,其中“resize2fs”設置的大小不能大於后續分區的大小,如果不確認后續使用的各個工具的單位,這里也可以故意設置小一些,如下

root@xxx-vm:/tmp# e2fsck -f /dev/sdd1
e2fsck 1.44.5 (15-Dec-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdd1: 26148/1957888 files (0.2% non-contiguous), 365215/7831547 blocks
root@xxx-vm:/tmp# resize2fs /dev/sdd1 3G
resize2fs 1.44.5 (15-Dec-2018)
Resizing the filesystem on /dev/sdd1 to 786432 (4k) blocks.
The filesystem on /dev/sdd1 is now 786432 (4k) blocks long.

然后可以使用 parted 或 fdisk 進行分區的調整,個人覺得 parted 更簡單一些,一條命令即可修改,不像 fdisk 需要還需要先刪除再創建,如下

root@xxx-vm:/tmp# parted /dev/sdd
GNU Parted 3.2
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Warning: Not all of the space available to /dev/sdd appears to be used, you can fix the GPT to use all of the space (an extra 4194304 blocks) or continue with the current setting?
Fix/Ignore? Ignore
Model: Msft Virtual Disk (scsi)
Disk /dev/sdd: 34.4GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name  Flags
14      1049kB  4194kB  3146kB                     bios_grub
15      4194kB  134MB   130MB   fat16              boot, esp
 1      134MB   32.2GB  32.1GB  ext4

(parted) resizepart 1 4G
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes
(parted)
Information: You may need to update /etc/fstab.

完成后可以用 mount 掛載一下分區進行驗證,看看是否能進行正常掛載以及文件系統容量是否符合預期。

 

【二、復制分區到小容量磁盤】

在第一步確認沒問題后可以將上述磁盤內的內容復制到小容量磁盤中,這里使用 fdisk 把調小分區容量的磁盤分區表備份下來,如下

root@xxx-vm:/tmp# fdisk /dev/sdd

Welcome to fdisk (util-linux 2.33.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. The backup GPT table is not on the end of the device. This problem will be corrected by write. Command (m for help): O Enter script file name: os-disk-pt Script successfully saved. Command (m for help): q

然后修改分區表備份文件 os-disk-pt 文件中 last-lba 的值為小容量磁盤的最后一個扇區,然后用 fdisk 對小容量磁盤導入該分區表即可,如下

root@xxx-vm:/tmp# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.33.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x99a32e79. Command (m for help): I Enter script file name: os-disk-pt Created a new GPT disklabel (GUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX). Created a new partition 1 of type 'Linux filesystem' and of size 3.6 GiB. Created a new partition 14 of type 'BIOS boot' and of size 3 MiB. Created a new partition 15 of type 'EFI System' and of size 124 MiB. Script successfully applied. Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.

完成后分別對所有分區使用 dd 命令復制即可,如下

root@xxx-vm:/tmp# dd if=/dev/sdd1 of=/dev/sdc1 bs=1M 3686+1 records in
3686+1 records out
3865782784 bytes (3.9 GB, 3.6 GiB) copied, 179.995 s, 21.5 MB/s
root@xxx-vm:/tmp# dd if=/dev/sdd14 of=/dev/sdc14 bs=1M 3+0 records in
3+0 records out
3145728 bytes (3.1 MB, 3.0 MiB) copied, 0.147453 s, 21.3 MB/s
root@xxx-vm:/tmp# dd if=/dev/sdd15 of=/dev/sdc15 bs=1M 124+0 records in
124+0 records out
130023424 bytes (130 MB, 124 MiB) copied, 5.775 s, 22.5 MB/s

完成后也可以用 mount 掛載一下新的分區進行驗證,沒問題后即可關閉該虛擬機。

 

【三、修改小容量磁盤配置】

通過界面創建的磁盤是不帶有操作系統類型的,也沒法讓虛擬機將該磁盤作為系統盤進行啟動,這里需要使用 Azure 的命令行,例如使用 Azure Powershell,可以參考相關鏈接3進行安裝。

然后打開 Powershell,輸入 “Connect-AzAccount”,即可彈出登錄 Azure 的對話框,並進行確認,完成后會顯示賬戶的所有訂閱,如下圖

然后輸入下列命令設置以下幾個環境變量

$DiskID = "磁盤資源ID"
$VMName = "虛擬機名稱"
$AzSubscription = "訂閱名"

其中“磁盤資源ID”需要進入磁盤頁面,並在“屬性”頁面中找到“資源ID”即為該內容,類似 “/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxx/providers/Microsoft.Compute/disks/xxxxxxxx”,如下圖

然后再執行下列命令即可

# 指定訂閱
Select-AzSubscription -Subscription $AzSubscription

# 獲取虛擬機信息
$VM = Get-AzVm | ? Name -eq $VMName

# 獲取磁盤信息
$Disk = Get-AzDisk | ? Id -eq $DiskID

# 修改磁盤操作系統類型
$Disk.OsType = "Linux"

# 修改磁盤 Hyper-V 代數(宿主機為V2時需要手動設置)
$Disk.HyperVGeneration = "V2"

# 更新磁盤設置
Update-AzDisk -ResourceGroupName $VM.ResourceGroupName -DiskName $Disk.Name -Disk $Disk

完成后即可在虛擬機頁面中,選擇“磁盤” -> “交換 OS 磁盤”,剛剛創建的小容量磁盤即會出現在這個頁面中,確定后啟動虛擬機即可。

 

【四、相關鏈接】

  1. How to shrink a managed disk:https://devblogs.microsoft.com/premier-developer/how-to-shrink-a-managed-disk/
  2. Shrink an Azure VMs OS Managed Disk using PowerShell:https://jrudlin.github.io/2019-08-27-shrink-azure-vm-osdisk/
  3. Install the Azure Az PowerShell module:https://docs.microsoft.com/en-us/powershell/azure/install-az-ps


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM