你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

社区支持的非认可分发版的信息

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

仅当使用某个认可的分发版时,Azure 平台 SLA 才适用于运行 Linux OS 的虚拟机。 对于这些认可的分发版,Azure 市场中提供了预配置的 Linux 映像。

Azure 上运行的所有其他非 Azure 市场分发版都要满足一些先决条件。 本文的内容并不全面,因为每个分发版不同。 即使满足以下所有条件,但仍可能需要大幅调整 Linux 系统才能让其正常运行。

本文重点介绍有关在 Azure 上运行 Linux 分发版的一般准则。

常规 Linux 安装说明

  1. Azure 不支持 Hyper-V 虚拟硬盘 (VHDX) 格式,仅支持固定大小的 VHD。 可使用 Hyper-V 管理器或 Convert-VHD cmdlet 将磁盘转换为 VHD 格式。 如果使用 VirtualBox,请在创建磁盘时选择“固定大小”,而不要选择默认(动态分配的)大小。

  2. Azure 支持 Gen1(BIOS 引导)和 Gen2(UEFI 引导)虚拟机。

  3. VHD 允许的最大大小为 1,023 GB。

  4. 在安装 Linux 系统时,建议使用标准分区而不是逻辑卷管理器 (LVM),这是许多安装的默认设置。 使用标准分区可避免 LVM 名称与克隆的 VM 发生冲突,特别是在 OS 磁盘曾经连接到另一台相同的 VM 进行故障排除的情况下。 LVMRAID 可以在数据磁盘上使用。

  5. 需要装载 UDF 文件系统的内核支持。 在 Azure 上首次启动时,预配配置将使用附加到来宾的 UDF 格式媒体传递到 Linux VM。 Azure Linux 代理必须装载 UDF 文件系统才能读取其配置和预配 VM。

  6. 低于 2.6.37 的 Linux 内核版本不支持具有更大 VM 大小的 Hyper-V 上的 NUMA。 此问题主要影响使用上游 Red Hat 2.6.32 内核的旧分发版,在 Red Hat Enterprise Linux (RHEL) 6.6 (kernel-2.6.32-504) 中已解决。 运行版本低于 2.6.37 的自定义内核的系统,或者版本低于 2.6.32-504 的基于 RHEL 的内核必须在 grub.conf 中的内核命令行上设置启动参数 numa=off。 有关详细信息,请参阅 Red Hat KB 436883

  7. 不要在 OS 磁盘上配置交换分区。 可根据以下步骤中所述配置 Linux 代理,并在临时资源磁盘上创建交换文件。

  8. 对 Azure 上的所有 VHD,其虚拟大小必须保持为 1 MB(1024 × 1024 字节)。 从原始磁盘转换为 VHD 时,必须根据以下步骤中所述,确保在转换前原始磁盘大小是 1 MB 的倍数。

  9. 使用最新的分发版本、包和软件。

  10. 删除用户和系统帐户、公钥、敏感数据、不必要的软件和应用程序。

安装无 Hyper-V 的内核模块

Azure 在 Hyper-V 虚拟机监控程序上运行,因此 Linux 需要某些内核模块才能在 Azure 中运行。 如果具有在 Hyper-V 外部创建的虚拟机,Linux 安装程序可能无法在初始 ramdisk(initrd 或 initramfs)中包含 Hyper-V 驱动程序,除非 VM 检测到它正在 Hyper-V 环境中运行。 使用不同的虚拟化系统(例如 VirtualBox、KVM 等)来准备 Linux 映像时,可能需要重新生成 initrd,以便至少 hv_vmbus 和 hv_storvsc 内核模块可在初始 ramdisk 上使用。 在基于上游 Red Hat 分发版的系统上(可能还包括其他系统),这是一个已知问题。

重新生成 initrd 或 initramfs 映像的机制可能会因分发而有所不同。 查阅分发的文档或相应过程的支持。 以下示例演示如何使用 mkinitrd 实用工具重新生成 initrd:

  1. 备份现有 initrd 映像:

    cd /boot
    sudo cp initrd-`uname -r`.img  initrd-`uname -r`.img.bak
    
  2. 使用 hv_vmbushv_storvsc 内核模块重新生成 initrd

    sudo mkinitrd --preload=hv_storvsc --preload=hv_vmbus -v -f initrd-`uname -r`.img `uname -r`
    

