为 Azure 准备 Debian VHD

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

先决条件

本部分假设已经将从 Debian 网站下载的 .iso 文件中的 Debian Linux 操作系统安装到虚拟硬盘 (VHD)。 可使用多种工具创建 .vhd 文件。 Hyper-V 只是一个示例。 有关 Hyper-V 的使用说明,请参阅安装 Hyper-V 角色和配置虚拟机 (VM)

安装说明

重要

本文中的远程 NVMe 准备是可选的。 仅当要创建打算使用远程 NVMe 磁盘控制器部署的映像时,才能完成该映像。 如果目标 VM 使用 SCSI,请跳过远程 NVMe 部分并保留标准设置。

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

重要

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

为 Azure 准备 Debian 映像

可以通过全自动安装 (FAI) 云映像生成器创建基本的 Azure Debian 云映像。 若要在没有 FAI 的情况下准备映像,请查看通用步骤文章

以下 git clone 和 apt 安装命令是从 Debian 云映像存储库中提取的。 首先克隆存储库并安装依赖项:

$ git clone https://salsa.debian.org/cloud-team/debian-cloud-images.git
$ sudo apt install --no-install-recommends ca-certificates debsums dosfstools \
    fai-server fai-setup-storage make python3 python3-libcloud python3-marshmallow \
    python3-pytest python3-yaml qemu-utils udev
$ cd ./debian-cloud-images

可选:通过将脚本(例如 Shell 脚本)添加到 ./config_space/scripts/AZURE 中,自定义构建。

用于自定义映像的脚本示例

$ mkdir -p ./config_space/scripts/AZURE
$ cat > ./config_space/scripts/AZURE/10-custom <<EOF
#!/bin/bash

\$ROOTCMD bash -c "echo test > /usr/local/share/testing"
EOF
$ sudo chmod 755 ./config_space/scripts/AZURE/10-custom

对于任何要用于自定义映像的命令,都请在前面加上 $ROOTCMD 前缀。 它的别名为 chroot $target

验证 Debian 磁盘配置

对于 SCSI 和 NVMe 映像,请添加用于验证 /etc/fstab 和拒绝非持久性磁盘名称的 FAI 自定义脚本:

$ cat > ./config_space/scripts/AZURE/15-storage-validation <<'EOF'
#!/bin/bash
set -eu

$ROOTCMD findmnt --verify --verbose

if $ROOTCMD grep -Eq '^[[:space:]]*[^#].*[[:space:]]/dev/(sd|nvme)' /etc/fstab; then
    echo 'Replace /dev/sd* and /dev/nvme* entries in /etc/fstab with UUIDs or another persistent identifier.' >&2
    exit 1
fi
EOF
$ sudo chmod 755 ./config_space/scripts/AZURE/15-storage-validation

为远程 NVMe 准备 Debian 映像

仅当为远程 NVMe 磁盘控制器创建映像时,才完成本部分。 否则,请继续生成 Azure Debian 映像,而无需添加此脚本。

在生成 NVMe 映像之前添加另一个 FAI 自定义脚本。 该脚本使 NVMe 驱动程序在早期启动期间可用,并设置AZURE NVMe I/O 超时。

$ cat > ./config_space/scripts/AZURE/20-nvme <<'EOF'
#!/bin/bash
set -eu

$ROOTCMD bash -c "printf '%s\n' nvme nvme_core >> /etc/initramfs-tools/modules"
$ROOTCMD update-initramfs -u -k all
$ROOTCMD sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT=/ s/"$/ nvme_core.io_timeout=240"/' /etc/default/grub
$ROOTCMD update-grub

$ROOTCMD modinfo nvme
$ROOTCMD modinfo nvme_core
$ROOTCMD bash -c "lsinitramfs /boot/initrd.img-\$(ls /lib/modules | sort -V | tail -1) | grep -Eq 'nvme(_core)?\\.ko'"
EOF
$ sudo chmod 755 ./config_space/scripts/AZURE/20-nvme

重要

