排查由于 Hyper-V 驱动程序相关的错误而导致的 Linux 虚拟机启动和网络问题

Azure 在 Hyper-V 虚拟机监控程序上运行,Linux 系统需要某些 Hyper-V 内核模块才能在 Azure 上运行。 这些内核模块捆绑到适用于 Hyper-V 和 Azure 的 Linux Integration Services (LIS) 驱动程序中。 Microsoft 将其直接贡献给 上游 Linux 内核。

本文讨论多个条件,其中一个或多个禁用的 Hyper-V 驱动程序可能导致 Linux 虚拟机 (VM) 启动和网络问题。

先决条件

确保 串行控制台 在 Linux VM 中已启用且正常运行。

如何识别缺少 Hyper-V 驱动程序的问题

若要确定 VM 是否由于缺少 Hyper-V 驱动程序而无法启动,请使用 Azure CLI 或Azure 门户在启动诊断窗格或串行控制台窗格中查看 VM 的串行控制台日志。 失败的示例输出显示在下面的相应部分中。

排查问题之前

若要排查 方案 1:网络 Hyper-V 驱动程序已禁用方案 2:NIC mac 地址已更改或不匹配的问题,需要对 Linux VM 进行 串行控制台 访问。

如果没有串行控制台访问权限,请按照 脱机方法 从救援虚拟机访问有问题的 OS 磁盘的内容。 脱机方法需要访问 Azure CLI 或 Azure Cloud Shell

若要排查 方案 3:禁用其他 Hyper-V 驱动程序的问题,脱机方法是解决问题的唯一选项。

方案 1:网络 Hyper-V 驱动程序已禁用

由于网络服务不可用,因此无法 (SSH) 虚拟机的安全外壳协议,但仍可以通过串行控制台从Azure 门户登录。 可以在串行控制台或Azure 门户的“启动诊断”窗格中看到以下类型的错误:

 cloud-init[807]: Cloud-init v. 19.4 running 'init-local' at Tue, xx Aug 20XX 20:41:53 +0000. Up 5.83 seconds.
 cloud-init[807]: 20XX-08-XX 20:41:54,231 - stages.py[WARNING]: Failed to rename devices: [nic not present] Cannot rename mac=xx:xx:xx:xx:xx:xx to eth0, not available.
[  OK  ] Started Initial cloud-init job (pre-networking).
----
[FAILED] Failed to start LSB: Bring up/down networking.
See 'systemctl status network.service' for details.

 cloud-init[799]: 2022-XX-XX 19:04:06,267 - azure.py[WARNING]: Interface not found for DHCP
 cloud-init[799]: 2022-XX-XX 19:04:07,269 - azure.py[WARNING]: Interface not found for DHCP
 cloud-init[799]: 2022-XX-XX 19:04:10,274 - azure.py[WARNING]: Interface not found for DHCP
 cloud-init[799]: 2022-XX-2XX 19:04:10,277 - azure.py[WARNING]: IMDS network metadata has incomplete configuration: None

解决方案 1:使用串行控制台启用 Hyper-V 网络驱动程序

  1. 访问 VM 的串行控制台。 网络已关闭,但登录提示仍可用。

  2. 使用正确的凭据登录到 VM。

  3. 切换到具有 sudo 访问权限的根帐户或用户帐户。

  4. 转到 /etc/modprobe.d 目录,查找禁用hv_netvsc驱动程序的任何行。

    1. 通过运行以下命令,确定禁用hv_netvsc驱动程序和相应行号的文件:

      grep -nr "hv_netvsc" /etc/modprobe.d/
      
    2. 修改相应的文件并注释掉或删除hv_netvsc项:

      显示用于禁用网络驱动程序的可能配置文件内容的屏幕截图。

      vi /etc/modprobe.d/disable.conf
      

      注意

      • 禁用驱动程序的条目由 Linux 操作系统定义,而不是由 Microsoft 定义。
      • 将 替换为 disable.conf 禁用hv_netvsc驱动程序的相应文件名。
  5. 为当前加载的内核重新生成初始 RAMdisk 映像:

    • 对于基于 RHEL/SLES 的图像

      # dracut -f -v
      
    • 对于基于 Ubuntu/Debian 的映像

      # mkinitramfs -k -o /boot/initrd.img-$(uname -r)
      
  6. 重新启动 VM。

