扩展 Linux VM 上的虚拟硬盘

适用于:✔️ Linux VM ✔️ 灵活规模集

本文介绍如何扩展 Linux 虚拟机 (VM) 的托管磁盘。 你可以通过添加数据磁盘来扩充存储空间,也可扩展现有的数据磁盘。 在 Azure 中的 Linux VM 上,操作系统 (OS) 的默认虚拟硬盘大小通常为 30 GB。 本文介绍如何扩展 OS 磁盘或数据磁盘。 无法扩展条带卷的大小。

OS 磁盘的最大容量为 4,095 GiB。 但许多操作系统默认使用主启动记录 (MBR) 进行分区。 MBR 将可用大小限制为 2 TiB。 如果需要 2 TiB 以上,请考虑为数据存储附加数据磁盘。 如果确实需要将数据存储在操作系统磁盘上,并且需要额外的空间,请将其转换为 GUID 分区表 (GPT)。

警告

始终确保文件系统处于正常状态,磁盘分区表类型(GPT 或 MBR)将支持新的大小,并确保在执行磁盘扩展操作之前备份数据。 有关详细信息,请参阅 Azure 备份快速入门

识别操作系统中的 Azure 数据磁盘对象

如果 VM 上存在多个数据磁盘,在扩展数据磁盘时可能难以将 Azure LUN 与 Linux 设备相关联。 如果 OS 磁盘需要扩展,则 Azure 门户中会明确将它标记为 OS 磁盘。

首先使用 df 命令识别磁盘利用率、装载点和设备之间的关系。

df -Th
Filesystem                Type      Size  Used Avail Use% Mounted on
/dev/sda1                 xfs        97G  1.8G   95G   2% /
<truncated>
/dev/sdd1                 ext4       32G   30G  727M  98% /opt/db/data
/dev/sde1                 ext4       32G   49M   30G   1% /opt/db/log

例如,在此处我们可以看到,/opt/db/data 文件系统几乎已满并且位于 /dev/sdd1 分区上。 df 的输出将显示设备路径,无论磁盘是使用设备路径还是 fstab 中的 UUID(首选)装载的。 另请注意“类型”列,它指示文件系统的格式。 格式会在后面会有重要影响。

现在,请通过检查 /dev/disk/azure/scsi1 的内容找到与 /dev/sdd 关联的 LUN。 在 Azure 门户中查找时,以下 ls 命令的输出将显示 Linux OS 中名为 /dev/sdd 的设备位于 LUN1 中。

sudo ls -alF /dev/disk/azure/scsi1/
total 0
drwxr-xr-x. 2 root root 140 Sep  9 21:54 ./
drwxr-xr-x. 4 root root  80 Sep  9 21:48 ../
lrwxrwxrwx. 1 root root  12 Sep  9 21:48 lun0 -> ../../../sdc
lrwxrwxrwx. 1 root root  12 Sep  9 21:48 lun1 -> ../../../sdd
lrwxrwxrwx. 1 root root  13 Sep  9 21:48 lun1-part1 -> ../../../sdd1
lrwxrwxrwx. 1 root root  12 Sep  9 21:54 lun2 -> ../../../sde
lrwxrwxrwx. 1 root root  13 Sep  9 21:54 lun2-part1 -> ../../../sde1

扩展 Azure 托管磁盘

在不停机的情况下扩展

你可以在不解除分配虚拟机的情况下扩展托管磁盘。 磁盘的主机缓存设置不会更改你是否可以在不解除分配虚拟机的情况下扩展数据磁盘。

此功能具有以下限制:

  • 仅支持数据磁盘。
  • 如果磁盘小于或等于 4 TiB,应解除分配 VM 并拆离磁盘,然后再将其扩展到 4 TiB 以上。 如果磁盘已经大于 4 TiB,则可以在不解除分配 VM 和拆离磁盘的情况下对其进行扩展。
  • 不支持超级磁盘或高级 SSD v2 磁盘。
  • 不支持共享磁盘。
  • 安装并使用以下任一项:
  • 在某些经典 VM 上不可用。 使用此脚本可获取支持在不停机的情况下扩展的经典 VM SKU 列表。

扩展 Azure 托管磁盘

确保已安装了最新的 Azure CLI 并已使用 az login 登录到 Azure 帐户。

本文需要 Azure 中的现有 VM 已附加至少一个数据磁盘并且该磁盘已准备就绪。 如果尚无可用的虚拟机,请参阅使用数据磁盘创建和准备虚拟机

注意

在可以在由世纪互联运营的 Microsoft Azure 中使用 Azure CLI 之前,请先运行 az cloud set -n AzureChinaCloud 来更改云环境。 若要切换回 Azure 公有云,请再次运行 az cloud set -n AzureCloud

在以下示例中,请将示例参数名称(例如 myResourceGroupmyVM)替换成自己的值。

重要

如果磁盘满足在不停机的情况下扩展中的要求,则可以跳过第 1 步和第 3 步。

不支持收缩现有磁盘,这可能会导致数据丢失。

