为 Azure 准备 Ubuntu 虚拟机

适用于:✔️ Linux 虚拟机 ✔️ 灵活规模集

Ubuntu 提供官方的 Azure 就绪云映像(cloudimg),其中包括在 Azure 上成功预配所需的所有组件,例如 cloud-init、Azure 优化的内核、Azure 来宾代理兼容性以及虚拟化环境的性能优化默认值。 这些映像是创建自定义 VHD 时建议的起点,因为它们符合Azure VM 预配要求并减少所需的手动配置步骤。

Ubuntu以多种格式发布这些映像,包括https://cloud-images.ubuntu.com/网站上的即用型的 Azure 虚拟硬盘(VHD)。 如果需要为Azure生成专用的 Ubuntu 映像,可以从这些经过验证的 VHD 生成开始,并根据需要对其进行自定义。 可在以下位置获取最新的映像版本:

先决条件

本文假定已将 Ubuntu Linux 操作系统 (OS) 安装到 VHD。 可使用多种工具创建 .vhd 文件。 一个例子是虚拟化解决方案(如 Hyper-V)。 有关说明,请参阅安装 Hyper-V 角色并配置虚拟机 (VM)

Ubuntu 安装说明

  • 有关为Azure准备 Linux 的更多提示,请参阅 General Linux 安装说明
  • Azure不支持 VHDX 格式,仅支持 fixed VHD。 可使用 Hyper-V 管理器或 Convert-VHD cmdlet 将磁盘转换为 VHD 格式。
  • 在安装 Linux 系统时,建议使用标准分区而不是逻辑卷管理器 (LVM)(通常是许多安装的默认设置)。 这些标准分区可避免 LVM 名称与克隆 VM 发生冲突,特别是在 OS 磁盘需要连接到另一台 VM 以进行故障排除的情况下。 LVMRAID也可用于数据磁盘。
  • 请勿在 OS 磁盘上配置交换分区或交换文件。 可以将 cloud-init 预配代理配置为在临时资源磁盘上创建交换文件或交换分区。 有关此过程的详细信息,请参阅 为 Azure Linux VM 创建 SWAP 分区
  • Azure上的所有 VHD 必须具有与 1 MB 对齐的虚拟大小。 从原始磁盘转换为 VHD 时,必须确保在转换前的原始磁盘大小是 1 MB 的倍数。 有关详细信息,请参阅 Linux 安装说明

重要

使用临时资源磁盘的交换指南仅适用于包含本地临时存储的 VM 大小。 远程磁盘控制器类型 SCSI 或 NVMe 无法确定资源磁盘是否可用。

可以将预生成的 Ubuntu 映像直接上传到Azure,并使用生成的 VHD 创建新的virtual machines。 如果这是你第一次上传 .vhd 文件,请参阅 从自定义磁盘创建 Linux VM

手动步骤

注意事项

在尝试为 Azure 创建自己的自定义 Ubuntu 映像之前,请考虑改用 Ubuntu 云映像网页中的预生成和测试映像

