排查 Linux VM 设备名称更改问题

适用于:✔️ Linux VM

本文解释重启 Linux VM 或重新附加数据磁盘后,设备名为何发生更改。 此外,本文还提供针对此问题的解决方案。

现象

在 Microsoft Azure 中运行 Linux VM 时,可能会遇到以下问题:

  • 重启后 VM 无法引导。
  • 分离再重新附加数据磁盘时,磁盘的设备名发生更改。
  • 使用设备名引用磁盘的应用程序或脚本会失败,因为设备名已发生更改。

原因

不保证 Linux 中的设备路径在重启后保持一致。 设备名由主要编号(字母)和次要编号组成。 当 Linux 存储设备驱动程序检测到新设备时,驱动程序会将可用范围内的主要和次要设备编号分配给该设备。 移除某个设备后,其设备编号将被释放,供重复使用。

之所以发生该问题,是因为 Linux 中的设备扫描由 SCSI 子系统计划以异步方式进行。 因此,设备路径名称会在重启后发生变化。

解决方案

若要解决此问题,请使用在重新启动时持久存在的设备名称。 有多种方法可以使用持久性命名:按文件系统标签、UUID 或派生设备路径。 对于不使用逻辑卷管理器(LVM)的 Linux VM,建议使用文件系统的 UUID 或 使用 udev 规则创建的链接。 对于基于 LVM 的文件系统,使用卷组和逻辑卷名称进行装载也是一种有效的方法,因为无论物理卷是如何排序的,LVM 对象都保持一致。

大多数分布区都提供 fstab nofailnobootwait 参数。 在启动时若无法装载磁盘,这些参数可使系统启动。 有关这些参数的详细信息,请查看分发文档。 有关在添加数据磁盘时如何将 Linux VM 配置为使用 UUID 的信息,请参阅连接到 Linux VM 以装载新磁盘

如果已以无法启动 VM 且无法通过 SSH 连接到 VM 的方式编辑 fstab,则可以使用 VM 串行控制台 进入 单用户模式 并修改 fstab,或使用 Azure Linux 自动修复 来自动执行修复过程。

识别磁盘 LUN

在 VM 上安装 Azure Linux 代理时,代理使用 udev 规则在 /dev/disk/azure 路径下构造一组符号链接,该链接将 Azure 定义的 LUN 附件关联到传统磁盘设备:

$ tree /dev/disk/azure

/dev/disk/azure
├── resource -> ../../sdb
├── resource-part1 -> ../../sdb1
├── root -> ../../sda
├── root-part1 -> ../../sda1
└── scsi1
    ├── lun0 -> ../../../sdc
    ├── lun0-part1 -> ../../../sdc1
    ├── lun1 -> ../../../sdd
    ├── lun1-part1 -> ../../../sdd1
    ├── lun1-part2 -> ../../../sdd2
    └── lun1-part3 -> ../../../sdd3

Linux 来宾帐户中的 LUN 信息通过使用 lsscsi 或类似工具进行检索:

$ sudo lsscsi

[1:0:0:0] cd/dvd Msft Virtual CD/ROM 1.0 /dev/sr0

[2:0:0:0] disk Msft Virtual Disk 1.0 /dev/sda

[3:0:1:0] disk Msft Virtual Disk 1.0 /dev/sdb

[5:0:0:0] disk Msft Virtual Disk 1.0 /dev/sdc

[5:0:0:1] disk Msft Virtual Disk 1.0 /dev/sdd

来宾 LUN 信息与 Azure 订阅元数据一起用于在包含分区数据的 Azure 存储中查找 VHD。 例如,可以使用 az CLI:

$ az vm show --resource-group testVM --name testVM | jq -r .storageProfile.dataDisks
[
{
"caching": "None",
  "createOption": "empty",
"diskSizeGb": 1023,
  "image": null,
"lun": 0,
"managedDisk": null,
"name": "testVM-20170619-114353",
"vhd": {
  "uri": "https://testVM.blob.core.windows.net/vhd/testVM-20170619-114353.vhd"
}
},
{
"caching": "None",
"createOption": "empty",
"diskSizeGb": 512,
"image": null,
"lun": 1,
"managedDisk": null,
"name": "testVM-20170619-121516",
"vhd": {
  "uri": "https://testVM.blob.core.windows.net/vhd/testVM-20170619-121516.vhd"
  }
  }
]

使用 blkid 发现文件系统 UUID

应用程序和脚本读取 blkid 的输出或类似的信息源,以在 /dev 路径中构造符号链接。 该输出显示所有附加到 VM 的磁盘的 UUID 及与其关联的设备文件:

$ sudo blkid -s UUID

/dev/sr0: UUID="120B021372645f72"
/dev/sda1: UUID="52c6959b-79b0-4bdd-8ed6-71e0ba782fb4"
/dev/sdb1: UUID="176250df-9c7c-436f-94e4-d13f9bdea744"
/dev/sdc1: UUID="b0048738-4ecc-4837-9793-49ce296d2692"

Azure Linux 代理 Udev 规则在 /dev/disk/azure 路径下构造一组符号链接:

$ ls -l /dev/disk/azure

total 0
lrwxrwxrwx 1 root root  9 Jun  2 23:17 resource -> ../../sdb
lrwxrwxrwx 1 root root 10 Jun  2 23:17 resource-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 Jun  2 23:17 root -> ../../sda
lrwxrwxrwx 1 root root 10 Jun  2 23:17 root-part1 -> ../../sda1

应用程序可使用此链接来识别启动盘设备和资源(临时)磁盘。 在 Azure 中,应用程序应搜索 /dev/disk/azure/root-part1 或 /dev/disk/azure-resource-part1 路径来发现这些分区。

blkid 列表中的任何其他分区都驻留在数据磁盘上。 应用程序维护这些分区的 UUID,并在运行时使用路径来发现设备名:

$ ls -l /dev/disk/by-uuid/b0048738-4ecc-4837-9793-49ce296d2692

lrwxrwxrwx 1 root root 10 Jun 19 15:57 /dev/disk/by-uuid/b0048738-4ecc-4837-9793-49ce296d2692 -> ../../sdc1

获取最新的 Azure 存储规则

若要获取最新的 Azure 存储规则,请运行以下命令:

# sudo curl -o /etc/udev/rules.d/66-azure-storage.rules https://raw.githubusercontent.com/Azure/WALinuxAgent/master/config/66-azure-storage.rules
# sudo udevadm trigger --subsystem-match=block

另请参阅

有关详细信息,请参阅以下文章:

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区