为 Azure 准备 SLES 或 openSUSE Leap 虚拟机

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

在某些情况下,你可能希望在Azure环境中使用自定义的 SUSE Linux Enterprise Server (SLES)或 openSUSE Leap Linux 虚拟机(VM),并且能够通过自动化生成这些类型的 VM。 本文演示如何创建和上传包含 SUSE Linux 操作系统的自定义Azure虚拟硬盘(VHD)。

先决条件

本文假定已在虚拟硬盘上安装 SLES 或 openSUSE Leap Linux 操作系统。 可使用多种工具创建 .vhd 文件。 例如,可以使用虚拟化解决方案,例如Hyper-V。 有关说明,请参阅 安装 Hyper-V 并创建虚拟机

SLES/openSUSE Leap 安装说明

重要

本文中的远程 NVMe 准备步骤是可选的。 仅当你正在创建一个打算部署到远程 NVMe 磁盘控制器上的映像时,才填写这些内容。 如果目标 VM 使用 SCSI,请跳过标记为远程 NVMe 的每个步骤并保留标准设置。

  • 有关为Azure准备 Linux 映像的更多提示,请参阅常规 Linux 安装说明
  • Azure不支持Windows硬盘映像 (.vhdx) 文件。 虚拟机外部仅支持 VHD (.vhd) 文件。 可使用 Hyper-V 管理器或 Convert-VHD cmdlet 将磁盘转换为 VHD 格式。
  • Azure 支持 Gen1(BIOS 引导)和 Gen2(UEFI 引导)虚拟机。
  • 必须在内核中启用虚拟文件分配表 (VFAT) 内核模块。
  • 不要在 OS 磁盘上配置交换分区。 可以将 Linux 代理配置为在临时资源磁盘上创建交换文件。 本文后面的步骤提供有关配置交换空间的详细信息。
  • Azure 上所有 VHD 的虚拟大小必须对齐到 1 MB。 从原始磁盘转换为 VHD 时,请确保原始磁盘大小在转换前为 1 MB 的倍数。 有关详细信息,请参阅 常规 Linux 安装说明

重要

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

注意

Cloud-init 版本 21.2 或更高版本会删除用户定义的函数(UDF)要求。 但如果未启用 udf 模块,CD-ROM 将不会在预配期间装载,这会阻止应用自定义数据。 解决方法是应用用户数据。 但是,与自定义数据不同,用户数据不会加密。 有关详细信息,请参阅 cloud-init 文档中的用户数据格式

使用 SUSE Studio

SUSE Studio 可以轻松创建和管理适用于 Azure 和 Hyper-V 的 SLES 和 openSUSE Leap 映像。 SUSE Studio 是自定义您自己的 SLES 和 openSUSE Leap 映像的推荐方式。

除了自行构建 VHD 外,SUSE 还在 VM Depot 上提供适用于 SLES 的 BYOS(自带订阅)映像。