如果使用 Windows 提取预生成的映像,请使用 Windows WSL 并运行以下命令

     sudo tar --sparse -xvzf <image name>-azure.vhd.tar.gz 
  1. 在 Hyper-V 管理器的中心窗格中,选择虚拟机。

  2. 选择“连接”以打开虚拟机的窗口。

  3. 替换映像中的当前存储库以使用 Ubuntu 的Azure存储库。

    在编辑 /etc/apt/sources.list/etc/apt/sources.list.d/ubuntu.sources之前,建议进行备份:

    对于 Ubuntu 22.04 及更早版本

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
    

    对于 Ubuntu 24.04 及更高版本

    sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
    

    对于 Ubuntu 22.04 及更早版本

    sudo sed -i 's#http://archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list
    sudo sed -i 's#http://[a-z][a-z]\.archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list
    sudo sed -i 's#http://security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list
    sudo sed -i 's#http://[a-z][a-z]\.security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list
    sudo apt update
    
    

    对于 Ubuntu 24.04 及更高版本

    sudo sed -i 's#http://archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list.d/ubuntu.sources
    sudo sed -i 's#http://[a-z][a-z]\.archive\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list.d/ubuntu.sources
    sudo sed -i 's#http://security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list.d/ubuntu.sources
    sudo sed -i 's#http://[a-z][a-z]\.security\.ubuntu\.com/ubuntu#http://azure\.archive\.ubuntu\.com/ubuntu#g' /etc/apt/sources.list.d/ubuntu.sources
    sudo apt update
    
    
  4. Ubuntu Azure映像使用Azure定制内核Azure定制内核。 将 OS 更新到最新的Azure定制内核,并安装 Azure Linux 工具(包括 Hyper-V 依赖项):

    sudo apt update
    sudo apt install linux-azure linux-image-azure linux-headers-azure linux-tools-common linux-cloud-tools-common linux-tools-azure linux-cloud-tools-azure
    sudo apt full-upgrade
    sudo reboot
    
  5. 修改 GRUB 的内核启动行,以包含用于Azure的额外内核参数。 要完成此步骤,在文本编辑器中打开/etc/default/grub,找到名为GRUB_CMDLINE_LINUX_DEFAULT的变量(如有需要可以添加),然后编辑它以包含以下参数:

        GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8 earlyprintk=ttyS0,115200 rootdelay=300 quiet splash"
    
  6. 保存并关闭此文件并运行 sudo update-grub。 此步骤可确保所有控制台消息都发送到第一个串行端口,这有助于Azure技术支持调试问题。

  7. 仅当为远程 NVMe 磁盘控制器创建映像时,配置并验证 NVMe 启动支持。 否则,请跳过此步骤。

    1. 使 NVMe 驱动程序持久化,以便将其添加到每个将来的 initramfs,然后重新生成当前的 initramfs。 循环会跳过已列出的模块,以避免重复条目:

      for module in nvme nvme_core; do
        grep -qxF "$module" /etc/initramfs-tools/modules || echo "$module" | sudo tee -a /etc/initramfs-tools/modules
      done
      sudo update-initramfs -u -k all
      
    2. 将Azure NVMe I/O 超时添加到内核命令行,然后重新生成 GRUB 配置,以便设置在重新启动时保留:

      sudo sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT=/ s/"$/ nvme_core.io_timeout=240"/' /etc/default/grub
      sudo update-grub
      
    3. 确认这两个 NVMe 模块都存在于内核的模块树中,以便将其打包到 initramfs 中。 此检查会读取磁盘上的模块文件,因此即使在 SCSI 准备 VM 上也成功,并且并不表示 NVMe 已加载或使用:

      modinfo nvme
      modinfo nvme_core
      

      每个命令必须返回模块详细信息。 如果未找到任一模块,请在继续之前按照 Ubuntu 内核文档安装或启用它。

  8. 确认重新生成的 initramfs 包包含两个 NVMe 驱动程序。 此检查确认映像已准备就绪:

    sudo lsinitramfs /boot/initrd.img-$(uname -r) | grep -E 'nvme(_core)?\.ko'
    

    输出必须同时列出 nvme 驱动程序和 nvme_core 驱动程序。 在 NVMe VM 上启动映像后,通过运行 cat /sys/module/nvme_core/parameters/io_timeout验证运行时超时;预期值为 240

  9. 对于 SCSI 和 NVMe 映像,请使用文件系统 UUID 或其他永久性标识符 /etc/fstab。 请勿使用 /dev/sd*/dev/nvme* 设备名称,因为设备名称可以在重新启动或磁盘控制器更改时更改。

    1. 列出块设备及其永久标识符,以便与 /etc/fstab 中的条目进行比较:

      sudo blkid
      
    2. 检查 /etc/fstab 中是否存在语法错误、无效的挂载选项以及无法解析的引用:

      sudo findmnt --verify --verbose
      
  10. 请确保已安装 SSH 服务器且将其配置为在引导时启动。 此设置通常是默认设置。

  11. 安装 cloud-init(预配代理)和 Azure Linux 代理(来宾扩展处理程序)。 Cloud-init 使用 netplan 配置系统网络配置(在预配和每次后续引导期间)并使用 gdisk 对资源磁盘进行分区。

    sudo apt update
    sudo apt install cloud-init gdisk netplan.io walinuxagent && systemctl stop walinuxagent
    

    注意事项

    如果安装了 walinuxagentNetworkManager 包,则 NetworkManager-gnome 包会将其移除。

  12. 删除cloud-init 默认配置和剩余netplan 工件,这些可能与 Azure 上的cloud-init 配置冲突:适用于 Ubuntu 22.04 及更早版本

    sudo rm -f /etc/cloud/cloud.cfg.d/50-curtin-networking.cfg /etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg /etc/cloud/cloud.cfg.d/99-installer.cfg /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
    sudo rm -f /etc/cloud/ds-identify.cfg
    sudo rm -f /etc/netplan/*.yaml
    

    对于 Ubuntu 24.04 及更高版本

    sudo rm -f /etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg /etc/cloud/cloud.cfg.d/99-installer.cfg /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
    sudo rm -f /etc/cloud/ds-identify.cfg
    sudo rm -f /etc/netplan/*.yaml
    
  13. 使用Azure数据源配置 cloud-init 以预配系统:

    sudo tee /etc/cloud/cloud.cfg.d/90_dpkg.cfg <<EOF
    datasource_list: [ Azure ]
    EOF
    
    sudo tee /etc/cloud/cloud.cfg.d/90-azure.cfg <<EOF
    system_info:
       package_mirrors:
         - arches: [i386, amd64]
           failsafe:
             primary: http://archive.ubuntu.com/ubuntu
             security: http://security.ubuntu.com/ubuntu
           search:
             primary:
               - http://azure.archive.ubuntu.com/ubuntu/
             security: []
         - arches: [armhf, armel, default]
           failsafe:
             primary: http://ports.ubuntu.com/ubuntu-ports
             security: http://ports.ubuntu.com/ubuntu-ports
    EOF
    
    sudo tee /etc/cloud/cloud.cfg.d/10-azure-kvp.cfg <<EOF
    reporting:
      logging:
        type: log
      telemetry:
        type: hyperv
    EOF
    
  14. 将 Azure Linux 代理配置为依赖于 cloud-init 来执行预配。 有关这些选项的详细信息,请参阅 WALinuxAgent project

    sudo sed -i 's/Provisioning.Enabled=y/Provisioning.Enabled=n/g' /etc/waagent.conf
    sudo sed -i 's/Provisioning.UseCloudInit=n/Provisioning.UseCloudInit=y/g' /etc/waagent.conf
    sudo sed -i 's/ResourceDisk.Format=y/ResourceDisk.Format=n/g' /etc/waagent.conf
    sudo sed -i 's/ResourceDisk.EnableSwap=y/ResourceDisk.EnableSwap=n/g' /etc/waagent.conf
    
    sudo tee -a /etc/waagent.conf <<EOF
    # For Azure Linux agent version >= 2.2.45, this is the option to configure,
    # enable, or disable the provisioning behavior of the Linux agent.
    # Accepted values are auto (default), waagent, cloud-init, or disabled.
    # A value of auto means that the agent will rely on cloud-init to handle
    # provisioning if it is installed and enabled, which in this case it will.
    Provisioning.Agent=auto
    EOF
    
  15. 清理 cloud-init 和 Azure Linux 代理的运行时环境工件和日志:

    sudo cloud-init clean --logs --seed
    sudo rm -rf /var/lib/cloud/
    sudo systemctl stop walinuxagent.service
    sudo rm -rf /var/lib/waagent/
    sudo rm -f /var/log/waagent.log
    
  16. 取消预配 VM,并准备在Azure上进行预配。

    注意事项

    sudo waagent -force -deprovision+user 命令会通过尝试清理系统将映像通用化,以使其适合重新预配。 +user 选项会删除上次预配的用户帐户和关联的数据。

    sudo waagent -force -deprovision+user
    sudo rm -f ~/.bash_history
    

    警告

    使用上述命令进行取消配置无法保证映像中的所有敏感信息被彻底清除并适合重新分发。

  17. 在 Hyper-V 管理器中选择“操作”>“关闭”

  18. Azure仅接受固定大小的 VHD。 如果 VM 的 OS 磁盘不是固定大小的 VHD,请使用 Convert-VHD PowerShell cmdlet 并指定 -VHDType Fixed 选项。 有关更多信息,请查看Convert-VHD的文档位于

  19. 若要在Azure上引入第 2 代 VM,请创建回退 UEFI 启动路径:

    1. ubuntu EFI 目录复制到名为 boot 的新目录中:

      sudo cp -rp /boot/efi/EFI/ubuntu /boot/efi/EFI/boot
      
    2. 将 EFI 加载程序重命名为回退启动加载程序名称:

      sudo mv /boot/efi/EFI/boot/shimx64.efi /boot/efi/EFI/boot/bootx64.efi
      
    3. 将 GRUB 配置文件重命名为备用名称:

      sudo mv /boot/efi/EFI/boot/grub.cfg /boot/efi/EFI/boot/bootx64.cfg
      

现在,可以使用 Ubuntu Linux VHD 在Azure中创建新的 VM。 如果这是首次将 .vhd 文件上传到 Azure,请参阅 从自定义磁盘创建 Linux VM

对于需要从 SCSI 迁移到 NVMe 的现有Azure VM,请使用将 Linux 和 Windows VM 从 SCSI 转换为 NVMe