如果 FAI 配置已设置这些值,请检查生成的 GRUB 命令行和 /etc/initramfs-tools/modules 中是否存在重复条目。 nvme_corenvme 都必须包含在生成的 initramfs 中。

生成 Azure Debian 映像

$ make image_[release]_azure_amd64

此命令会在当前目录中输出少量文件,最重要的是 image_[release]_azure_amd64.raw 映像文件。

将原始映像转换为适用于 Azure 的 VHD:

rawdisk="image_[release]_azure_amd64.raw"
vhddisk="image_[release]_azure_amd64.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))
rounded_size_adjusted=$(($rounded_size + 512))

echo "Rounded Size Adjusted = $rounded_size_adjusted"

sudo qemu-img resize "$rawdisk" $rounded_size
qemu-img convert -f raw -o subformat=fixed,force_size -O vpc "$rawdisk" "$vhddisk"

此过程会创建一个大小经过取整的 VHD image_[release]_azure_amd64.vhd,以便能够成功将其复制到 Azure 磁盘。

注意

与其在本地克隆 salsa 仓库并构建镜像,不如从 FAI 构建并下载当前的稳定镜像。

创建稳定的 Debian VHD 映像后,请验证是否已安装以下包,然后再上传:

sudo apt update
sudo apt install hyperv-daemons
sudo apt install waagent # *(Optional but recommended for password resets and the use of extensions)*
sudo apt-get install cloud-init

然后执行完整升级:

sudo apt full-upgrade

现在必须为此映像创建 Azure 资源。 此示例使用 $rounded_size_adjusted 变量,因此它应来自上一步的同一 shell 进程。

在创建托管磁盘之前设置 Hyper-V 代系。 示例默认 V1 为标准 SCSI 映像。 仅当您完成远程 NVMe 准备部分或准备第 2 代映像时,才将其更改为 V2

HYPER_V_GENERATION=V1

az group create -l $LOCATION -n $RG

az disk create \
    -n $DISK \
    -g $RG \
    -l $LOCATION \
    --for-upload --upload-size-bytes "$rounded_size_adjusted" \
    --sku standard_lrs --hyper-v-generation $HYPER_V_GENERATION

ACCESS=$(az disk grant-access \
    -n $DISK -g $RG \
    --access-level write \
    --duration-in-seconds 86400 \
    --query accessSas -o tsv)

azcopy copy "$vhddisk" "$ACCESS" --blob-type PageBlob

az disk revoke-access -n $DISK -g $RG
az image create \
    -g $RG \
    -n $IMAGE \
    --os-type linux \
    --hyper-v-generation $HYPER_V_GENERATION \
    --source $(az disk show \
        -g $RG \
        -n $DISK \
        --query id -o tsv)
az vm create \
    -g $RG \
    -n $VM \
    --ssh-key-value $SSH_KEY_VALUE \
    --public-ip-address-dns-name $VM \
    --image $(az image show \
        -g $RG \
        -n $IMAGE \
        --query id -o tsv)

如果从本地计算机到 Azure 磁盘的带宽导致使用 azcopy 处理上传需要很长时间,则可以使用 Azure VM Jumpbox 来加快处理速度。 下面是此过程的实现方式:

  1. 在本地计算机上将 VHD 创建为 tar 归档文件:tar -czvf ./image_buster_azure_amd64.vhd.tar.gz ./image_[release]_azure_amd64.vhd
  2. 创建一个 Azure Linux VM(你选择的发行版本)。 请确保在创建它时使用足够大的磁盘空间,以容纳提取出的 VHD。
  3. azcopy 实用工具下载到 Azure Linux VM。 可以从 AzCopy 入门获取它。
  4. 将 tarball 复制到虚拟机:scp ./image_buster_azure_amd64.vhd.tar.gz <vm>:~
  5. 在 VM 上,提取 VHD:tar -xf ./image_buster_azure_amd64.vhd.tar.gz。 此步骤需要一些时间,具体取决于文件大小。
  6. 最后,在虚拟机上,使用 azcopy(上文中的命令)将 VHD 复制到 Azure 磁盘。

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

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