为 Azure 准备 SLES

  1. 根据需要配置Azure和 Hyper-V 模块。

    如果您的软件虚拟机监控程序不是 Hyper-V,则需要将其他模块添加到初始 RAM 磁盘(initramfs)中,才能在 Azure 中成功启动。

    创建 /etc/dracut.conf.d/azure.conf 文件并添加以下行:

    add_drivers+=" hv_vmbus hv_netvsc hv_storvsc "
    

    重新生成 initramfs:

    sudo dracut --verbose --force
    
  2. 设置串行控制台。

    若要成功使用串行控制台,必须在 /etc/defaults/grub 文件中设置多个变量并在服务器上重新创建 GRUB:

    # Add console=ttyS0 and earlyprintk=ttS0 to the variable.
    # Remove "splash=silent" and "quiet" options.
    GRUB_CMDLINE_LINUX_DEFAULT="audit=1 no-scroll fbcon=scrollback:0 mitigations=auto security=apparmor crashkernel=228M,high crashkernel=72M,low console=ttyS0 earlyprintk=ttyS0"
    
    # Add "console serial" to GRUB_TERMINAL.
    GRUB_TERMINAL="console serial"
    
    # Set the GRUB_SERIAL_COMMAND variable.
    
    GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
    
    sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
    
  3. 仅当你要为远程 NVMe 磁盘控制器创建映像时,请在步骤 2 中将 nvme_core.io_timeout=240 添加到 GRUB_CMDLINE_LINUX_DEFAULT,将 nvme nvme_core 添加到 /etc/dracut.conf.d/azure.conf 中的 add_drivers 值,然后重新生成 GRUB 和 initramfs。 否则,请省略这些设置。

    sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
    sudo dracut --verbose --force
    

    仅对于远程 NVMe 映像,请验证驱动程序:

    1. 确认这两个 NVMe 模块都存在于内核的模块树中,以便将其打包到 initramfs 中。 此检查会读取磁盘上的模块文件,因此即使在 SCSI 准备 VM 上也成功,并且并不表示 NVMe 已加载或使用:

      modinfo nvme
      modinfo nvme_core
      

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

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

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

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

  5. 注册 SUSE Linux Enterprise 系统以允许它下载更新和安装包。

  6. 使用最新的修补程序更新系统:

    sudo zypper update
    
  7. 安装 Azure Linux VM 代理(waagent)和 cloud-init:

    sudo SUSEConnect -p sle-module-public-cloud/15.2/x86_64  (SLES 15 SP2)
    sudo zypper refresh
    sudo zypper install python-azure-agent
    sudo zypper install cloud-init
    
  8. 启用 waagent 和 cloud-init 以在开机时启动:

    sudo systemctl enable  waagent
    sudo systemctl enable cloud-init-local.service
    sudo systemctl enable cloud-init.service
    sudo systemctl enable cloud-config.service
    sudo systemctl enable cloud-final.service
    sudo systemctl daemon-reload
    sudo cloud-init clean
    
  9. 更新 cloud-init 的配置:

    cat <<EOF | sudo tee /etc/cloud/cloud.cfg.d/91-azure_datasource.cfg
    datasource_list: [ Azure ]
    datasource:
        Azure:
            apply_network_config: False
    
    EOF
    
    sudo cat <<EOF | sudo tee  /etc/cloud/cloud.cfg.d/05_logging.cfg
    # This tells cloud-init to redirect its stdout and stderr to
    # 'tee -a /var/log/cloud-init-output.log' so the user can see output
    # there without needing to look on the console.
    output: {all: '| tee -a /var/log/cloud-init-output.log'}
    EOF
    
    # Make sure mounts and disk_setup are in the init stage:
    echo "Adding mounts and disk_setup to init stage"
    sudo sed -i '/ - mounts/d' /etc/cloud/cloud.cfg
    sudo sed -i '/ - disk_setup/d' /etc/cloud/cloud.cfg
    sudo sed -i '/cloud_init_modules/a\\ - mounts' /etc/cloud/cloud.cfg
    sudo sed -i '/cloud_init_modules/a\\ - disk_setup' /etc/cloud/cloud.cfg
    
  10. 如果要装载、格式化和创建交换分区,一个选项是在每次创建 VM 时传入 cloud-init 配置。

    另一个选项是使用映像中的 cloud-init 指令在每次创建 VM 时配置交换空间:

    cat  <<EOF | sudo tee -a /etc/systemd/system.conf
    'DefaultEnvironment="CLOUD_CFG=/etc/cloud/cloud.cfg.d/00-azure-swap.cfg"'
    EOF
    
    cat <<EOF | sudo tee /etc/cloud/cloud.cfg.d/00-azure-swap.cfg
    #cloud-config
    # Generated by Azure cloud image build
    disk_setup:
      ephemeral0:
        table_type: mbr
        layout: [66, [33, 82]]
        overwrite: True
    fs_setup:
      - device: ephemeral0.1
        filesystem: ext4
      - device: ephemeral0.2
        filesystem: swap
    mounts:
      - ["ephemeral0.1", "/mnt"]
      - ["ephemeral0.2", "none", "swap", "sw,nofail,x-systemd.requires=cloud-init.service,x-systemd.device-timeout=2", "0", "0"]
    EOF
    
  11. 以前,Azure Linux 代理用于通过使用Azure上预配虚拟机后附加到虚拟机的本地资源磁盘来自动配置交换空间。 由于 cloud-init 现在处理此步骤,因此不得使用 Azure Linux 代理格式化资源磁盘或创建交换文件。 使用以下命令适当修改 /etc/waagent.conf

    sudo sed -i 's/Provisioning.UseCloudInit=n/Provisioning.UseCloudInit=auto/g' /etc/waagent.conf
    sudo sed -i 's/Provisioning.Enabled=y/Provisioning.Enabled=n/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
    

    注意

    如果使用的是低于 21.2 的 cloud-init 版本,请确保已启用该 udf 模块。 删除或禁用会导致预配或启动失败。 Cloud-init 版本 21.2 或更高版本会删除 UDF 要求。

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

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

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

      sudo findmnt --verify --verbose
      
  13. 删除 udev 规则和网络适配器配置文件,以避免为以太网接口生成静态规则。 在Microsoft Azure或Hyper-V中克隆虚拟机时,这些规则可能会导致问题。

    sudo rm -f /etc/udev/rules.d/70-persistent-net.rules
    sudo rm -f /etc/udev/rules.d/85-persistent-net-cloud-init.rules
    sudo rm -f /etc/sysconfig/network/ifcfg-eth*
    
  14. 编辑 /etc/sysconfig/network/dhcp 文件,并将 DHCLIENT_SET_HOSTNAME 参数更改为以下值:

    DHCLIENT_SET_HOSTNAME="no"
    
  15. /etc/sudoers 文件中,如果存在,请注释掉或删除以下行:

    Defaults targetpw   # Ask for the password of the target user i.e. root
    ALL    ALL=(ALL) ALL   # WARNING! Only use this setting together with 'Defaults targetpw'!
    
  16. 确保安全外壳(SSH)服务器已安装并配置为在启动时启动:

    sudo systemctl enable sshd
    
  17. 清理 cloud-init 阶段:

    sudo cloud-init clean --seed --logs
    
  18. 运行以下命令以取消预配虚拟机,并准备在 Azure 上进行预配。

    如果要迁移特定的虚拟机,但不希望创建通用化映像,请跳过取消预配步骤。

    sudo rm -f /var/log/waagent.log
    sudo waagent -force -deprovision+user
    sudo export HISTSIZE=0
    sudo rm -f ~/.bash_history
    