始终备份原始初始 RAMdisk 映像,以便在需要时进行回滚。

  • 对于基于 RHEL 的映像:

    # cp /boot/initramfs-<kernelVersion>.img /boot/initramfs-<kernelVersion>.img.bak
    
  • 对于基于 SLES 的图像:

    # cp /boot/initrd-<kernelVersion> /boot/initrd-<kernelVersion>.bak
    
  • 对于基于 Ubuntu/Debian 的映像:

    # cp /boot/initrd.img-<kernelVersion> /boot/initrd.img-<kernelVersion>.bak
    

解决方案 2:脱机启用 Hyper-V 网络驱动程序

  1. 使用 az vm repair 从救援 VM 访问受影响 OS 磁盘的内容。

  2. 按照 chroot 说明将和 chroot 装载到救援 VM 中附加的 OS 磁盘 文件系统。

  3. 访问受影响的 OS 磁盘的内容后,请按照 解决方案 1:使用串行控制台启用 Hyper-V 网络驱动程序 中的步骤 4 和 5 重新启用驱动程序并重新生成初始 RAMdisk 映像。

    在重新生成初始 RAMdisk 映像之前,请切换到 chroot 环境。 必须提供映像的完整路径。

  4. 应用更改后,与原始 VM 执行自动 OS 磁盘交换,并使用 az vm repair restore 命令重新启动系统。

方案 2:NIC MAC 地址已更改或不匹配

如果网络接口卡 MAC 地址已更改或在 OS 配置中不匹配,则无法通过 SSH 连接到 VM,因为网络服务不可用。 你仍可以通过串行控制台从 Azure 门户登录。 将显示类似于 方案 1:禁用网络 Hyper-V 驱动程序 中的错误。

如果即使启用了 Hyper-V 网络驱动程序,问题仍然存在,请使用以下解决方案之一来验证 OS NIC 配置并解决问题。

解决方案 1:使用串行控制台修复 NIC MAC 地址不匹配问题

  1. 访问 VM 的串行控制台。 网络已关闭,但登录提示仍可用。

  2. 使用正确的凭据登录到 VM。

  3. 切换到具有 sudo 访问权限的根帐户或用户帐户。

  4. 转到 /etc/cloud/cloud.cfg.d 目录。

  5. 考虑使用 Linux 合作伙伴映像 ,打开和编辑以下文件:

    • 91-azure_datasource.cfg ,用于基于 RHEL 的分发。
    • 90_dpkg.cfg ,适用于 Debian 和基于 Ubuntu 的发行版。
  6. 如果参数 apply_network_config 设置为 false,则将其设置为 true。 如果未指定任何内容,则默认值设置为 true。 此设置将确保在下次重新启动时将新的 MAC 地址应用于网络配置。

  7. 通常,仅当管理员删除或添加 NIC 或在后端更新 NIC 时,NIC MAC 地址才会更改。 如果不需要通过 cloud-init 进行网络配置,并且 apply_network_config 参数需要设置为 false,请删除 /var/lib/cloud/instance/obj.pkl 文件并重新启动系统。

    # rm /var/lib/cloud/instance/obj.pkl
    
  8. 应用更改后,重启系统。

解决方案 2:修复脱机 NIC MAC 地址不匹配问题

  1. 使用 az vm repair 命令从救援虚拟机访问受影响 OS 磁盘的内容。
  2. 按照 chroot 说明正确装载并 chroot 到救援 VM 中附加的 OS 磁盘 文件系统。
  3. 访问受影响的 OS 磁盘副本的内容后,请按照 解决方案 1:使用串行控制台修复 NIC MAC 地址不匹配 中的步骤 4 到 7 进行网络更改或清除 obj.pkl 文件。
  4. 应用更改后,使用 az vm repair restore 命令与原始 VM 执行自动 OS 磁盘交换并重新启动系统。