扩展磁盘后,需要扩展操作系统中的卷才能使用更大的磁盘。

  1. 当 VM 正在运行时,无法在虚拟硬盘上执行操作。 使用 az vm deallocate 解除分配 VM。 以下示例在名为 myResourceGroup 的资源组中解除分配名为 myVM 的 VM:

    az vm deallocate --resource-group myResourceGroup --name myVM
    

    注意

    只有释放 VM 才能扩展虚拟硬盘。 使用 az vm stop 停止虚拟机不会释放计算资源。 若要释放计算资源,请使用 az vm deallocate

  2. 使用 az disk list 查看资源组中的托管磁盘列表。 以下示例显示名为 myResourceGroup 的资源组中的托管磁盘列表:

    az disk list \
        --resource-group myResourceGroup \
        --query '[*].{Name:name,Gb:diskSizeGb,Tier:accountType}' \
        --output table
    

    使用 az disk update 扩展所需磁盘。 以下示例将名为 myDataDisk 的托管磁盘扩展为 200 GB:

    az disk update \
        --resource-group myResourceGroup \
        --name myDataDisk \
        --size-gb 200
    

    注意

    扩展托管磁盘时,更新的大小将向上舍入到最接近的托管磁盘大小。 有关可用托管磁盘大小和层的表,请参阅 Azure 托管磁盘概述 - 定价和计费

  3. 使用 az vm start 启动 VM。 以下示例在名为 myResourceGroup 的资源组中启动名为 myVM 的 VM:

    az vm start --resource-group myResourceGroup --name myVM
    

扩展磁盘分区和文件系统

注意

虽然有许多工具可用于执行分区大小调整,但本文其余部分详细介绍的工具与某些自动化进程(例如 cloud-init)所使用的工具相同。 如此处所述,带有 gdisk 包的 growpart 工具提供了与 GUID 分区表 (GPT) 磁盘的通用兼容性,因为某些工具(如 fdisk)的旧版本不支持 GPT。

检测已更改的磁盘大小

如果使用上述过程在不停机的情况下扩展了数据磁盘,则在重新扫描设备(通常只在启动过程中进行)之前,报告的磁盘大小不会改变。 可以通过以下过程按需调用重新扫描。 在此示例中,我们使用本文档中的方法发现,数据磁盘当前为 /dev/sda,其大小从 256 GiB 变成了 512 GiB。

  1. 确定 fdisk -l /dev/sda 输出第一行上当前识别的大小

    sudo fdisk -l /dev/sda
    
    Disk /dev/sda: 256 GiB, 274877906944 bytes, 536870912 sectors
    Disk model: Virtual Disk
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disklabel type: dos
    Disk identifier: 0x43d10aad
    
    Device     Boot Start       End   Sectors  Size Id Type
    /dev/sda1        2048 536870878 536868831  256G 83 Linux
    
  2. 1 字符插入到此设备的重新扫描文件中。 请注意示例中对 sda 的引用。 如果调整了其他磁盘设备的大小,则磁盘标识符会更改。

    echo 1 | sudo tee /sys/class/block/sda/device/rescan
    
  3. 验证是否已识别新的磁盘大小

    sudo fdisk -l /dev/sda
    
    Disk /dev/sda: 512 GiB, 549755813888 bytes, 1073741824 sectors
    Disk model: Virtual Disk
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disklabel type: dos
    Disk identifier: 0x43d10aad
    
    Device     Boot Start       End   Sectors  Size Id Type
    /dev/sda1        2048 536870878 536868831  256G 83 Linux
    

本文的余下部分使用 OS 磁盘作为在 OS 级别增加卷大小的过程的示例。 如果扩展的磁盘是数据磁盘,请使用之前的指南来标识数据磁盘设备,并按照这些说明作为指导,根据需要替换数据磁盘磁盘(例如 /dev/sda)、分区号、卷名、装入点和文件系统格式。

所有 Linux OS 指南都应被视为通用指南,并可能适用于任何分发版,但通常与命名市场发布者的约定相匹配。 请参考 Red Hat 文档,了解任何基于 Red Hat 或声称与 Red Hat 兼容的分发版的程序包要求。

增加 OS 磁盘的大小

以下说明适用于认可的 Linux 发行版。

注意

在继续操作之前,请创建 VM 的完整备份副本,至少应创建 OS 磁盘的快照。

在 Ubuntu 16.x 和更高版本上,操作系统磁盘和文件系统的根分区将通过 cloud-init 自动扩展以利用根磁盘上的所有可用连续空间,前提是有少量的可用空间用于大小调整操作。 在这种情况下,序列将只是执行以下操作:

  1. 根据前面的详述增加 OS 磁盘的大小
  2. 重启 VM,然后使用 root 用户帐户访问 VM。
  3. 验证 OS 磁盘现在是否显示增加后的文件系统大小。

如以下示例所示,操作系统磁盘已在门户中调整为 100 GB。 / 上装载的 /dev/sda1 文件系统现在显示为 97 GB。

df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
udev           devtmpfs  314M     0  314M   0% /dev
tmpfs          tmpfs      65M  2.3M   63M   4% /run
/dev/sda1      ext4       97G  1.8G   95G   2% /
tmpfs          tmpfs     324M     0  324M   0% /dev/shm
tmpfs          tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs          tmpfs     324M     0  324M   0% /sys/fs/cgroup
/dev/sda15     vfat      105M  3.6M  101M   4% /boot/efi
/dev/sdb1      ext4       20G   44M   19G   1% /mnt
tmpfs          tmpfs      65M     0   65M   0% /run/user/1000
user@ubuntu:~#

不停机扩展经典 VM SKU 支持

如果使用经典 VM SKU,可能不支持在不停机的情况下扩展磁盘。

使用以下 PowerShell 脚本确定其可用的 VM SKU:

Connect-AzAccount -Environment AzureChinaCloud
$subscriptionId="yourSubID"
$location="desiredRegion"
Set-AzContext -Subscription $subscriptionId
$vmSizes=Get-AzComputeResourceSku -Location $location | where{$_.ResourceType -eq 'virtualMachines'}

foreach($vmSize in $vmSizes){
    foreach($capability in $vmSize.Capabilities)
    {
       if(($capability.Name -eq "EphemeralOSDiskSupported" -and $capability.Value -eq "True") -or ($capability.Name -eq "PremiumIO" -and $capability.Value -eq "True") -or ($capability.Name -eq "HyperVGenerations" -and $capability.Value -match "V2"))
        {
            $vmSize.Name
       }
   }
}