准备 openSUSE 15.4+

  1. 在 Hyper-V 管理器的中心窗格中,选择虚拟机。

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

  3. 在终端中,运行命令 zypper lr。 如果此命令返回类似于以下示例的输出,则存储库将按预期进行配置,无需进行调整。 (版本号可能有所不同。

    # Alias Name 已启用 GPG 检查 刷新
    1 Cloud:Tools_15.4 云:工具-> (r) 是
    2 openSUSE_stable_OSS openSUSE_st-> (r) 是
    3 openSUSE_stable_Updates openSUSE_st-> (r) 是

    如果来自 zypper lr 的消息“未定义存储库”出现,则必须手动添加这些存储库。

    下面是用于添加这些存储库的命令示例(版本和链接可能有所不同):

    sudo zypper ar -f https://download.opensuse.org/update/openSUSE-stable openSUSE_stable_Updates
    sudo zypper ar -f https://download.opensuse.org/repositories/Cloud:/Tools/15.4 Cloud:Tools_15.4
    sudo zypper ar -f https://download.opensuse.org/distribution/openSUSE-stable/repo/oss openSUSE_stable_OSS
    

    然后,可以通过再次运行命令 zypper lr 来验证是否已添加存储库。 如果未启用其中一个相关的更新存储库,请使用以下命令启用它:

    sudo zypper mr -e [NUMBER OF REPOSITORY]
    
  4. 将内核更新到最新的可用版本:

    sudo zypper up kernel-default
    

    或者使用所有最新修补程序更新操作系统:

    sudo zypper update
    
  5. 安装 Azure Linux 代理:

    sudo zypper install WALinuxAgent
    
  6. 修改 GRUB 配置中的内核启动行,以包含Azure的其他内核参数。 为此,请在文本编辑器中打开 /boot/grub/menu.lst ,并确保默认内核包含以下参数:

    console=ttyS0 earlyprintk=ttyS0
    

    此选项可确保所有控制台消息都发送到第一个串行端口,这有助于Azure 支持调试问题。 此外,如果存在以下参数,请从内核启动行中删除以下参数:

     libata.atapi_enabled=0 reserve=0x1f0,0x8
    
  7. 建议编辑 /etc/sysconfig/network/dhcp 文件,并将 DHCLIENT_SET_HOSTNAME 参数更改为以下设置:

     DHCLIENT_SET_HOSTNAME="no"
    
  8. /etc/sudoers 文件中,如果存在,请注释掉或删除以下行。 这是一个重要步骤。

    Defaults targetpw   # ask for the password of the target user i.e. root
    ALL    ALL=(ALL) ALL   # WARNING! Only use this together with 'Defaults targetpw'!
    
  9. 请确保已安装 SSH 服务器且已将其配置为在引导时启动。

  10. 不要在 OS 磁盘上创建交换空间。

    Azure Linux 代理可以使用预配Azure后附加到 VM 的本地资源磁盘自动配置交换空间。 本地资源磁盘是 临时 磁盘,在取消预配 VM 时将清空。

    安装 Azure Linux 代理后,修改 /etc/waagent.conf 中的参数,如下所示:

    ResourceDisk.Format=n
    ResourceDisk.Filesystem=ext4
    ResourceDisk.MountPoint=/mnt/resource
    ResourceDisk.EnableSwap=n
    ResourceDisk.SwapSizeMB=2048    ## NOTE: set the size to whatever you need it to be.
    
  11. 确保Azure Linux 代理在启动时运行:

    sudo systemctl enable waagent.service
    
  12. 运行以下命令以取消预配虚拟机,并准备在 Azure 上进行预配。

    如果要迁移特定的虚拟机,但不希望创建通用化映像,请跳过取消预配步骤。

    sudo rm -f ~/.bash_history # Remove current user history
    sudo rm -rf /var/lib/waagent/
    sudo rm -f /var/log/waagent.log
    sudo waagent -force -deprovision+user
    sudo rm -f ~/.bash_history # Remove root user history
    sudo export HISTSIZE=0
    
  13. 在 Hyper-V 管理器中选择“操作”>“关闭”

后续步骤

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

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