方案 3:禁用其他 Hyper-V 驱动程序

如果遇到其他 Hyper-V 驱动程序的启动问题,则可能无法通过 SSH 连接到 VM,因为网络服务不可用。 你被扔进了一个草皮壳。 可以通过串行控制台从 Azure 门户查看此问题。 可以在Azure 门户的“启动诊断”窗格中的串行控制台或最新串行日志中看到以下错误:

 dracut-initqueue[455]: Warning: dracut-initqueue timeout - starting timeout scripts
 dracut-initqueue[455]: Warning: Could not boot.
         Starting Setup Virtual Console...
[  OK  ] Started Setup Virtual Console.
         Starting Dracut Emergency Shell...
Warning: /dev/mapper/rootvg-rootlv does not exist
Generating "/run/initramfs/rdsosreport.txt"
 
Entering emergency mode. Exit the shell to continue.
Type "journalctl" to view system logs.
You might want to save "/run/initramfs/rdsosreport.txt" to a USB stick or /boot
after mounting them and attach it to a bug report.
dracut:/#

Gave up waiting for root file system device.  Common problems:
 - Boot args (cat /proc/cmdline)
   - Check rootdelay= (did the system wait long enough?)
 - Missing modules (cat /proc/modules; ls /dev)
ALERT!  UUID=143c811b-9b9c-48f3-b0c8-040f6e65f50aa does not exist.  Dropping to a shell!


BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu3.4) built-in shell (ash)
Enter 'help' for a list of built-in commands.

(initramfs)

解决方案:启用 Hyper-V 驱动程序

如果由于禁用其他 Hyper-V 驱动程序而无法访问 VM,请使用脱机方法来重新启用驱动程序,因为无法加载 initramfs。

  1. 使用 az vm repair 命令从救援虚拟机访问有问题的 OS 磁盘的内容。

  2. 按照 chroot 说明正确将和 chroot 装载到救援 VM 中附加的 OS 磁盘 文件系统。

  3. 进入 chroot 环境后,转到 /etc/modprobe.d 目录,查找可能禁用hv_utils、hv_vmbus、hv_storvsc或hv_netvsc驱动程序的任何行。

    1. 运行以下命令,确定禁用hv_utils、hv_vmbus、hv_storvsc或hv_netvsc驱动程序的文件以及相应的行号。

      egrep -nr "hv_utils|hv_vmbus|hv_storvsc|hv_netvsc" /etc/modprobe.d/
      
    2. 修改相应的文件,并注释掉或删除hv_utils、hv_vmbus、hv_storvsc或hv_netvsc项。 条目通常为以下任一 (或两者) :

      显示使用安装选项禁用内核模块/驱动程序的可能配置文件内容的屏幕截图。

      显示用于禁用内核模块/驱动程序的可能配置文件内容的屏幕截图。

      vi /etc/modprobe.d/disable.conf
      

    重要

    • 禁用驱动程序的条目由 Linux 操作系统定义,而不是由 Microsoft 定义。
    • 将 替换为 disable.conf 禁用 Hyper-V 驱动程序的相应文件名。
  4. 为当前加载的内核重新生成初始 RAMdisk 映像:

    • 对于基于 RHEL/SLES 的图像

      # dracut -f -v
      
    • 对于基于 Ubuntu/Debian 的映像

      # mkinitramfs -k -o /boot/initrd.img-$(uname -r)
      
  5. 应用更改后,使用 az vm repair restore 命令与原始 VM 执行自动 OS 磁盘交换并重新启动系统。

始终备份原始初始 RAMdisk 映像,以便在需要时进行回滚。

如果问题仍未解决,请参阅 Azure Linux 虚拟机无法启动并输入 dracut 紧急 shell 以调查 dracut 问题。

后续步骤

如果特定的启动错误不是 Hyper-V 问题,请参阅排查 Azure Linux 虚拟机启动错误以获取进一步的故障排除选项。

联系我们寻求帮助

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