调整 VHD 大小

Azure 上的 VHD 映像必须已将虚拟大小调整为 1MB。 通常情况下,使用 Hyper-V 创建的 VHD 已正确调整。 如果未正确调整 VHD,在尝试基于 VHD 创建映像时,可能会收到如下错误消息:

The VHD http:\//\<mystorageaccount>.blob.core.windows.net/vhds/MyLinuxVM.vhd has an unsupported virtual size of 21475270656 bytes. The size must be a whole number (in MBs).

在这种情况下,可使用 Hyper-V 管理器控制台或 Resize-VHD PowerShell cmdlet 调整 VM 大小。 如果不是在 Windows 环境中运行,我们建议使用 qemu-img 转换(如果需要)并调整 VHD 大小。

注意

2.2.1 版及更高版本的 qemu-img 中有一个已知 bug 会导致 VHD 格式不正确。 QEMU 2.6 中已修复此问题。 我们建议使用 qemu-img 2.2.0 或更低版本,或者 2.6 或更高版本。

  1. 直接使用工具(如 qemu-imgvbox-manage)调整 VHD 大小可能会生成无法启动的 VHD。 我们建议先将 VHD 转换为 RAW 磁盘映像。 如果已将 VM 映像创建为 RAW 磁盘映像(对于 KVM 等某些虚拟机监控程序,这是默认设置),则可以跳过此步骤。

    qemu-img convert -f vpc -O raw MyLinuxVM.vhd MyLinuxVM.raw
    
  2. 计算磁盘映像所需的大小,使虚拟大小调整为 1MB。 以下 bash shell 脚本使用 qemu-img info 来确定磁盘映像的虚拟大小,然后将大小计算到下个 1 MB。

    rawdisk="MyLinuxVM.raw"
    vhddisk="MyLinuxVM.vhd"
    
    MB=$((1024*1024))
    size=$(qemu-img info -f raw --output json "$rawdisk" | \
    gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')
    
    rounded_size=$(((($size+$MB-1)/$MB)*$MB))
    
    echo "Rounded Size = $rounded_size"
    
  3. 使用上面设置的 $rounded_size 调整原始磁盘大小。

    qemu-img resize MyLinuxVM.raw $rounded_size
    
  4. 现在,将 RAW 磁盘重新转换为固定大小 VHD。

    qemu-img convert -f raw -o subformat=fixed,force_size -O vpc MyLinuxVM.raw MyLinuxVM.vhd
    

    或者,使用 2.6 之前的 qemu 版本,请删除该 force_size 选项。

    qemu-img convert -f raw -o subformat=fixed -O vpc MyLinuxVM.raw MyLinuxVM.vhd
    

Linux 内核要求

Hyper-V 和 Azure 的 Linux 集成服务 (LIS) 驱动程序会直接影响上游 Linux 内核。 包括最新 Linux 内核版本(例如 3.x)在内的许多分发版已提供这些驱动程序,或以其他方式为其内核提供了这些驱动程序的向后移植版本。 这些驱动程序会不断地在上游内核中使用新的修补程序和功能进行更新,因此,如果可能,建议运行包含这些修补程序和更新的认可的分发版

如果你正在运行 Red Hat Enterprise Linux 版本 6.0 到 6.3 的一个变体,需要安装适用于 Hyper-V 的最新 LIS 驱动程序。 从 RHEL 6.4+(和派生产品)开始,LIS 驱动程序已包含在内核中,因此,无需其他安装包。

如果需要自定义内核,我们建议使用最新的内核版本(例如 3.8+)。 对于维护自己内核的分发版或供应商,需要定期将 LIS 驱动程序从上游内核向后移植到自定义内核。 即使已运行相对较新的内核版本,我们也强烈建议跟踪 LIS 驱动程序中的任何上游修复,并根据需要向后移植这些修复。 LIS 驱动程序源文件的位置在 Linux 内核源树中的 MAINTAINERS 文件中指定:

    F:    arch/x86/include/asm/mshyperv.h
    F:    arch/x86/include/uapi/asm/hyperv.h
    F:    arch/x86/kernel/cpu/mshyperv.c
    F:    drivers/hid/hid-hyperv.c
    F:    drivers/hv/
    F:    drivers/input/serio/hyperv-keyboard.c
    F:    drivers/net/hyperv/
    F:    drivers/scsi/storvsc_drv.c
    F:    drivers/video/fbdev/hyperv_fb.c
    F:    include/linux/hyperv.h
    F:    tools/hv/

必须在内核中包含以下修补程序。 此列表并不完整,并未包括所有分发版。

Azure Linux 代理

Azure Linux 代理waagent 在 Azure 中预配 Linux 虚拟机。 可以在 Linux 代理 GitHub 存储库中获取最新版本、文件问题或提交拉取请求。

  • 根据 Apache 2.0 许可证发布 Linux 代理。 许多发行版已经为该代理提供 RPM 或 .deb 包,可以轻松安装和更新这些包。
  • Azure Linux 代理需要 Python v2.6 以上版本。
  • 该代理还需要 python-pyasn1 模块。 大多数分发版提供此模块作为可安装的单独包。
  • 在某些情况下,Azure Linux 代理可能与 NetworkManager 不兼容。 发行版提供的许多 RPM/deb 包都将 NetworkManager 配置为与 waagent 包冲突。 在这种情况下,它会在你安装 Linux 代理包时卸载 NetworkManager。
  • Azure Linux 代理必须至少是支持的最低版本

注意

请确保启用“udf”(cloud-init >= 21.2) 和“vfat”模块。 将 udf 模块列入阻止列表将会导致预配失败,而将 vfat 模块列回将会导致预配和启动失败。 Cloud-init < 21.2 不受影响,并且不需要此更改

一般 Linux 系统要求

  1. 修改 GRUB 或 GRUB2 中的内核引导行并包含以下参数,以便将所有控制台消息发送到第一个串行端口。 这些消息可以协助 Azure 支持人员调试任何问题。

    GRUB_CMDLINE_LINUX="rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0"
    

    我们还建议删除以下参数(如果存在)。

    rhgb quiet crashkernel=auto
    

    图形界面式引导和安静引导在云环境中不适用,在云环境中,我们希望所有日志都发送到串行端口。 可根据需要配置 crashkernel 选项,但请注意此参数会使 VM 中的可用内存量至少减少 128 MB,这对于较小的 VM 而言可能是个问题。

  2. 完成编辑 /etc/default/grub 后,运行以下命令以重新生成 grub 配置:

    sudo grub2-mkconfig -o /boot/grub2/grub.cfg
    
  3. 添加 Hyper-V 模块 initrd 和 initramfs 指令 (Dracut)。

  4. 重新生成 initrd 或 initramfs Initramfs

    cp /boot/initramfs-$(uname -r).img /boot/initramfs-[latest kernel version ].img.bak 
    dracut -f -v /boot/initramfs-[latest kernel version ].img  [depending on the version of grub] 
    grub-mkconfig -o /boot/grub/grub.cfg 
    grub2-mkconfig -o /boot/grub2/grub.cfg 
    

    Initrd

    mv /boot/[initrd kernel] /boot/[initrd kernel]-old 
    mkinitrd /boot/initrd.img-[initrd kernel]-generic /boot/[initrd kernel]-generic-old 
    update-initramfs -c -k [initrd kernel] 
    update-grub 
    
  5. 确保已安装 SSH 服务器且已将其配置为在引导时启动。 此配置通常是默认值。

  6. 安装 Azure Linux 代理。 Azure Linux 代理是在 Azure 上设置 Linux 映像所必需的。 许多发行版以 RPM 或 .deb 包的形式提供代理(该包通常称为 WALinuxAgent 或 walinuxagent)。 还可以按照 Linux 代理指南中的步骤手动安装该代理。

    通过运行以下命令安装 Azure Linux 代理、cloud-init 和其他必需的实用程序:

    Redhat/Centos

    sudo yum install -y [waagent] cloud-init cloud-utils-growpart gdisk hyperv-daemons
    

    Ubuntu/Debian

    sudo apt install walinuxagent cloud-init cloud-utils-growpart gdisk hyperv-daemons
    

    Suse

    sudo zypper install python-azure-agent cloud-init cloud-utils-growpart gdisk hyperv-daemons
    

    然后使用以下命令在所有分发版上启用代理和 cloud-init:

    sudo systemctl enable waagent.service
    sudo systemctl enable cloud-init.service
    
  7. 不要在 OS 磁盘上创建交换空间。 Azure Linux 代理可使用在 Azure 上设置后附加到虚拟机的本地资源磁盘自动配置交换空间。 本地资源磁盘是临时磁盘,并可能在取消预配 VM 时被清空。 安装 Azure Linux 代理后,根据需要在 /etc/waagent.conf 中修改以下参数。

    ResourceDisk.Format=y
    ResourceDisk.Filesystem=ext4
    ResourceDisk.MountPoint=/mnt/resource
    ResourceDisk.EnableSwap=y
    ResourceDisk.SwapSizeMB=2048    ## NOTE: Set this to your desired size.
    
  8. 配置 cloud-init 来处理预配:

    1. 为 cloud-init 配置 waagent:
      sed -i 's/Provisioning.Agent=auto/Provisioning.Agent=cloud-init/g' /etc/waagent.conf
      sed -i 's/ResourceDisk.Format=y/ResourceDisk.Format=n/g' /etc/waagent.conf
      sed -i 's/ResourceDisk.EnableSwap=y/ResourceDisk.EnableSwap=n/g' /etc/waagent.conf
      
      如果要迁移特定的虚拟机,但不希望创建通用化映像,请在 /etc/waagent.conf config 中设置 Provisioning.Agent=disabled
    2. 配置装载:
      echo "Adding mounts and disk_setup to init stage"
      sed -i '/ - mounts/d' /etc/cloud/cloud.cfg
      sed -i '/ - disk_setup/d' /etc/cloud/cloud.cfg
      sed -i '/cloud_init_modules/a\\ - mounts' /etc/cloud/cloud.cfg
      sed -i '/cloud_init_modules/a\\ - disk_setup' /etc/cloud/cloud.cfg
      
    3. 配置 Azure 数据源:
      echo "Allow only Azure datasource, disable fetching network setting via IMDS"
      cat > /etc/cloud/cloud.cfg.d/91-azure_datasource.cfg <<EOF
      datasource_list: [ Azure ]
      datasource:
         Azure:
           apply_network_config: False
      EOF
      
    4. 如果已配置,则删除现有的交换文件:
      if [[ -f /mnt/resource/swapfile ]]; then
      echo "Removing swapfile" #RHEL uses a swapfile by defaul
      swapoff /mnt/resource/swapfile
      rm /mnt/resource/swapfile -f
      fi
      
  9. 配置 cloud-init 日志记录:

    echo "Add console log file"
    cat >> /etc/cloud/cloud.cfg.d/05_logging.cfg <<EOF
    
    # 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
    
  10. 交换配置。 不要在操作系统磁盘上创建交换空间。 以前,Azure Linux 代理使用在 Azure 上预配虚拟机后附加到虚拟机的本地资源磁盘自动配置交换空间。 但是,现在这由 cloud-init 处理,你不能使用 Linux 代理来格式化资源磁盘以创建交换文件,请在 /etc/waagent.conf 中相应地修改以下参数:

    ResourceDisk.Format=n
    ResourceDisk.EnableSwap=n
    

    如果要装载、格式化和创建交换,可以:1. 每次通过 customdata 创建 VM 时,都将其作为 cloud-init config 传入。 这是建议的方法。 2. 使用融入映像中的 cloud-init 指令,该指令将会在每次创建 VM 时都执行此操作。

           echo 'DefaultEnvironment="CLOUD_CFG=/etc/cloud/cloud.cfg.d/00-azure-swap.cfg"' >> /etc/systemd/system.conf
           cat > /etc/cloud/cloud.cfg.d/00-azure-swap.cfg << EOF
           #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. 取消设置。

    注意

    如果要迁移特定的虚拟机,但不希望创建通用化映像,请跳过“取消预配”步骤。 运行命令 waagent -force -deprovision+user 将导致源计算机无法使用,此步骤仅用于创建通用化映像。

    运行以下命令以取消预配虚拟机。

    # sudo rm -f /var/log/waagent.log
    # sudo cloud-init clean
    # waagent -force -deprovision+user
    # rm -f ~/.bash_history
    # export HISTSIZE=0
    # logout
    

    注意

    运行 waagent -force -deprovision 之后,Virtualbox 上可能会出现以下错误,指出 [Errno 5] Input/output error。 此错误消息并不关键,可以忽略。

  12. 关闭虚拟机并将 VHD 上传到 Azure。

后续步骤

使用 Azure CLI 从自定义磁盘创建 Linux VM